diff --git a/03_source/cms_backend/src/app/api/party-user-auth/me/route.ts b/03_source/cms_backend/src/app/api/party-user-auth/me/route.ts index ce056b1..235afaa 100644 --- a/03_source/cms_backend/src/app/api/party-user-auth/me/route.ts +++ b/03_source/cms_backend/src/app/api/party-user-auth/me/route.ts @@ -1,5 +1,14 @@ -import type { User } from '@prisma/client'; +// src/app/api/party-user-auth/me/route.ts +// +// PURPOSE: +// - Handle authentication for party users via JWT +// - Verify and decode JWT tokens +// - Return current authenticated party user details +// - Log all access attempts (success/failure) +// - Validate token structure and user existence +// import type { NextRequest } from 'next/server'; +import type { PartyUser } from '@prisma/client'; import { headers } from 'next/headers'; @@ -7,15 +16,13 @@ import { verify } from 'src/utils/jwt'; import { STATUS, response, handleError } from 'src/utils/response'; import { JWT_SECRET } from 'src/_mock/_auth'; -import { getUserById } from 'src/app/services/user.service'; import { createAccessLog } from 'src/app/services/access-log.service'; +import { getPartyUserById } from 'src/app/services/party-user.service'; import { flattenNextjsRequest } from '../sign-in/flattenNextjsRequest'; // ---------------------------------------------------------------------- -// export const runtime = 'edge'; - /** * This API is used for demo purpose only * You should use a real database @@ -24,11 +31,12 @@ import { flattenNextjsRequest } from '../sign-in/flattenNextjsRequest'; * You should not expose the JWT_SECRET in the client side */ -const USER_TOKEN_CHECK_FAILED = 'user token check failed'; -const INVALID_AUTH_TOKEN = 'Invalid authorization token'; -const USER_ID_NOT_FOUND = 'userId not found'; +const ERR_USER_TOKEN_CHECK_FAILED = 'user token check failed'; +const ERR_INVALID_AUTH_TOKEN = 'Invalid authorization token'; +const ERR_USER_ID_NOT_FOUND = 'userId not found'; +const ERR_AUTHORIZATION_TOKEN_MISSING_OR_INVALID = 'Authorization token missing or invalid'; + const USER_TOKEN_OK = 'user token check ok'; -const AUTHORIZATION_TOKEN_MISSING_OR_INVALID = 'Authorization token missing or invalid'; export async function GET(req: NextRequest) { const debug = { 'req.headers': flattenNextjsRequest(req) }; @@ -38,29 +46,29 @@ export async function GET(req: NextRequest) { const authorization = headersList.get('authorization'); if (!authorization || !authorization.startsWith('Bearer ')) { - return response({ message: AUTHORIZATION_TOKEN_MISSING_OR_INVALID }, STATUS.UNAUTHORIZED); + return response({ message: ERR_AUTHORIZATION_TOKEN_MISSING_OR_INVALID }, STATUS.UNAUTHORIZED); } const accessToken = `${authorization}`.split(' ')[1]; const data = await verify(accessToken, JWT_SECRET); - console.log(data.userId); if (data.userId) { // TODO: remove me // const currentUser = _users.find((user) => user.id === data.userId); - const currentUser: User | null = await getUserById(data.userId); + // const currentUser: User | null = await getUserById(data.userId); + const currentUser: PartyUser | null = await getPartyUserById(data.userId); if (!currentUser) { - createAccessLog('', USER_TOKEN_CHECK_FAILED, debug); + createAccessLog('', ERR_USER_TOKEN_CHECK_FAILED, debug); - return response({ message: INVALID_AUTH_TOKEN }, STATUS.UNAUTHORIZED); + return response({ message: ERR_INVALID_AUTH_TOKEN }, STATUS.UNAUTHORIZED); } createAccessLog(currentUser.id, USER_TOKEN_OK, debug); return response({ user: currentUser }, STATUS.OK); } else { - return response({ message: USER_ID_NOT_FOUND }, STATUS.ERROR); + return response({ message: ERR_USER_ID_NOT_FOUND }, STATUS.ERROR); } } catch (error) { return handleError('[Auth] - Me', error); diff --git a/03_source/cms_backend/src/app/api/party-user-auth/me/test.http b/03_source/cms_backend/src/app/api/party-user-auth/me/test.http index 4bcb1a1..d53182f 100644 --- a/03_source/cms_backend/src/app/api/party-user-auth/me/test.http +++ b/03_source/cms_backend/src/app/api/party-user-auth/me/test.http @@ -1,22 +1,35 @@ +// Test cases for Party User Authentication endpoints +// Tests both successful and error scenarios +// Environment: http://localhost:7272 +// Expected responses: +// - 200 OK with user data for valid tokens +// - 401 Unauthorized for invalid/missing tokens +// - 400 Bad Request for invalid credentials + ### + # username and password ok -GET http://localhost:7272/api/auth/me -Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjbWJnbnUyengwMDBjaHEzaGZ3dmtjejlvIiwiaWF0IjoxNzQ4OTY0ODkyLCJleHAiOjE3NTAxNzQ0OTJ9.lo04laCxtm0IVeYaETEV3hXKyDmXPEn7SyWtY2VR4dI +GET http://localhost:7272/api/party-user-auth/me +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjbWMwdWo4azIwMDBxM2Y1eTZlNXJzejRxIiwiaWF0IjoxNzUwMjEzOTkwLCJleHAiOjE3NTE0MjM1OTB9.MoKv3Nmrp_blE0jQ1rG1WyQ_TrJeF7kSe5xfHrF8b64 ### + # There is no user corresponding to the email address. -POST http://localhost:7272/api/auth/sign-in + +POST http://localhost:7272/api/party-user-auth/sign-in content-type: application/json { - "email": "demo@minimals1.cc", + "email": "demo@minimals.cc", "password": "@2Minimal" } ### + # Wrong password -POST http://localhost:7272/api/auth/sign-in + +POST http://localhost:7272/api/party-user-auth/sign-in content-type: application/json { diff --git a/03_source/cms_backend/src/app/services/party-user.service.ts b/03_source/cms_backend/src/app/services/party-user.service.ts index db34e33..92540fb 100644 --- a/03_source/cms_backend/src/app/services/party-user.service.ts +++ b/03_source/cms_backend/src/app/services/party-user.service.ts @@ -1,14 +1,18 @@ -// src/app/services/user.service.ts +// src/app/services/party-user.service.ts // // PURPOSE: -// - Handle User Record CRUD operations +// - Handle Party User Record CRUD operations +// - Manage party member data and permissions +// - Interface between controllers and database // // RULES: // - Follow Prisma best practices for database operations -// - Validate input data before processing +// - Validate all party user data before processing +// - Enforce party-specific business rules +// - Maintain audit trail for sensitive operations // -import type { User, PartyUser } from '@prisma/client'; +import type { PartyUser } from '@prisma/client'; import prisma from '../lib/prisma'; @@ -47,8 +51,8 @@ async function getPartyUserByEmail(email: string): Promise { }); } -async function getUserById(id: string): Promise { - return prisma.user.findFirst({ where: { id } }); +async function getPartyUserById(id: string): Promise { + return prisma.partyUser.findFirst({ where: { id } }); } async function createPartyUser(partyUserData: any): Promise { @@ -69,7 +73,7 @@ async function deletePartyUser(partyUserId: string): Promise { } export { - getUserById, + getPartyUserById, getPartyUser, listPartyUsers, createPartyUser,