Email verification Backend
This commit is contained in:
@@ -77,10 +77,12 @@ userRouter.post('/create',
|
|||||||
email: req.body.email
|
email: req.body.email
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await container.createUserCommandHandler.execute(req.body);
|
const language = req.header('Accept-Language') || 'en';
|
||||||
|
|
||||||
logRequest('User created successfully', req, res, {
|
const result = await container.createUserCommandHandler.execute({ ...req.body, language });
|
||||||
username: result.username
|
|
||||||
|
logRequest('User created successfully', req, res, {
|
||||||
|
username: result.username
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(201).json(result);
|
res.status(201).json(result);
|
||||||
@@ -268,10 +270,11 @@ userRouter.post('/forgot-password',
|
|||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { email } = req.body;
|
const { email } = req.body;
|
||||||
|
const language = req.header('Accept-Language') || 'en';
|
||||||
|
|
||||||
logRequest('Forgot password endpoint accessed', req, res, { email });
|
logRequest('Forgot password endpoint accessed', req, res, { email });
|
||||||
|
|
||||||
const result = await container.requestPasswordResetCommandHandler.execute({ email });
|
const result = await container.requestPasswordResetCommandHandler.execute({ language, email });
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
logAuth('Password reset request successful', undefined, { email }, req, res);
|
logAuth('Password reset request successful', undefined, { email }, req, res);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export interface ShortDeckDto {
|
|||||||
type: number;
|
type: number;
|
||||||
playedNumber: number;
|
playedNumber: number;
|
||||||
ctype: number;
|
ctype: number;
|
||||||
cardsCount: number;
|
cardCount: number;
|
||||||
creator: string;
|
creator: string;
|
||||||
creationdate: Date;
|
creationdate: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export class DeckMapper {
|
|||||||
type: deck.type,
|
type: deck.type,
|
||||||
playedNumber: deck.playedNumber,
|
playedNumber: deck.playedNumber,
|
||||||
ctype: deck.ctype,
|
ctype: deck.ctype,
|
||||||
cardsCount: deck.cards.length,
|
cardCount: deck.cards.length,
|
||||||
creator: deck.user?.username || 'Unknown',
|
creator: deck.user?.username || 'Unknown',
|
||||||
creationdate: deck.creationdate
|
creationdate: deck.creationdate
|
||||||
};
|
};
|
||||||
@@ -36,7 +36,7 @@ export class DeckMapper {
|
|||||||
type: deck.type,
|
type: deck.type,
|
||||||
playedNumber: deck.playedNumber,
|
playedNumber: deck.playedNumber,
|
||||||
ctype: deck.ctype,
|
ctype: deck.ctype,
|
||||||
cardsCount: deck.cards.length,
|
cardCount: deck.cards.length,
|
||||||
creator: deck.user?.username || 'Unknown',
|
creator: deck.user?.username || 'Unknown',
|
||||||
creationdate: deck.creationdate
|
creationdate: deck.creationdate
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ export interface CreateUserCommand {
|
|||||||
code?: string;
|
code?: string;
|
||||||
orgid?: string;
|
orgid?: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
|
language: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class CreateUserCommandHandler {
|
|||||||
const created = await this.userRepo.create(user);
|
const created = await this.userRepo.create(user);
|
||||||
|
|
||||||
// Send verification email (non-blocking)
|
// Send verification email (non-blocking)
|
||||||
this.sendVerificationEmailAsync(created, verificationTokenData.token);
|
this.sendVerificationEmailAsync(cmd.language, created, verificationTokenData.token);
|
||||||
|
|
||||||
return UserMapper.toShortDto(created);
|
return UserMapper.toShortDto(created);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -67,16 +67,24 @@ export class CreateUserCommandHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sendVerificationEmailAsync(user: UserAggregate, token: string): Promise<void> {
|
private async sendVerificationEmailAsync(language: string, user: UserAggregate, token: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const baseUrl = process.env.FRONTEND_URL || 'http://localhost:5173';
|
const baseUrl = process.env.FRONTEND_URL || 'http://localhost:5173';
|
||||||
const verificationUrl = TokenService.generateVerificationUrl(baseUrl, token);
|
const verificationUrl = TokenService.generateVerificationUrl(baseUrl, token);
|
||||||
|
|
||||||
|
var lang: 'en' | 'hu' | 'de' = 'en';
|
||||||
|
if (language) {
|
||||||
|
lang = language.toLowerCase() as 'en' | 'hu' | 'de';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const emailSent = await this.emailService.sendVerificationEmail(
|
const emailSent = await this.emailService.sendVerificationEmail(
|
||||||
user.email,
|
user.email,
|
||||||
`${user.fname} ${user.lname}`,
|
`${user.fname} ${user.lname}`,
|
||||||
token,
|
token,
|
||||||
verificationUrl
|
verificationUrl,
|
||||||
|
lang
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!emailSent) {
|
if (!emailSent) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export interface RequestPasswordResetCommand {
|
export interface RequestPasswordResetCommand {
|
||||||
|
language: string;
|
||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -38,14 +38,21 @@ export class RequestPasswordResetCommandHandler {
|
|||||||
|
|
||||||
// Send password reset email
|
// Send password reset email
|
||||||
try {
|
try {
|
||||||
const baseUrl = process.env.APP_BASE_URL || 'http://localhost:3000';
|
const baseUrl = process.env.FRONTEND_URL || 'http://localhost:5173';
|
||||||
const resetUrl = TokenService.generatePasswordResetUrl(baseUrl, resetTokenData.token);
|
const resetUrl = TokenService.generatePasswordResetUrl(baseUrl, resetTokenData.token);
|
||||||
|
|
||||||
|
var lang: 'en' | 'hu' | 'de' = 'en';
|
||||||
|
if (cmd.language) {
|
||||||
|
lang = cmd.language.toLowerCase() as 'en' | 'hu' | 'de';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const emailSent = await this.emailService.sendPasswordResetEmail(
|
const emailSent = await this.emailService.sendPasswordResetEmail(
|
||||||
user.email,
|
user.email,
|
||||||
`${user.fname} ${user.lname}`,
|
`${user.fname} ${user.lname}`,
|
||||||
resetTokenData.token,
|
resetTokenData.token,
|
||||||
resetUrl
|
resetUrl,
|
||||||
|
lang
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!emailSent) {
|
if (!emailSent) {
|
||||||
|
|||||||
Reference in New Issue
Block a user