| | |
| |
|
| | import axios, { AxiosResponse, AxiosError } from 'axios'; |
| | import { Request, Response } from 'express'; |
| |
|
| | console.log(`[Register Module] src/register.ts file is being evaluated. __dirname is: ${__dirname}`); |
| |
|
| | interface PastebinResponse { |
| | link: string; |
| | } |
| |
|
| | interface RegisterClientPayload { |
| | user: string; |
| | pass: string; |
| | email: string; |
| | nickname?: string; |
| | avatar?: string; |
| | bio?: string; |
| | dob?: string; |
| | cover_photo?: string; |
| | country?: string; |
| | timezone?: string; |
| | } |
| |
|
| | type ExternalApiSignUpPayload = RegisterClientPayload; |
| |
|
| | interface RegisterApiResponseData { |
| | status: string; |
| | token?: string; |
| | cookies?: string; |
| | avatar?: string; |
| | cover_photo?: string; |
| | message?: string; |
| | } |
| |
|
| | function isRegisterClientPayload(body: any): body is RegisterClientPayload { |
| | return !!(body && typeof body === 'object' && |
| | typeof body.user === 'string' && body.user.length > 0 && |
| | typeof body.pass === 'string' && body.pass.length > 0 && |
| | typeof body.email === 'string' && body.email.length > 0); |
| | } |
| |
|
| | function isRegisterApiResponseData(data: any): data is RegisterApiResponseData { |
| | return !!(data && typeof data === 'object' && typeof data.status === 'string'); |
| | } |
| |
|
| | const api = { |
| | async getLink(): Promise<string> { |
| | console.log("[Register API - getLink] Attempting to fetch link..."); |
| | try { |
| | const res: AxiosResponse<string | PastebinResponse> = await axios.get('https://pastebin.com/raw/YtqNc7Yi'); |
| | const responseData = res.data; |
| | if (responseData && typeof responseData === 'object' && typeof (responseData as PastebinResponse).link === 'string') { |
| | return (responseData as PastebinResponse).link; |
| | } else if (typeof responseData === 'string' && responseData.startsWith('http')) { |
| | return responseData; |
| | } |
| | throw new Error('Invalid or missing link in Pastebin response data.'); |
| | } catch (err: unknown) { |
| | const error = err instanceof Error ? err : new Error(String(err)); |
| | throw new Error('Failed to get base link.', { cause: error }); |
| | } |
| | }, |
| |
|
| | async register(body: ExternalApiSignUpPayload): Promise<RegisterApiResponseData> { |
| | console.log("[Register API - register] Attempting external API signup, payload:", body); |
| | try { |
| | const link: string = await api.getLink(); |
| | const res: AxiosResponse<RegisterApiResponseData> = await axios.post(`${link}/signup`, body); |
| | console.log("[Register API - register] Response from external API:", res.data); |
| | return res.data; |
| | } catch (err: unknown) { |
| | const error = err instanceof Error ? err : new Error(String(err)); |
| | if (axios.isAxiosError(error) && error.response) { |
| | console.error("Axios error data:", error.response.data, "Status:", error.response.status); |
| | } |
| | throw new Error('Failed to contact/process signup endpoint.', { cause: error }); |
| | } |
| | }, |
| | }; |
| |
|
| | interface RegisterRouteParams { |
| | req: Request<any, any, any>; |
| | res: Response; |
| | } |
| |
|
| | interface RegisterExpressRouteModule { |
| | method: "get" | "post" | "put" | "delete" | "patch" | "options" | "head" | "all"; |
| | path: string; |
| | install: (params: RegisterRouteParams) => Promise<void> | void; |
| | } |
| |
|
| | export const modules: RegisterExpressRouteModule[] = [ |
| | { |
| | method: 'post', |
| | path: '/register', |
| | install: async ({ req, res }: RegisterRouteParams): Promise<void> => { |
| | console.log(`[Register Route] Handler for ${req.method.toUpperCase()} ${req.path}`); |
| | const rawClientBody: unknown = req.body; |
| | console.log("[Register Route] Raw request body from client:", rawClientBody); |
| |
|
| | try { |
| | if (isRegisterClientPayload(rawClientBody)) { |
| | const clientData: RegisterClientPayload = rawClientBody; |
| |
|
| | const payloadForExternalApi: ExternalApiSignUpPayload = { |
| | user: clientData.user, |
| | pass: clientData.pass, |
| | email: clientData.email, |
| | }; |
| |
|
| | if (clientData.nickname && clientData.nickname.trim() !== "") payloadForExternalApi.nickname = clientData.nickname; |
| | if (clientData.avatar && clientData.avatar.trim() !== "") payloadForExternalApi.avatar = clientData.avatar; |
| | if (clientData.bio && clientData.bio.trim() !== "") payloadForExternalApi.bio = clientData.bio; |
| | if (clientData.dob && clientData.dob.trim() !== "") payloadForExternalApi.dob = clientData.dob; |
| | if (clientData.cover_photo && clientData.cover_photo.trim() !== "") payloadForExternalApi.cover_photo = clientData.cover_photo; |
| | if (clientData.country && clientData.country.trim() !== "") payloadForExternalApi.country = clientData.country; |
| | if (clientData.timezone && clientData.timezone.trim() !== "") payloadForExternalApi.timezone = clientData.timezone; |
| |
|
| | const rawApiResult: RegisterApiResponseData = await api.register(payloadForExternalApi); |
| |
|
| | if (isRegisterApiResponseData(rawApiResult)) { |
| | const resultFromExternalApi: RegisterApiResponseData = rawApiResult; |
| |
|
| | if (resultFromExternalApi.status === 'success') { |
| | console.log("[Register Route] External API reported SUCCESS."); |
| | res.json({ |
| | success: true, |
| | message: resultFromExternalApi.message || "Registration successful!", |
| | data: resultFromExternalApi |
| | }); |
| | } else { |
| | console.warn("[Register Route] External API reported FAILURE. Status:", resultFromExternalApi.status, "Message:", resultFromExternalApi.message); |
| | res.status(400).json({ |
| | success: false, |
| | error: resultFromExternalApi.message || "Registration failed at external API." |
| | }); |
| | } |
| | } else { |
| | console.error("[Register Route] Unexpected response structure from external API:", rawApiResult); |
| | res.status(500).json({ success: false, error: "Received an unexpected response from the registration service." }); |
| | } |
| |
|
| | } else { |
| | console.warn("[Register Route] Validation failed: req.body does not conform to RegisterClientPayload. Received:", rawClientBody); |
| | res.status(400).json({ success: false, error: 'Invalid registration data: user, pass, and email are required and must be valid non-empty strings.' }); |
| | return; |
| | } |
| | } catch (err: unknown) { |
| | const error = err instanceof Error ? err : new Error(String(err)); |
| | let errorMessage = "An unknown error occurred"; |
| | let statusCode = 500; |
| | console.error(`[Register Route] Overall error:`, error.message, (error as any).cause || error); |
| |
|
| | const originalError = (error as any).cause || error; |
| |
|
| | if (axios.isAxiosError(originalError)) { |
| | const axiosError = originalError as AxiosError<any>; |
| | errorMessage = axiosError.message; |
| | statusCode = axiosError.response?.status || 503; |
| | const responseData = axiosError.response?.data; |
| | const specificApiError = responseData?.error || responseData?.message; |
| |
|
| | if (specificApiError) { |
| | errorMessage = `Reg API Error (${statusCode}): ${specificApiError}`; |
| | } else if (axiosError.response) { |
| | errorMessage = `Reg API Error (${statusCode}): Req failed (status ${statusCode}).`; |
| | } else if (axiosError.request) { |
| | errorMessage = `No response from reg service: ${axiosError.message}`; |
| | } |
| | } else if (originalError instanceof Error) { |
| | errorMessage = originalError.message || String(originalError); |
| | } else { |
| | errorMessage = String(originalError); |
| | } |
| |
|
| | console.error(`[Register Route] Error to client: ${errorMessage}, Status: ${statusCode}`); |
| | if (!res.headersSent) { |
| | res.status(statusCode).json({ success: false, error: errorMessage }); |
| | } else { |
| | console.warn("[Register Route] Headers sent, cannot send error."); |
| | } |
| | } |
| | }, |
| | }, |
| | ]; |
| |
|