convertified

This commit is contained in:
bootunloader
2025-12-31 08:08:55 +02:00
parent 2a122e1551
commit 9fa4a0c113
5 changed files with 637 additions and 676 deletions

7
pyapi/start.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
# FastAPI Proxy Server Startup Script
# This script starts the FastAPI proxy server that bypasses Cloudflare
echo "Starting FastAPI Proxy Server on port 3070..."
uv run python -m fastapi dev --port=3070 main.py

View File

@@ -1,4 +1,4 @@
import { getRandomUserAgent, getULID, sleep } from "$lib/utils"; import { getULID, sleep } from "$lib/utils";
import { constants } from "$lib/utils/constants"; import { constants } from "$lib/utils/constants";
import type { BookingEntry, Draw, LooseApiUser } from "$lib/utils/data.types"; import type { BookingEntry, Draw, LooseApiUser } from "$lib/utils/data.types";
import { rng } from "$lib/utils/rng"; import { rng } from "$lib/utils/rng";
@@ -15,12 +15,10 @@ import { rng } from "$lib/utils/rng";
export const testIfSessionIsValid = async (jwt: string) => { export const testIfSessionIsValid = async (jwt: string) => {
try { try {
const res = await fetch( const res = await fetch(
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=6339`, `${constants.PROXY_API_URL}/v1/user/get-balance?userId=6339&authorization=${encodeURIComponent(jwt)}`,
{ {
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS, "Content-Type": "application/json",
Authorization: jwt,
"User-Agent": getRandomUserAgent(),
}, },
}, },
); );
@@ -49,11 +47,9 @@ export const getSessionToken = async (payload: {
userType: number; userType: number;
}): Promise<{ ok: boolean; message: string }> => { }): Promise<{ ok: boolean; message: string }> => {
console.log("Requesting..."); console.log("Requesting...");
const res = await fetch(`${constants.SCRAP_API_URL}/v1/auth/login`, { const res = await fetch(`${constants.PROXY_API_URL}/v1/auth/login`, {
method: "POST", method: "POST",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS,
"User-Agent": getRandomUserAgent(),
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify(payload), body: JSON.stringify(payload),
@@ -68,12 +64,10 @@ export const getSessionToken = async (payload: {
export async function getUsersBalance(userId: number, jwt: string) { export async function getUsersBalance(userId: number, jwt: string) {
try { try {
const res = await fetch( const res = await fetch(
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=${userId}`, `${constants.PROXY_API_URL}/v1/user/get-balance?userId=${userId}&authorization=${encodeURIComponent(jwt)}`,
{ {
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS, "Content-Type": "application/json",
Authorization: jwt,
"User-Agent": getRandomUserAgent(),
}, },
}, },
); );
@@ -85,9 +79,7 @@ export async function getUsersBalance(userId: number, jwt: string) {
time: string; time: string;
}; };
if (res.status !== 200 || rj.code !== 200 || !rj.success) { if (res.status !== 200 || rj.code !== 200 || !rj.success) {
console.log( console.log(`[!] Error getting balance for ${userId} :: ${JSON.stringify(rj)}`);
`[!] Error getting balance for ${userId} :: ${JSON.stringify(rj)}`,
);
return false; return false;
} }
return rj.data.balance; return rj.data.balance;
@@ -103,14 +95,11 @@ export const getDealers = async (jwt: string, distributor_ids: string[]) => {
const requests = distributor_ids.map(async (did) => { const requests = distributor_ids.map(async (did) => {
await sleep(rng(100, 10000)); await sleep(rng(100, 10000));
const res = await fetch( const res = await fetch(
`${constants.SCRAP_API_URL}/v1/user/dealer-list`, `${constants.PROXY_API_URL}/v1/user/dealer-list?authorization=${encodeURIComponent(jwt)}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS,
"Content-Type": "application/json", "Content-Type": "application/json",
"User-Agent": getRandomUserAgent(),
Authorization: jwt,
}, },
body: JSON.stringify({ body: JSON.stringify({
page: 1, page: 1,
@@ -175,14 +164,11 @@ export const getDealers = async (jwt: string, distributor_ids: string[]) => {
export const getDistributors = async (jwt: string) => { export const getDistributors = async (jwt: string) => {
const res = await fetch( const res = await fetch(
`${constants.SCRAP_API_URL}/v1/user/distributor-list`, `${constants.PROXY_API_URL}/v1/user/distributor-list?authorization=${encodeURIComponent(jwt)}`,
{ {
method: "POST", method: "POST",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS,
Authorization: jwt,
"Content-Type": "application/json", "Content-Type": "application/json",
"User-Agent": getRandomUserAgent(),
}, },
body: JSON.stringify({ body: JSON.stringify({
page: 1, page: 1,
@@ -218,14 +204,11 @@ export const getDistributors = async (jwt: string) => {
export const getDraws = async (jwt: string) => { export const getDraws = async (jwt: string) => {
const res = await fetch( const res = await fetch(
`${constants.SCRAP_API_URL}/v1/draw/list-my?userId=15`, `${constants.PROXY_API_URL}/v1/draw/list-my?userId=15&authorization=${encodeURIComponent(jwt)}`,
{ {
method: "GET", method: "GET",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS,
Authorization: jwt,
"Content-Type": "application/json", "Content-Type": "application/json",
"User-Agent": getRandomUserAgent(),
}, },
}, },
); );
@@ -253,13 +236,12 @@ export const getData = async (
drawId: number, drawId: number,
chosenDate: string, chosenDate: string,
) => { ) => {
const res = await fetch(`${constants.SCRAP_API_URL}/v1/book/list2`, { const res = await fetch(
`${constants.PROXY_API_URL}/v1/book/list2?authorization=${encodeURIComponent(jwt)}`,
{
method: "POST", method: "POST",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS,
Authorization: jwt,
"Content-Type": "application/json", "Content-Type": "application/json",
"User-Agent": getRandomUserAgent(),
}, },
body: JSON.stringify({ body: JSON.stringify({
userType: 3, userType: 3,
@@ -271,7 +253,8 @@ export const getData = async (
containImported: false, containImported: false,
keyword: "", keyword: "",
}), }),
}); },
);
type J = { type J = {
code: number; code: number;
success: boolean; success: boolean;

View File

@@ -1,4 +1,4 @@
import { getRandomUserAgent, getULID, sleep } from "$lib/utils"; import { getULID, sleep } from "$lib/utils";
import { constants } from "$lib/utils/constants"; import { constants } from "$lib/utils/constants";
import type { import type {
ApiPostUserWithParent, ApiPostUserWithParent,
@@ -7,8 +7,6 @@ import type {
PostDataEntry, PostDataEntry,
ServerError, ServerError,
} from "$lib/utils/data.types"; } from "$lib/utils/data.types";
import Fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";
export type APIResponse<T> = { export type APIResponse<T> = {
code: number; code: number;
@@ -72,9 +70,7 @@ export async function postDataToApi(payload: {
return { return {
ok: false, ok: false,
detail: "User not found to post data with", detail: "User not found to post data with",
errors: [ errors: [{ message: "User not found for request" }] as ServerError,
{ message: "User not found for request" },
] as ServerError,
}; };
} }
if (!dataByUser[userId]) { if (!dataByUser[userId]) {
@@ -84,14 +80,11 @@ export async function postDataToApi(payload: {
} }
try { try {
const userPromises = Object.entries(dataByUser).map( const userPromises = Object.entries(dataByUser).map(async ([userId, userData]) => {
async ([userId, userData]) => {
const session = payload.sessions[userId]; const session = payload.sessions[userId];
const usr = payload.users.find((u) => u.userId === userId); const usr = payload.users.find((u) => u.userId === userId);
if (!usr) { if (!usr) {
throw new Error( throw new Error(`User ${userId} not found for posting to api`);
`User ${userId} not found for posting to api`,
);
} }
const distId = usr.parentDistributor ?? 0; const distId = usr.parentDistributor ?? 0;
@@ -116,13 +109,7 @@ export async function postDataToApi(payload: {
drawId, drawId,
date, date,
); );
const res = await sendBatchRequest( const res = await sendBatchRequest(session, dealerId, payload.draw, total, message);
session,
dealerId,
payload.draw,
total,
message,
);
let rj: let rj:
| APIResponse<{ | APIResponse<{
bookDtos: { bookDtos: {
@@ -134,9 +121,7 @@ export async function postDataToApi(payload: {
try { try {
rj = (await res.json()) as any; rj = (await res.json()) as any;
} catch (err) { } catch (err) {
console.log( console.log("Encountered error while parsing post response");
"Encountered error while parsing post response",
);
console.log(res.status, err); console.log(res.status, err);
} }
if (rj && rj.code === 200 && res.status === 200) { if (rj && rj.code === 200 && res.status === 200) {
@@ -167,14 +152,11 @@ export async function postDataToApi(payload: {
}); });
console.log(await out.text()); console.log(await out.text());
} }
throw new Error( throw new Error(`Failed to send data to api for user ${userId}`);
`Failed to send data to api for user ${userId}`,
);
} }
} }
return userResponseIds; return userResponseIds;
}, });
);
// Wait for all user processes to complete // Wait for all user processes to complete
const results = await Promise.allSettled(userPromises); const results = await Promise.allSettled(userPromises);
@@ -195,9 +177,7 @@ export async function postDataToApi(payload: {
return { return {
ok: false, ok: false,
detail: "Failed to post data to API for some users", detail: "Failed to post data to API for some users",
errors: [ errors: [{ message: "Failed to post data to API for some users" }] as ServerError,
{ message: "Failed to post data to API for some users" },
] as ServerError,
}; };
} }
@@ -225,14 +205,12 @@ async function sendBatchRequest(
changedBalance: number, changedBalance: number,
body: string, body: string,
) { ) {
return Fetch(`${constants.SCRAP_API_URL}/v1/book/add-multiple`, { return fetch(
agent: new HttpsProxyAgent(`http://${session.ip}`), `${constants.PROXY_API_URL}/v1/book/add-multiple?authorization=${encodeURIComponent(session.sessionToken)}`,
{
method: "POST", method: "POST",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS, "Content-Type": "application/json",
"Content-Type": "application/json;charset=UTF-8",
Authorization: session.sessionToken,
"User-Agent": getRandomUserAgent(),
}, },
body: JSON.stringify({ body: JSON.stringify({
dealerId, dealerId,
@@ -242,7 +220,8 @@ async function sendBatchRequest(
changedBalance, changedBalance,
insertData: body, insertData: body,
}), }),
}); },
);
} }
async function mockSendBatchRequest( async function mockSendBatchRequest(
@@ -313,14 +292,12 @@ async function deleteAllBookedEntries({
drawId: number; drawId: number;
closeTime: string; closeTime: string;
}) { }) {
return Fetch(`${constants.SCRAP_API_URL}/v1/book/delete-multiple`, { return fetch(
agent: new HttpsProxyAgent(`http://${session.ip}`), `${constants.PROXY_API_URL}/v1/book/delete-multiple?authorization=${encodeURIComponent(session.sessionToken)}`,
{
method: "POST", method: "POST",
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS, "Content-Type": "application/json",
"Content-Type": "application/json;charset=UTF-8",
Authorization: session.sessionToken,
"User-Agent": getRandomUserAgent(),
}, },
body: JSON.stringify({ body: JSON.stringify({
bookIds: data.map((e) => e.bookId), bookIds: data.map((e) => e.bookId),
@@ -328,7 +305,8 @@ async function deleteAllBookedEntries({
dealerId, dealerId,
drawId, drawId,
}), }),
}); },
);
} }
// export async function postDataToApi(payload: { // export async function postDataToApi(payload: {

View File

@@ -1,30 +1,26 @@
import { getSessionToken } from "$lib/server/external/api.scraping.helpers";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "../t";
import { constants } from "$lib/utils/constants";
import { getUUID } from "$lib/utils";
import { z } from "zod";
import { dbApiUser } from "$lib/server/db/apiuser.db"; import { dbApiUser } from "$lib/server/db/apiuser.db";
import type { ServerError } from "$lib/utils/data.types"; import { getSessionToken } from "$lib/server/external/api.scraping.helpers";
import { import {
isSessionValidInStore, isSessionValidInStore,
removeSessionFromStore, removeSessionFromStore,
setSessionToRedis, setSessionToRedis,
} from "$lib/server/utils/session.service"; } from "$lib/server/utils/session.service";
import { getUUID } from "$lib/utils";
import { constants } from "$lib/utils/constants";
import type { ServerError } from "$lib/utils/data.types";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { createTRPCRouter, protectedProcedure } from "../t";
export const apiAuthRouter = createTRPCRouter({ export const apiAuthRouter = createTRPCRouter({
getCaptcha: protectedProcedure.mutation(async () => { getCaptcha: protectedProcedure.mutation(async () => {
try { try {
const uuid = getUUID(); const uuid = getUUID();
const res = await fetch( const res = await fetch(`${constants.PROXY_API_URL}/verify/image?uuid=${uuid}`, {
`${constants.SCRAP_API_URL}/verify/image?uuid=${uuid}`,
{
headers: { headers: {
...constants.SCRAP_API_BASE_HEADERS, "Content-Type": "application/json",
Accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
}, },
}, });
);
const bloob = await res.blob(); const bloob = await res.blob();
const imageBuffer = Buffer.from(await bloob.arrayBuffer()); const imageBuffer = Buffer.from(await bloob.arrayBuffer());
const base64String = imageBuffer.toString("base64"); const base64String = imageBuffer.toString("base64");
@@ -50,8 +46,7 @@ export const apiAuthRouter = createTRPCRouter({
console.log("[=] Getting new session... ", input); console.log("[=] Getting new session... ", input);
try { try {
const { captchaId, captchaAnswer } = input; const { captchaId, captchaAnswer } = input;
let { userId, userType, password } = let { userId, userType, password } = await dbApiUser.getRandomDistributor();
await dbApiUser.getRandomDistributor();
if (input.userId) { if (input.userId) {
let _user = await dbApiUser.getUserById(input.userId); let _user = await dbApiUser.getUserById(input.userId);
@@ -74,10 +69,7 @@ export const apiAuthRouter = createTRPCRouter({
userType: userType, userType: userType,
password: password, password: password,
}); });
console.log( console.log("[=] Token Response :: ", JSON.stringify(token, null, 2));
"[=] Token Response :: ",
JSON.stringify(token, null, 2),
);
if (!token.ok) { if (!token.ok) {
return { return {
success: false, success: false,

View File

@@ -4,6 +4,7 @@ export const constants = {
POST_SESSION_KEY: "postsession", POST_SESSION_KEY: "postsession",
LAST_FETCHED_KEY: "LAST_FETCHED", LAST_FETCHED_KEY: "LAST_FETCHED",
SCRAP_API_URL: "https://gamebooking24.com/lottery-api", SCRAP_API_URL: "https://gamebooking24.com/lottery-api",
PROXY_API_URL: "http://localhost:3070",
SCRAP_API_SESSION_KEY: "SRAJWT", SCRAP_API_SESSION_KEY: "SRAJWT",
SCRAP_API_BASE_HEADERS: { SCRAP_API_BASE_HEADERS: {
Host: "gamebooking24.com", Host: "gamebooking24.com",