fix invite issue.

This commit is contained in:
Fizer Khan
2025-12-05 09:55:21 +05:30
parent 67976fc35b
commit 330fbcbd42
6 changed files with 283 additions and 58 deletions
+16
View File
@@ -6,6 +6,8 @@ import {
ForgotPasswordSchema,
ResetPasswordSchema,
MfaVerifySchema,
UpdateProfileSchema,
ChangePasswordSchema,
} from '../../../../shared/src/index';
import * as authService from './auth.service';
import { authenticate } from '../../common/middleware/auth';
@@ -105,4 +107,18 @@ export const authRoutes: FastifyPluginAsync = async (fastify) => {
await authService.disableMfa(request.user!.sub);
return { success: true };
});
// PATCH /auth/profile - Update profile
fastify.patch('/profile', { preHandler: authenticate }, async (request) => {
const body = UpdateProfileSchema.parse(request.body);
const user = await authService.updateProfile(request.user!.sub, body);
return { user };
});
// POST /auth/change-password - Change password
fastify.post('/change-password', { preHandler: authenticate }, async (request) => {
const body = ChangePasswordSchema.parse(request.body);
await authService.changePassword(request.user!.sub, body.currentPassword, body.newPassword);
return { message: 'Password changed successfully' };
});
};
+56
View File
@@ -352,6 +352,62 @@ export async function disableMfa(userId: string): Promise<void> {
});
}
// ==================== Profile Updates ====================
export async function updateProfile(
userId: string,
data: { firstName?: string; lastName?: string; email?: string }
): Promise<User> {
// If email is being changed, check for conflicts
if (data.email) {
const existingUser = await prisma.user.findFirst({
where: {
email: data.email.toLowerCase(),
id: { not: userId },
},
});
if (existingUser) {
throw new ConflictError('Email is already in use');
}
}
const user = await prisma.user.update({
where: { id: userId },
data: {
...(data.firstName && { firstName: data.firstName }),
...(data.lastName && { lastName: data.lastName }),
...(data.email && { email: data.email.toLowerCase() }),
},
});
return mapUser(user);
}
export async function changePassword(
userId: string,
currentPassword: string,
newPassword: string
): Promise<void> {
const user = await prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
throw new NotFoundError('User');
}
const isValidPassword = await verifyPassword(user.passwordHash, currentPassword);
if (!isValidPassword) {
throw new ValidationError('Current password is incorrect');
}
const passwordHash = await hashPassword(newPassword);
await prisma.user.update({
where: { id: userId },
data: { passwordHash },
});
}
// ==================== Helpers ====================
async function generateTokens(
@@ -3,7 +3,7 @@ import { z } from 'zod';
import { randomBytes } from 'crypto';
import { prisma } from '../../lib/prisma';
import { authenticate, optionalAuthenticate } from '../../common/middleware/auth';
import { NotFoundError, ConflictError, ForbiddenError } from '@nats-console/shared';
import { NotFoundError, ConflictError, ForbiddenError } from '../../../../shared/src/index';
const CreateInviteSchema = z.object({
email: z.string().email(),