recipeList: [ ThirdPartyPasswordless.init({ providers: socialAuthConfigurations, contactMethod: 'EMAIL_OR_PHONE', flowType: 'USER_INPUT_CODE', emailDelivery: { override: (originalImplementation) => { return { ...originalImplementation, async sendEmail({ email, userInputCode }) { await authCustomMethods.sendEmail(email, userInputCode); }, }; }, }, smsDelivery: { override: (originalImplementation) => { return { ...originalImplementation, async sendSms({ phoneNumber, userInputCode }) { await authCustomMethods.sendSms(phoneNumber, userInputCode); }, }; }, }, override: { apis: (originalImplementation) => { return { ...originalImplementation, async signInUpPOST(input: any) { console.log('input', input); }, async consumeCodePOST(input) { // using any because supertokens doesn't return any well defined type // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: any = await originalImplementation.consumeCodePOST(input); if (data.status !== 'OK') { throw new BadRequestException(`${data.status}`); } if (data.createdNewRecipeUser && data?.user?.loginMethods?.length === 1) { authCustomMethods.postSignup(data, input.userContext); } const response = await authCustomMethods.postLogin(data, input.userContext); if (response) { return response; } // supertokens doesn't return any well defined type // eslint-disable-next-line @typescript-eslint/no-explicit-any const loginResponse: LoginResponseDto = { sAccessToken: data.session?.accessToken, sRefreshToken: data.session?.refreshToken?.token, userId: data.user?.id, }; input.options.res.sendJSONResponse(loginResponse); return data; }, async createCodePOST(input) { console.log('input', input); const data: any = await originalImplementation.createCodePOST(input); if (data.status !== 'OK') { throw new BadRequestException(`${data.status}`); } return data; }, async thirdPartySignInUpPOST(input) { // using any because supertokens doesn't return any well defined type // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: any = await originalImplementation.thirdPartySignInUpPOST(input); if (data.status !== 'OK') { throw new BadRequestException(`${data.status}`); } const response = await authCustomMethods.postLogin(data, input.userContext); if (response) { return response; } const loginResponse: LoginResponseDto = { sAccessToken: data.session?.accessToken, sRefreshToken: data.session?.refreshToken?.token, userId: data.user?.id, }; input.options.res.sendJSONResponse(loginResponse); return data; }, }; }, functions: (originalImplementation) => { return { ...originalImplementation, async thirdPartySignInUp(input) { const accountInfo: AccountInfo = { thirdParty: { id: input.thirdPartyId, userId: input.thirdPartyUserId, }, }; const existingUser = await authCustomMethods.existingUserCheck(accountInfo); if (input.email) { await authCustomMethods.checkUserAccountStatusByEmail(input.email); } if (!existingUser) { throw new BadRequestException('Signup is supported only by Mobile Number'); } const response = await originalImplementation.thirdPartySignInUp(input); return response; }, async signInUp(input: any) { console.log('input', input); }, async createCode(input: any) { console.log('input', input); const accountInfo: AccountInfo = { phoneNumber: input?.phoneNumber, email: input?.email, }; const existingUser = await authCustomMethods.existingUserCheck(accountInfo); if (!existingUser && input.email) { throw new BadRequestException('Signup is supported only by Mobile Number'); } const request: BaseRequest = supertokens.getRequestFromUserContext(input.userContext); const requestBody = await request.getJSONBody(); if (!existingUser && input.phoneNumber) { const { acceptTermsAndConditions } = requestBody; if (!acceptTermsAndConditions) { throw new BadRequestException('Please accept terms and conditions'); } } if (input.phoneNumber) { await authCustomMethods.checkUserAccountStatusByMobile(input.phoneNumber); } if (input.email) { await authCustomMethods.checkUserAccountStatusByEmail(input.email); } if (process.env.NODE_ENV !== 'production' && requestBody?.isTest) { input.userInputCode = '212121'; } const response = await originalImplementation.createCode(input); console.log('response', response); return response; }, }; }, }, }), Session.init({ cookieDomain: process.env.BACKEND_DOMAIN, cookieSameSite: 'none', cookieSecure: true, override: { apis: (originalImplementation) => { return { ...originalImplementation, async refreshPOST(input) { const data = await originalImplementation.refreshPOST(input); const tokens = data.getAllSessionTokensDangerously(); const response: LoginResponseDto = { sAccessToken: tokens?.accessToken, sRefreshToken: tokens?.refreshToken, }; input.options.res.sendJSONResponse(response); return data; }, }; }, functions: (originalImplementation) => { return { ...originalImplementation, async createNewSession(input) { try { const request: BaseRequest = supertokens.getRequestFromUserContext(input.userContext); let jwt: string; let ipInfo: IpInfoDto; let deviceInfo: UserDeviceInfoDto; if (request !== undefined) { jwt = await authCustomMethods.getAnonymousToken(input.userContext); } if (jwt) { const jwtToken = jwtService.verify(jwt); ipInfo = jwtToken?.anonymousSessionDto?.ipInfo; deviceInfo = jwtToken?.anonymousSessionDto?.deviceInfo; } if (!ipInfo) { const ipAddresses = request.getHeaderValue('x-forwarded-for') as string; const ipAddress: string = ipAddresses?.split(',')[0].trim(); ipInfo = await authCustomMethods.getIpInfo(ipAddress); logger.info(`ipAddress session creation: ${ipAddress}`); } if (!deviceInfo) { deviceInfo = authCustomMethods.getDeviceInformation(input.userContext); } input.accessTokenPayload = { ...input.accessTokenPayload, ipInfo, deviceInfo: { deviceIdentifier: deviceInfo?.deviceIdentifier, deviceType: deviceInfo?.deviceType, }, }; return originalImplementation.createNewSession(input); } catch (error) { throw new BadRequestException(`${error} `); } }, async regenerateAccessToken(input) { const data = await originalImplementation.regenerateAccessToken(input); return data; }, async refreshSession(input) { const request: BaseRequest = supertokens.getRequestFromUserContext(input.userContext); const ipAddresses = request.getHeaderValue('x-forwarded-for') as string; const ipAddress: string = ipAddresses?.split(',')[0].trim(); // using any because supertokens doesn't return any well defined type // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: any = await originalImplementation.refreshSession(input); const payload: AccessTokenPayload = data.getAccessTokenPayload(); const ipInfo = await authCustomMethods.getIpInfo(ipAddress); if (ipInfo.isProxy) { throw new UnauthorizedException({ message: 'Please turn off the VPN', statusCode: 403 }); } const regeneratedData = await this.regenerateAccessToken({ accessToken: data.getAccessToken(), newAccessTokenPayload: { ipInfo, deviceInfo: payload.deviceInfo, }, userContext: input.userContext, }); data.accessToken = regeneratedData.accessToken?.token; return data; }, }; }, }, }), ],