Actions
Feature #181
open
CN
CN
add-created-by-and-updated-by-sapi
Feature #181:
add-created-by-and-updated-by-sapi
Start date:
01/05/2026
Due date:
% Done:
0%
Estimated time:
Environment:
Develop
Description
- 5002 = jobpost
- 5003 = candidates
- 5006 = jobapplication
สร้างไฟล์ src/shared/utils/jwt.util.ts¶
export function decodeJwt<T = unknown>(token: string): T {
const parts = token.split(".");
if (parts.length !== 3) {
throw new Error("Invalid JWT format");
}
const payload = parts[1];
const decoded = Buffer.from(
payload.replace(/-/g, "+").replace(/_/g, "/"),
"base64",
).toString("utf-8");
return JSON.parse(decoded) as T;
}
แก้ไฟล์ auth-context.decorator.ts¶
import {
createParamDecorator,
ExecutionContext,
UnauthorizedException,
} from "@nestjs/common";
import type { Request } from "express";
import type { JWTPayload } from "@shared/auth/jwt-payload.interface";
import { decodeJwt } from "@shared/utils/jwt.util";
export interface AuthContext {
userId: string;
userName: string;
group: string[];
}
export const ExtractAuthContext = createParamDecorator(
(data: unknown, ctx: ExecutionContext): AuthContext => {
const request = ctx.switchToHttp().getRequest<Request>();
// Extract token from Authorization header
const authHeader = request.headers.authorization;
if (!authHeader) {
throw new UnauthorizedException("Authorization header is required");
}
const token = authHeader.replace("Bearer ", "").trim();
if (!token) {
throw new UnauthorizedException("Token is required");
}
const jwtPayload = decodeJwt<JWTPayload>(token);
if (!jwtPayload.sid || !jwtPayload.name || !jwtPayload.group) {
throw new UnauthorizedException("User detail not correct");
}
// Return auth context
return {
userId: jwtPayload.sid,
userName: jwtPayload.name,
group: jwtPayload.group,
};
},
);
แก้ไฟล์ src/shared/auth/jwt-payload.interface.ts¶
export interface JWTPayload {
sid: string;
name: string;
group: string[];
}
วิธีใช้ pass value ตั้งแต่ controller เข้าไป¶
@ExtractAuthContext() authContext: AuthContext
Actions