refactor: update user identification to pass userId directly to services instead of JWT tokens.
Some checks failed
Build and Deploy Backend / Build Backend Docker Image (push) Successful in 48s
Build and Deploy Backend / Deploy E-learning Backend to Dev Server (push) Successful in 9s
Build and Deploy Backend / Notify Deployment Status (push) Successful in 2s
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Failing after 33s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Has been skipped
Build and Deploy Frontend Learner / Notify Deployment Status (push) Failing after 1s
Some checks failed
Build and Deploy Backend / Build Backend Docker Image (push) Successful in 48s
Build and Deploy Backend / Deploy E-learning Backend to Dev Server (push) Successful in 9s
Build and Deploy Backend / Notify Deployment Status (push) Successful in 2s
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Failing after 33s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Has been skipped
Build and Deploy Frontend Learner / Notify Deployment Status (push) Failing after 1s
This commit is contained in:
parent
b6c1aebe30
commit
522a0eec8a
28 changed files with 558 additions and 952 deletions
|
|
@ -24,15 +24,10 @@ import { auditService } from './audit.service';
|
|||
import { AuditAction } from '@prisma/client';
|
||||
|
||||
export class UserService {
|
||||
async getUserProfile(token: string): Promise<UserResponse> {
|
||||
async getUserProfile(userId: number): Promise<UserResponse> {
|
||||
try {
|
||||
// Decode JWT token to get user ID
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; username: string; email: string; roleCode: string };
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: decoded.id
|
||||
},
|
||||
where: { id: userId },
|
||||
include: {
|
||||
profile: true,
|
||||
role: true
|
||||
|
|
@ -68,14 +63,6 @@ export class UserService {
|
|||
} : undefined
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.error('Invalid JWT token:', error);
|
||||
throw new UnauthorizedError('Invalid token');
|
||||
}
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.error('JWT token expired:', error);
|
||||
throw new UnauthorizedError('Token expired');
|
||||
}
|
||||
logger.error('Error fetching user profile:', error);
|
||||
throw error;
|
||||
}
|
||||
|
|
@ -84,12 +71,9 @@ export class UserService {
|
|||
/**
|
||||
* Change user password
|
||||
*/
|
||||
async changePassword(token: string, oldPassword: string, newPassword: string): Promise<ChangePasswordResponse> {
|
||||
async changePassword(userId: number, oldPassword: string, newPassword: string): Promise<ChangePasswordResponse> {
|
||||
try {
|
||||
// Decode JWT token to get user ID
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; username: string; email: string; roleCode: string };
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: decoded.id } });
|
||||
const user = await prisma.user.findUnique({ where: { id: userId } });
|
||||
if (!user) throw new UnauthorizedError('User not found');
|
||||
|
||||
// Check if account is deactivated
|
||||
|
|
@ -127,21 +111,12 @@ export class UserService {
|
|||
message: 'Password changed successfully'
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.error('Invalid JWT token:', error);
|
||||
throw new UnauthorizedError('Invalid token');
|
||||
}
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.error('JWT token expired:', error);
|
||||
throw new UnauthorizedError('Token expired');
|
||||
}
|
||||
logger.error('Failed to change password', { error });
|
||||
const decoded = jwt.decode(token) as { id: number } | null;
|
||||
await auditService.logSync({
|
||||
userId: decoded?.id || 0,
|
||||
userId,
|
||||
action: AuditAction.ERROR,
|
||||
entityType: 'User',
|
||||
entityId: decoded?.id || 0,
|
||||
entityId: userId,
|
||||
metadata: {
|
||||
operation: 'change_password',
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
|
|
@ -154,12 +129,9 @@ export class UserService {
|
|||
/**
|
||||
* Update user profile
|
||||
*/
|
||||
async updateProfile(token: string, profile: ProfileUpdate): Promise<ProfileUpdateResponse> {
|
||||
async updateProfile(userId: number, profile: ProfileUpdate): Promise<ProfileUpdateResponse> {
|
||||
try {
|
||||
// Decode JWT token to get user ID
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; username: string; email: string; roleCode: string };
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: decoded.id } });
|
||||
const user = await prisma.user.findUnique({ where: { id: userId } });
|
||||
if (!user) throw new UnauthorizedError('User not found');
|
||||
|
||||
// Check if account is deactivated
|
||||
|
|
@ -189,21 +161,12 @@ export class UserService {
|
|||
}
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.error('Invalid JWT token:', error);
|
||||
throw new UnauthorizedError('Invalid token');
|
||||
}
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.error('JWT token expired:', error);
|
||||
throw new UnauthorizedError('Token expired');
|
||||
}
|
||||
logger.error('Failed to update profile', { error });
|
||||
const decoded = jwt.decode(token) as { id: number } | null;
|
||||
await auditService.logSync({
|
||||
userId: decoded?.id || 0,
|
||||
userId,
|
||||
action: AuditAction.UPDATE,
|
||||
entityType: 'UserProfile',
|
||||
entityId: decoded?.id || 0,
|
||||
entityId: userId,
|
||||
metadata: {
|
||||
operation: 'update_profile',
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
|
|
@ -213,9 +176,8 @@ export class UserService {
|
|||
}
|
||||
}
|
||||
|
||||
async getRoles(token: string): Promise<rolesResponse> {
|
||||
async getRoles(): Promise<rolesResponse> {
|
||||
try {
|
||||
jwt.verify(token, config.jwt.secret);
|
||||
const roles = await prisma.role.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
|
|
@ -224,14 +186,6 @@ export class UserService {
|
|||
});
|
||||
return { roles };
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.error('JWT token expired:', error);
|
||||
throw new UnauthorizedError('Token expired');
|
||||
}
|
||||
if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.error('Invalid JWT token:', error);
|
||||
throw new UnauthorizedError('Invalid token');
|
||||
}
|
||||
logger.error('Failed to get roles', { error });
|
||||
throw error;
|
||||
}
|
||||
|
|
@ -240,13 +194,11 @@ export class UserService {
|
|||
/**
|
||||
* Upload avatar picture to MinIO
|
||||
*/
|
||||
async uploadAvatarPicture(token: string, file: Express.Multer.File): Promise<updateAvatarResponse> {
|
||||
async uploadAvatarPicture(userId: number, file: Express.Multer.File): Promise<updateAvatarResponse> {
|
||||
try {
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as { id: number };
|
||||
|
||||
// Check if user exists
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: decoded.id },
|
||||
where: { id: userId },
|
||||
include: { profile: true }
|
||||
});
|
||||
|
||||
|
|
@ -265,7 +217,7 @@ export class UserService {
|
|||
const fileName = file.originalname || 'avatar';
|
||||
const extension = fileName.split('.').pop() || 'jpg';
|
||||
const safeFilename = `${timestamp}-${uniqueId}.${extension}`;
|
||||
const filePath = `avatars/${decoded.id}/${safeFilename}`;
|
||||
const filePath = `avatars/${userId}/${safeFilename}`;
|
||||
|
||||
// Delete old avatar if exists
|
||||
if (user.profile?.avatar_url) {
|
||||
|
|
@ -285,13 +237,13 @@ export class UserService {
|
|||
// Update or create profile - store only file path
|
||||
if (user.profile) {
|
||||
await prisma.userProfile.update({
|
||||
where: { user_id: decoded.id },
|
||||
where: { user_id: userId },
|
||||
data: { avatar_url: filePath }
|
||||
});
|
||||
} else {
|
||||
await prisma.userProfile.create({
|
||||
data: {
|
||||
user_id: decoded.id,
|
||||
user_id: userId,
|
||||
avatar_url: filePath,
|
||||
first_name: '',
|
||||
last_name: ''
|
||||
|
|
@ -301,10 +253,10 @@ export class UserService {
|
|||
|
||||
// Audit log - UPLOAD_AVATAR
|
||||
await auditService.logSync({
|
||||
userId: decoded.id,
|
||||
userId,
|
||||
action: AuditAction.UPLOAD_FILE,
|
||||
entityType: 'User',
|
||||
entityId: decoded.id,
|
||||
entityId: userId,
|
||||
metadata: {
|
||||
operation: 'upload_avatar',
|
||||
filePath
|
||||
|
|
@ -318,26 +270,17 @@ export class UserService {
|
|||
code: 200,
|
||||
message: 'Avatar uploaded successfully',
|
||||
data: {
|
||||
id: decoded.id,
|
||||
id: userId,
|
||||
avatar_url: presignedUrl
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.JsonWebTokenError) {
|
||||
logger.error('Invalid JWT token:', error);
|
||||
throw new UnauthorizedError('Invalid token');
|
||||
}
|
||||
if (error instanceof jwt.TokenExpiredError) {
|
||||
logger.error('JWT token expired:', error);
|
||||
throw new UnauthorizedError('Token expired');
|
||||
}
|
||||
logger.error('Failed to upload avatar', { error });
|
||||
const decoded = jwt.decode(token) as { id: number } | null;
|
||||
await auditService.logSync({
|
||||
userId: decoded?.id || 0,
|
||||
userId,
|
||||
action: AuditAction.UPLOAD_FILE,
|
||||
entityType: 'UserProfile',
|
||||
entityId: decoded?.id || 0,
|
||||
entityId: userId,
|
||||
metadata: {
|
||||
operation: 'upload_avatar',
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
|
|
@ -390,12 +333,10 @@ export class UserService {
|
|||
/**
|
||||
* Send verification email to user
|
||||
*/
|
||||
async sendVerifyEmail(token: string): Promise<SendVerifyEmailResponse> {
|
||||
async sendVerifyEmail(userId: number): Promise<SendVerifyEmailResponse> {
|
||||
try {
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; email: string; roleCode: string };
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: decoded.id },
|
||||
where: { id: userId },
|
||||
include: { role: true }
|
||||
});
|
||||
|
||||
|
|
@ -453,15 +394,12 @@ export class UserService {
|
|||
message: 'Verification email sent successfully'
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.JsonWebTokenError) throw new UnauthorizedError('Invalid token');
|
||||
if (error instanceof jwt.TokenExpiredError) throw new UnauthorizedError('Token expired');
|
||||
logger.error('Failed to send verification email', { error });
|
||||
const decoded = jwt.decode(token) as { id: number } | null;
|
||||
await auditService.logSync({
|
||||
userId: decoded?.id || 0,
|
||||
userId,
|
||||
action: AuditAction.ERROR,
|
||||
entityType: 'UserProfile',
|
||||
entityId: decoded?.id || 0,
|
||||
entityId: userId,
|
||||
metadata: {
|
||||
operation: 'send_verification_email',
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue