Akshar2325 commited on
Commit
fcc750f
Β·
1 Parent(s): 11cad63

fix(auth): improve robustness of user signup and email flow

Browse files

- 【auth】make welcome email sending non-blocking to prevent signup failures
- 【email】enhance error handling for email API to manage non-json responses

feat(email): add detailed logging for traceability
- log email payloads, raw API responses, and success/error states
- improves debugging capabilities for email delivery issues

refactor(db): remove unused clientId field from UserSession
- clean up the prisma schema by removing the obsolete `clientId` column

prisma/schema.prisma CHANGED
@@ -110,7 +110,6 @@ model UserSession {
110
  ipAddress String?
111
  userAgent String? @db.Text
112
  geoIpCountry String?
113
- clientId String?
114
  status SESSION_STATUS @default(CURRENT)
115
  loginAt DateTime? @db.Timestamp(3)
116
  logoutAt DateTime? @db.Timestamp(3)
 
110
  ipAddress String?
111
  userAgent String? @db.Text
112
  geoIpCountry String?
 
113
  status SESSION_STATUS @default(CURRENT)
114
  loginAt DateTime? @db.Timestamp(3)
115
  logoutAt DateTime? @db.Timestamp(3)
src/modules/user/auth/auth.service.ts CHANGED
@@ -341,12 +341,17 @@ export class UserAuthService {
341
  },
342
  });
343
 
344
- // Send welcome email
345
- await this.emailService.sendWelcomeEmail(
346
- email,
347
- user.firstName || 'User',
348
- user.lastName || '',
349
- );
 
 
 
 
 
350
 
351
  return {
352
  user: updatedUser,
 
341
  },
342
  });
343
 
344
+ // Send welcome email (don't block profile completion if email fails)
345
+ try {
346
+ await this.emailService.sendWelcomeEmail(
347
+ email,
348
+ user.firstName || 'User',
349
+ user.lastName || '',
350
+ );
351
+ } catch (emailError) {
352
+ // Log error but don't fail the request
353
+ console.error('Failed to send welcome email:', emailError);
354
+ }
355
 
356
  return {
357
  user: updatedUser,
src/shared/modules/email/email.service.ts CHANGED
@@ -7,7 +7,7 @@ export class EmailService {
7
  private readonly logger = new Logger(EmailService.name);
8
  private readonly config: EmailConfig;
9
 
10
- constructor(private configService: ConfigService) {
11
  this.config = new EmailConfig(configService);
12
  }
13
 
@@ -17,37 +17,55 @@ export class EmailService {
17
  firstName?: string,
18
  ): Promise<void> {
19
  try {
 
20
  const greeting = firstName ? `Hi ${firstName}` : 'Hello';
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  const response = await fetch('https://api.brevo.com/v3/smtp/email', {
23
  method: 'POST',
24
  headers: {
25
  'api-key': this.config.apiKey,
26
  'Content-Type': 'application/json',
27
  },
28
- body: JSON.stringify({
29
- sender: {
30
- email: this.config.otpEmail,
31
- name: 'StreamFlix',
32
- },
33
- to: [{ email, name: firstName || email }],
34
- templateId: this.config.otpTemplateId,
35
- params: {
36
- GREETING: greeting,
37
- OTP: otp,
38
- },
39
- }),
40
  });
41
 
 
 
 
42
  if (!response.ok) {
43
- const error = await response.json();
44
- this.logger.error('Failed to send OTP email', error);
 
 
 
 
 
45
  throw new Error('Failed to send OTP email');
46
  }
47
 
48
- this.logger.log(`OTP email sent to ${email}`);
49
  } catch (error) {
50
- this.logger.error('Error sending OTP email', error);
51
  throw error;
52
  }
53
  }
@@ -58,7 +76,27 @@ export class EmailService {
58
  lastName: string,
59
  ): Promise<void> {
60
  try {
61
- const fullName = `${firstName} ${lastName}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  const response = await fetch('https://api.brevo.com/v3/smtp/email', {
64
  method: 'POST',
@@ -66,28 +104,26 @@ export class EmailService {
66
  'api-key': this.config.apiKey,
67
  'Content-Type': 'application/json',
68
  },
69
- body: JSON.stringify({
70
- sender: {
71
- email: this.config.welcomeEmail,
72
- name: 'StreamFlix',
73
- },
74
- to: [{ email, name: fullName }],
75
- templateId: this.config.welcomeTemplateId,
76
- params: {
77
- FIRSTNAME: fullName,
78
- },
79
- }),
80
  });
81
 
 
 
 
82
  if (!response.ok) {
83
- const error = await response.json();
84
- this.logger.error('Failed to send welcome email', error);
 
 
 
 
 
85
  throw new Error('Failed to send welcome email');
86
  }
87
 
88
- this.logger.log(`Welcome email sent to ${email}`);
89
  } catch (error) {
90
- this.logger.error('Error sending welcome email', error);
91
  throw error;
92
  }
93
  }
 
7
  private readonly logger = new Logger(EmailService.name);
8
  private readonly config: EmailConfig;
9
 
10
+ constructor(configService: ConfigService) {
11
  this.config = new EmailConfig(configService);
12
  }
13
 
 
17
  firstName?: string,
18
  ): Promise<void> {
19
  try {
20
+ this.logger.log(`πŸ“§ Attempting to send OTP email to: ${email}`);
21
  const greeting = firstName ? `Hi ${firstName}` : 'Hello';
22
 
23
+ const payload = {
24
+ sender: {
25
+ email: this.config.otpEmail,
26
+ name: 'StreamFlix',
27
+ },
28
+ to: [{ email, name: firstName || email }],
29
+ templateId: this.config.otpTemplateId,
30
+ params: {
31
+ GREETING: greeting,
32
+ OTP: otp,
33
+ },
34
+ };
35
+
36
+ this.logger.log('πŸ“§ OTP Email payload:', {
37
+ sender: payload.sender,
38
+ to: payload.to,
39
+ templateId: payload.templateId,
40
+ params: payload.params,
41
+ });
42
+
43
  const response = await fetch('https://api.brevo.com/v3/smtp/email', {
44
  method: 'POST',
45
  headers: {
46
  'api-key': this.config.apiKey,
47
  'Content-Type': 'application/json',
48
  },
49
+ body: JSON.stringify(payload),
 
 
 
 
 
 
 
 
 
 
 
50
  });
51
 
52
+ const responseText = await response.text();
53
+ this.logger.log(`πŸ“§ Raw Response: ${responseText}`);
54
+
55
  if (!response.ok) {
56
+ let error;
57
+ try {
58
+ error = JSON.parse(responseText);
59
+ } catch {
60
+ error = responseText;
61
+ }
62
+ this.logger.error('πŸ“§ Failed to send OTP email:', error);
63
  throw new Error('Failed to send OTP email');
64
  }
65
 
66
+ this.logger.log(`πŸ“§ βœ… OTP email sent successfully to ${email}`);
67
  } catch (error) {
68
+ this.logger.error('πŸ“§ ❌ Error sending OTP email:', error);
69
  throw error;
70
  }
71
  }
 
76
  lastName: string,
77
  ): Promise<void> {
78
  try {
79
+ this.logger.log(`πŸ“§ Attempting to send welcome email to: ${email}`);
80
+ const fullName = `${firstName} ${lastName}`.trim();
81
+
82
+ const payload = {
83
+ sender: {
84
+ email: this.config.welcomeEmail,
85
+ name: 'StreamFlix',
86
+ },
87
+ to: [{ email, name: fullName || email }],
88
+ templateId: this.config.welcomeTemplateId,
89
+ params: {
90
+ FIRSTNAME: fullName || firstName || 'User',
91
+ },
92
+ };
93
+
94
+ this.logger.log('πŸ“§ Welcome Email payload:', {
95
+ sender: payload.sender,
96
+ to: payload.to,
97
+ templateId: payload.templateId,
98
+ params: payload.params,
99
+ });
100
 
101
  const response = await fetch('https://api.brevo.com/v3/smtp/email', {
102
  method: 'POST',
 
104
  'api-key': this.config.apiKey,
105
  'Content-Type': 'application/json',
106
  },
107
+ body: JSON.stringify(payload),
 
 
 
 
 
 
 
 
 
 
108
  });
109
 
110
+ const responseText = await response.text();
111
+ this.logger.log(`πŸ“§ Raw Response: ${responseText}`);
112
+
113
  if (!response.ok) {
114
+ let error;
115
+ try {
116
+ error = JSON.parse(responseText);
117
+ } catch {
118
+ error = responseText;
119
+ }
120
+ this.logger.error('πŸ“§ Failed to send welcome email:', error);
121
  throw new Error('Failed to send welcome email');
122
  }
123
 
124
+ this.logger.log(`πŸ“§ βœ… Welcome email sent successfully to ${email}`);
125
  } catch (error) {
126
+ this.logger.error('πŸ“§ ❌ Error sending welcome email:', error);
127
  throw error;
128
  }
129
  }