feat: add role-based frontend URL routing for password reset and email verification

Add separate frontend URL environment variables for student and instructor portals. Update password reset and email verification services to route users to the appropriate frontend based on their role (INSTRUCTOR vs STUDENT).
This commit is contained in:
JakkrapartXD 2026-01-30 17:29:08 +07:00
parent 16322454b1
commit bf5d939910
3 changed files with 23 additions and 8 deletions

View file

@ -36,3 +36,6 @@ CORS_ORIGIN=http://localhost:3000
# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
FRONTEND_URL_STUDENT=http://localhost:3000
FRONTEND_URL_INSTRUCTOR=http://localhost:3000

View file

@ -261,14 +261,21 @@ export class AuthService {
*/
async resetRequest(email: string): Promise<ResetRequestResponse> {
try {
// Find user
const user = await prisma.user.findUnique({ where: { email } });
// Find user with role
const user = await prisma.user.findUnique({
where: { email },
include: { role: true }
});
if (!user) throw new UnauthorizedError('User not found');
const token = jwt.sign({ id: user.id, email: user.email }, config.jwt.secret, { expiresIn: '1h' });
// Create reset URL
const resetURL = `${process.env.FRONTEND_URL || 'http://localhost:3000'}/reset-password?token=${token}`;
// Create reset URL based on role
const isInstructor = user.role.code === 'INSTRUCTOR';
const baseUrl = isInstructor
? (process.env.FRONTEND_URL_INSTRUCTOR || 'http://localhost:3001')
: (process.env.FRONTEND_URL_STUDENT || 'http://localhost:3000');
const resetURL = `${baseUrl}/reset-password?token=${token}`;
// Create transporter
const transporter = nodemailer.createTransport({

View file

@ -307,10 +307,11 @@ export class UserService {
*/
async sendVerifyEmail(token: string): Promise<SendVerifyEmailResponse> {
try {
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; email: string };
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: decoded.id },
include: { role: true }
});
if (!user) throw new UnauthorizedError('User not found');
@ -323,8 +324,12 @@ export class UserService {
{ expiresIn: '24h' }
);
// Create verification URL
const verifyURL = `${process.env.FRONTEND_URL || 'http://localhost:3000'}/verify-email?token=${verifyToken}`;
// Create verification URL based on role
const isInstructor = user.role.code === 'INSTRUCTOR';
const baseUrl = isInstructor
? (process.env.FRONTEND_URL_INSTRUCTOR || 'http://localhost:3001')
: (process.env.FRONTEND_URL_STUDENT || 'http://localhost:3000');
const verifyURL = `${baseUrl}/verify-email?token=${verifyToken}`;
// Create transporter
const transporter = nodemailer.createTransport({