diff --git a/serverless/functions/user.yml b/serverless/functions/user.yml index f7aff48..6b95c35 100644 --- a/serverless/functions/user.yml +++ b/serverless/functions/user.yml @@ -62,6 +62,22 @@ setPasscodeForMobile: path: /user/set-passcode method: post + +verifyPasscode: + handler: src/modules/user/handlers/authentication/verifyPasscode.handler + memorySize: 384 + package: + patterns: + - 'src/modules/user/**' + - ${file(./serverless/patterns/base.yml):pattern1} + - ${file(./serverless/patterns/base.yml):pattern2} + - ${file(./serverless/patterns/base.yml):pattern3} + - ${file(./serverless/patterns/base.yml):pattern4} + events: + - httpApi: + path: /user/verify-passcode + method: post + setUserInterest: handler: src/modules/user/handlers/authentication/SetuserInterest.handler memorySize: 384 diff --git a/src/modules/user/handlers/authentication/verifyPasscode.ts b/src/modules/user/handlers/authentication/verifyPasscode.ts new file mode 100644 index 0000000..5a39e6b --- /dev/null +++ b/src/modules/user/handlers/authentication/verifyPasscode.ts @@ -0,0 +1,62 @@ +import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; +import { prismaClient } from '../../../../common/database/prisma.lambda.service'; +import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser'; +import { safeHandler } from '../../../../common/utils/handlers/safeHandler'; +import ApiError from '../../../../common/utils/helper/ApiError'; +import { UserService } from '../../services/user.service'; + +const userService = new UserService(prismaClient); + +export const handler = safeHandler(async ( + event: APIGatewayProxyEvent, + context?: Context +): Promise => { + // Extract token from headers + const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token']; + if (!token) { + throw new ApiError(400, 'This is a protected route. Please provide a valid token.'); + } + + // Authenticate user using verifyUserToken + const userInfo = await verifyUserToken(token); + const userId = userInfo.id; + + if (Number.isNaN(userId)) { + throw new ApiError(400, 'User id must be a number'); + } + + // Parse request body + let body: { passcode?: string; }; + + try { + body = event.body ? JSON.parse(event.body) : {}; + } catch (error) { + throw new ApiError(400, 'Invalid JSON in request body'); + } + + const { passcode } = body; + + // Validate required fields + if (!passcode) { + throw new ApiError(400, 'passcode is required'); + } + + // Verify the passcode + const isValid = await userService.verifyUserPasscode(userId, passcode); + + if (!isValid) { + throw new ApiError(400, 'Invalid passcode'); + } + + return { + statusCode: 200, + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + body: JSON.stringify({ + success: true, + message: 'Passcode verified successfully', + }), + }; +}); diff --git a/src/modules/user/services/user.service.ts b/src/modules/user/services/user.service.ts index 0c1747a..71ab06c 100644 --- a/src/modules/user/services/user.service.ts +++ b/src/modules/user/services/user.service.ts @@ -279,6 +279,25 @@ export class UserService { return updatedUser; } + async verifyUserPasscode(userId: number, passcode: string): Promise { + const user = await this.prisma.user.findUnique({ + where: { id: userId, isActive: true }, + select: { userPasscode: true }, + }); + + if (!user || !user.userPasscode) { + throw new ApiError(404, 'User passcode not found'); + } + + const isMatch = await bcrypt.compare(passcode, user.userPasscode); + + if (!isMatch) { + return false; + } + + return true; + } + async setUserInterests(userId: number, interest_Xid: number[]): Promise { // Remove existing interests await this.prisma.userInterests.deleteMany({