Skip to content

Conversation

@hib4
Copy link
Member

@hib4 hib4 commented May 23, 2025

PR Type

Enhancement


Description

  • Implement email verification with nodemailer templates

  • Send password reset emails via Mailtrap SMTP

  • Include emailVerified in sessionCheck response

  • Add verify-account controller and route


Changes walkthrough 📝

Relevant files
Enhancement
auth_controller.ts
Add email verification and reset email features                   

functions/src/controllers/auth_controller.ts

  • Configure nodemailer transporter with Mailtrap SMTP
  • Add HTML/text templates for reset and verification emails
  • Send verification email in register and verifyAccount endpoint
  • Enhance sessionCheck to include emailVerified status
  • +205/-154
    auth.ts
    Add verify-account API route                                                         

    functions/src/routes/auth.ts

  • Import and register verifyAccount route
  • Add POST /verify-account endpoint
  • +4/-0     
    Configuration changes
    auth_middleware.ts
    Update auth middleware exempt routes                                         

    functions/src/middlewares/auth_middleware.ts

    • Remove /auth/request-reset from exempt routes
    +0/-1     
    csrf_middleware.ts
    Adjust CSRF middleware exempt routes                                         

    functions/src/middlewares/csrf_middleware.ts

  • Remove /auth/request-reset from CSRF exempt routes
  • Add /auth/verify-account to exempt list
  • +1/-1     

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • @hib4 hib4 self-assigned this May 23, 2025
    @hib4 hib4 changed the title Feat/email verification feat: email verification May 23, 2025
    @github-actions
    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Missing ActionCodeSettings

    Using generatePasswordResetLink without specifying action code settings may produce incorrect or invalid reset URLs for your frontend.

    const link = await auth.generatePasswordResetLink(email);
    Performance Impact

    Calling auth.getUser on every sessionCheck may introduce latency; consider caching or embedding emailVerified in the session token.

    // Get user data to check email verification status
    const user = await auth.getUser(decodedSessionCookie.sub);
    
    res.status(200).json({
      status: 200,
      message: "Session is valid",
      data: {
        user: {
          email: decodedSessionCookie.email,
          displayName: decodedSessionCookie.name,
          emailVerified: user.emailVerified,
    Error Handling

    Ensure errors from auth.getUser and sendMail are handled separately to avoid exposing internal errors and to provide more granular responses.

    // Get user data to check email verification status
    const user = await auth.getUser(decodedSessionCookie.sub);
    
    res.status(200).json({
      status: 200,
      message: "Session is valid",
      data: {
        user: {
          email: decodedSessionCookie.email,
          displayName: decodedSessionCookie.name,
          emailVerified: user.emailVerified,

    @github-actions
    Copy link

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Add error handling for sendMail

    Wrap the sendMail call in a try-catch block to log failures and prevent unhandled
    promise rejections. This ensures the function handles SMTP errors gracefully without
    crashing the process.

    functions/src/controllers/auth_controller.ts [118]

    -await transporter.sendMail(mailOptions);
    +try {
    +  await transporter.sendMail(mailOptions);
    +} catch (error) {
    +  functions.logger.error("Failed to send email", error);
    +}
    Suggestion importance[1-10]: 7

    __

    Why: Wrapping transporter.sendMail in a try-catch improves resilience by preventing unhandled promise rejections and logging SMTP failures.

    Medium
    Handle errors in getUser call

    Wrap the getUser call in a try-catch to handle potential errors fetching the user
    and respond with a proper status. This prevents unhandled errors from crashing the
    session check.

    functions/src/controllers/auth_controller.ts [537]

    -const user = await auth.getUser(decodedSessionCookie.sub);
    +let user;
    +try {
    +  user = await auth.getUser(decodedSessionCookie.sub);
    +} catch (error) {
    +  functions.logger.error("Failed to fetch user for session check", error);
    +  res.status(500).json({ status: 500, error: "Internal server error" });
    +  return;
    +}
    Suggestion importance[1-10]: 7

    __

    Why: Catching errors from auth.getUser in sessionCheck prevents uncaught exceptions and returns a proper 500 response on failure.

    Medium
    General
    Include redirect settings in verification link

    Pass ActionCodeSettings with a frontend URL so the verification link redirects
    correctly after click. This ensures users land on the intended page
    post-verification.

    functions/src/controllers/auth_controller.ts [635]

    -const link = await auth.generateEmailVerificationLink(email);
    +const actionCodeSettings = {
    +  url: process.env.FRONTEND_URL
    +    ? `${process.env.FRONTEND_URL}/verify-account`
    +    : "https://portal.garudahacks.com/verify-account",
    +  handleCodeInApp: true,
    +};
    +const link = await auth.generateEmailVerificationLink(email, actionCodeSettings);
    Suggestion importance[1-10]: 6

    __

    Why: Adding ActionCodeSettings ensures the verification link redirects users to the correct frontend URL, enhancing UX without impacting core functionality.

    Low
    Add redirect settings to reset link

    Reintroduce ActionCodeSettings when generating the reset link so it points to your
    frontend reset page. Users will then be routed correctly after clicking the email
    link.

    functions/src/controllers/auth_controller.ts [581]

    -const link = await auth.generatePasswordResetLink(email);
    +const actionCodeSettings = {
    +  url: process.env.FRONTEND_URL
    +    ? `${process.env.FRONTEND_URL}/reset-password`
    +    : "https://portal.garudahacks.com/reset-password",
    +  handleCodeInApp: true,
    +};
    +const link = await auth.generatePasswordResetLink(email, actionCodeSettings);
    Suggestion importance[1-10]: 6

    __

    Why: Reintroducing ActionCodeSettings for generatePasswordResetLink directs users to the frontend reset page, improving navigation but not affecting core logic.

    Low

    @hib4 hib4 merged commit 662411f into dev May 23, 2025
    1 check passed
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    2 participants