chage api use token
This commit is contained in:
parent
6239159099
commit
d8a9909eb9
4 changed files with 17 additions and 23 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import { Body, Post, Route, Tags, SuccessResponse, Response, Example, Controller, Security } from 'tsoa';
|
import { Body, Post, Route, Tags, SuccessResponse, Response, Example, Controller, Security, Request } from 'tsoa';
|
||||||
import { AuthService } from '../services/auth.service';
|
import { AuthService } from '../services/auth.service';
|
||||||
import {
|
import {
|
||||||
LoginRequest,
|
LoginRequest,
|
||||||
|
|
@ -170,7 +170,7 @@ export class AuthController {
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new ValidationError(error.details[0].message);
|
throw new ValidationError(error.details[0].message);
|
||||||
}
|
}
|
||||||
return await this.authService.resetPassword(body.id, body.token, body.password);
|
return await this.authService.resetPassword(body.token, body.password);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -183,11 +183,15 @@ export class AuthController {
|
||||||
@Security('jwt')
|
@Security('jwt')
|
||||||
@SuccessResponse('200', 'Password changed successfully')
|
@SuccessResponse('200', 'Password changed successfully')
|
||||||
@Response('401', 'Invalid or expired reset token')
|
@Response('401', 'Invalid or expired reset token')
|
||||||
public async changePassword(@Body() body: ChangePassword): Promise<{ message: string }> {
|
public async changePassword(@Request() request: any, @Body() body: ChangePassword): Promise<{ message: string }> {
|
||||||
const { error } = changePasswordSchema.validate(body);
|
const { error } = changePasswordSchema.validate(body);
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new ValidationError(error.details[0].message);
|
throw new ValidationError(error.details[0].message);
|
||||||
}
|
}
|
||||||
return await this.authService.changePassword(body.id, body.oldPassword, body.newPassword);
|
const token = request.headers.authorization?.replace('Bearer ', '');
|
||||||
|
if (!token) {
|
||||||
|
throw new ValidationError('No token provided');
|
||||||
|
}
|
||||||
|
return await this.authService.changePassword(token, body.oldPassword, body.newPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ export class AuthService {
|
||||||
const token = jwt.sign({ id: user.id, email: user.email }, config.jwt.secret, { expiresIn: '1h' });
|
const token = jwt.sign({ id: user.id, email: user.email }, config.jwt.secret, { expiresIn: '1h' });
|
||||||
|
|
||||||
// Create reset URL
|
// Create reset URL
|
||||||
const resetURL = `${process.env.FRONTEND_URL || 'http://localhost:3000'}/reset-password?id=${user.id}&token=${token}`;
|
const resetURL = `${process.env.FRONTEND_URL || 'http://localhost:3000'}/reset-password?token=${token}`;
|
||||||
|
|
||||||
// Create transporter
|
// Create transporter
|
||||||
const transporter = nodemailer.createTransport({
|
const transporter = nodemailer.createTransport({
|
||||||
|
|
@ -231,9 +231,10 @@ export class AuthService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async resetPassword(id: number, token: string, password: string): Promise<ResetPasswordResponse> {
|
async resetPassword(token: string, password: string): Promise<ResetPasswordResponse> {
|
||||||
try {
|
try {
|
||||||
const user = await prisma.user.findUnique({ where: { id } });
|
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; email: string };
|
||||||
|
const user = await prisma.user.findUnique({ where: { id: decoded.id } });
|
||||||
if (!user) throw new UnauthorizedError('User not found');
|
if (!user) throw new UnauthorizedError('User not found');
|
||||||
|
|
||||||
const secret = config.jwt.secret;
|
const secret = config.jwt.secret;
|
||||||
|
|
@ -254,14 +255,15 @@ export class AuthService {
|
||||||
message: 'Password reset successfully'
|
message: 'Password reset successfully'
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to reset password', { id, error });
|
logger.error('Failed to reset password', { error });
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async changePassword(id: number, oldPassword: string, newPassword: string): Promise<ChangePasswordResponse> {
|
async changePassword(token: string, oldPassword: string, newPassword: string): Promise<ChangePasswordResponse> {
|
||||||
try {
|
try {
|
||||||
const user = await prisma.user.findUnique({ where: { 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 } });
|
||||||
if (!user) throw new UnauthorizedError('User not found');
|
if (!user) throw new UnauthorizedError('User not found');
|
||||||
|
|
||||||
const isPasswordValid = await bcrypt.compare(oldPassword, user.password);
|
const isPasswordValid = await bcrypt.compare(oldPassword, user.password);
|
||||||
|
|
@ -280,7 +282,7 @@ export class AuthService {
|
||||||
message: 'Password changed successfully'
|
message: 'Password changed successfully'
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to change password', { id, error });
|
logger.error('Failed to change password', { error });
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,11 @@ export interface ResetRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResetPasswordRequest {
|
export interface ResetPasswordRequest {
|
||||||
id: number;
|
|
||||||
token: string;
|
token: string;
|
||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChangePassword {
|
export interface ChangePassword {
|
||||||
id: number;
|
|
||||||
oldPassword: string;
|
oldPassword: string;
|
||||||
newPassword: string;
|
newPassword: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,11 +81,6 @@ export const refreshTokenSchema = Joi.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export const resetPasswordSchema = Joi.object({
|
export const resetPasswordSchema = Joi.object({
|
||||||
id: Joi.number()
|
|
||||||
.required()
|
|
||||||
.messages({
|
|
||||||
'any.required': 'User ID is required'
|
|
||||||
}),
|
|
||||||
token: Joi.string()
|
token: Joi.string()
|
||||||
.required()
|
.required()
|
||||||
.messages({
|
.messages({
|
||||||
|
|
@ -103,11 +98,6 @@ export const resetPasswordSchema = Joi.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export const changePasswordSchema = Joi.object({
|
export const changePasswordSchema = Joi.object({
|
||||||
id: Joi.number()
|
|
||||||
.required()
|
|
||||||
.messages({
|
|
||||||
'any.required': 'User ID is required'
|
|
||||||
}),
|
|
||||||
oldPassword: Joi.string()
|
oldPassword: Joi.string()
|
||||||
.min(6)
|
.min(6)
|
||||||
.max(100)
|
.max(100)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue