Skip to content

Conversation

@sujitaw
Copy link
Contributor

@sujitaw sujitaw commented Oct 13, 2025

What

  • updated the send verification email to be false by default

Summary by CodeRabbit

  • New Features
    • Streamlined sign-up: if an email is pre-verified, the app skips sending a verification email and marks it verified so users proceed directly to username setup.
    • Manual verification endpoint: admins can trigger manual email verification for a user (optional client selection).
  • Behavior Changes
    • Verification flow now respects an internal "pre-verified" flag to conditionally send emails.
  • Chores
    • Added a new "Verification Successful" success message.

@sujitaw sujitaw requested a review from shitrerohit October 13, 2025 13:01
@sujitaw sujitaw self-assigned this Oct 13, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 13, 2025

Walkthrough

Adds an optional isDefaultVerified flag across DTOs and interfaces, updates user creation flow to optionally skip sending verification emails and auto-verify when flagged, introduces a new admin-only manual verification endpoint, and adds a success response message.

Changes

Cohort / File(s) Summary
DTO: user email verification flag
apps/api-gateway/src/user/dto/create-user.dto.ts
Adds optional boolean field isDefaultVerified (default false), decorated with @ApiHideProperty(), @IsOptional(), and @IsBoolean().
Service: user creation / verification flow
apps/user/src/user.service.ts
Reads isDefaultVerified from payload; if true skips sending verification email and calls verifyEmail post-creation; otherwise sends verification email; adjusts downstream flow for username creation and persistence.
Interface: payload extension
libs/common/src/interfaces/user.interface.ts
Adds optional isDefaultVerified?: boolean to ISendVerificationEmail.
Controller: manual verification endpoint
apps/api-gateway/src/authz/authz.controller.ts
Adds POST /verify-mail-manually endpoint guarded by JWT and OrgRolesGuard, restricted to PLATFORM_ADMIN, accepts optional clientAlias, processes UserEmailVerificationDto and invokes verification mail/verification flow.
Service: force set default verified flag before send
apps/api-gateway/src/authz/authz.service.ts
In sendVerificationMail, sets userEmailVerification.isDefaultVerified = true before building payload and publishing to NATS.
Response messages
libs/common/src/response-messages/index.ts
Adds ResponseMessages.user.success.verificationSuccess = "Verification Successful".

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API as API Gateway
  participant Authz as AuthzController
  participant UserSvc as User Service
  participant Email as Email Service

  Client->>API: POST /create-user {email,..., isDefaultVerified?}
  API->>UserSvc: createUser(payload)

  alt isDefaultVerified == true
    UserSvc->>UserSvc: create user record
    UserSvc->>UserSvc: verifyEmail(user)
    UserSvc-->>Client: 201 Created (user, verified)
  else isDefaultVerified == false
    UserSvc->>Email: sendVerificationEmail(user)
    Email-->>UserSvc: queued/sent
    UserSvc-->>Client: 201 Created (user, pending verification)
  end

  Note right of Authz: Admin manual flow
  Client->>Authz: POST /verify-mail-manually (PLATFORM_ADMIN)
  Authz->>Authz: set clientAlias/default, set isDefaultVerified=true
  Authz->>UserSvc: sendVerificationMail(payload)
  UserSvc->>UserSvc: verifyEmail(user) / enqueue as appropriate
  UserSvc-->>Client: 201 Created / success message
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • authz.controller new endpoint: authz guards, role checks, error/response behavior.
    • user.service branching for isDefaultVerified: ensure no race conditions and consistent persistence state.
    • authz.service change that forces isDefaultVerified = true before NATS publish — confirm intended semantics.
    • DTO/interface compatibility and Swagger hiding behavior.

Suggested reviewers

  • shitrerohit

Poem

Thump, says the rabbit, code in my paw,
A tiny flag flips—no waiting for law.
If true, I stamp it, no mail in the night,
If false, off goes the message in flight.
Hop, hop—verified, and everything's right. 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a default parameter to control whether verification emails are sent by default.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/verify-email-modification

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sujitaw sujitaw changed the title feat:update send email verification API feat:update send email verification API default parameter for sending email Oct 13, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/user/src/user.service.ts (1)

137-137: Initialize the variable for clarity.

The variable sendVerificationMail is declared but not initialized. While the logic works due to short-circuit evaluation on line 169, explicit initialization improves readability and makes the intent clearer.

Apply this diff to initialize the variable:

-      let sendVerificationMail: boolean;
+      let sendVerificationMail: boolean = false;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69b8f27 and c61267f.

📒 Files selected for processing (3)
  • apps/api-gateway/src/user/dto/create-user.dto.ts (2 hunks)
  • apps/user/src/user.service.ts (2 hunks)
  • libs/common/src/interfaces/user.interface.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/user/src/user.service.ts (2)
apps/api-gateway/src/authz/authz.service.ts (1)
  • sendVerificationMail (44-47)
apps/user/src/user.controller.ts (1)
  • sendVerificationMail (58-60)
🔇 Additional comments (6)
libs/common/src/interfaces/user.interface.ts (1)

23-23: LGTM! Interface extension is backward compatible.

The optional isDefaultVerified field is properly typed and maintains backward compatibility with existing code.

apps/api-gateway/src/user/dto/create-user.dto.ts (2)

1-2: LGTM! Import additions are appropriate.

The new imports ApiHideProperty and IsBoolean are necessary for the isDefaultVerified field implementation.


42-45: LGTM! Field is properly decorated and validated.

The isDefaultVerified field is correctly configured with:

  • @ApiHideProperty() to hide it from Swagger documentation
  • @IsOptional() to make it optional
  • @IsBoolean() for type validation
  • Sensible default value of false
apps/user/src/user.service.ts (3)

116-116: LGTM! Properly extracts the new field.

The destructuring includes the new isDefaultVerified field from the userEmailVerification parameter.


153-164: Conditional email sending logic is correct.

The email verification is correctly skipped when isDefaultVerified is true, allowing for immediate verification in the subsequent flow.


169-169: No issues: sendEmailForVerification only returns true or throws, so sendVerificationMail || isDefaultVerified covers all edge cases.

@GHkrishna
Copy link
Contributor

As discussed in the CREDEBL call dated 15th October. The fix provided here is not the best way to enable registering users without email verification. As having the flag responsible for making the user verified by default can open path to attacks like spamming of users on CREDEBL.

@sujitaw mentioned he would be revisiting the requirements with @shitrerohit

Some discussed suggestions to implement user registration without email verification were as follows:

  • Having a familiar list of pre-approved users known to CREDEBL platform (via. admin access) - This might need having a separate API and table(not sure abut this, will need to check if we can add users to user table without them being registered on Keycloak. I believe we should be able to do this, as the user entry goes to the db without being added to keycloak for email verification)
  • Registering unverified users on specific keycloak client. This way the user list is managed by the client owner with their sub-application instead of handling it on CREDEBL. Dependency needs to be checked.

We should be flexible with updating the verification email logic as it is our own, not dependent on Keycloak

CC: @ajile-in @shitrerohit @RinkalBhojani @ankita-p17

@ajile-in ajile-in changed the title feat:update send email verification API default parameter for sending email feat: update send email verification API default parameter for sending email Oct 22, 2025
@ajile-in
Copy link
Member

ajile-in commented Oct 22, 2025

@sujitaw , @GHkrishna

We can think of:

  • Provide an ability to configure client's own SMTP to that there is no dependency on the default SMTP provider i.e. SendGrid
  • Provide a way for Platform Admin to manually approve user registrations especially in case where user base is in low numbers (10s) and also in a scenario where userid is used instead of email for user registration.

@GHkrishna
Copy link
Contributor

there is no dependency on the default SMTP provider

I believe the SMTP server would be a complete new feature regarding how someone sends email. For this specific issue I believe we can overlook that(even though a configurable email provider is what we want) for now. Let me know what you think. As this specific issue is mostly to avoid spamming of user accounts without verifying their email(no email required) with the suggested changes

  • Provide a way for Platform Admin to manually approve user registrations especially in case where user base is in low numbers (10s)

Yes this was one of the options we discussed, however, as we don't have an admin portal, we can start with an API to add these users for the admin (CREDEBL)

Also, I believe we'll also need to understand the use case for having this and if the base requirement is to add a large number of pre-approved users. This should help us get to the limit/number and if we want that in the first place.

also in a scenario where userid is used instead of email for user registration.

Yess right

@sonarqubecloud
Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c61267f and 46fc08b.

📒 Files selected for processing (3)
  • apps/api-gateway/src/authz/authz.controller.ts (2 hunks)
  • apps/api-gateway/src/authz/authz.service.ts (1 hunks)
  • libs/common/src/response-messages/index.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/api-gateway/src/authz/authz.controller.ts (4)
apps/api-gateway/src/authz/decorators/roles.decorator.ts (1)
  • Roles (6-6)
apps/api-gateway/src/user/dto/create-user.dto.ts (1)
  • UserEmailVerificationDto (7-46)
apps/api-gateway/src/user/utils/index.ts (1)
  • getDefaultClient (4-9)
libs/common/src/interfaces/response.interface.ts (1)
  • IResponseType (1-7)
🔇 Additional comments (1)
libs/common/src/response-messages/index.ts (1)

18-18: Message addition looks good.

The new success string slots in cleanly with the existing response message structure.

Comment on lines +45 to 47
userEmailVerification.isDefaultVerified = true;
const payload = { userEmailVerification };
return this.natsClient.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t auto-set isDefaultVerified for every send path.

sendVerificationMail now flips the flag to true for every caller, which makes the downstream user service treat every user as already verified and skip the email entirely—exactly the abuse scenario we’re trying to avoid. Please keep the default false (from the DTO) and only set it to true in the specific flows that really need auto-verification (e.g., a manual approval path) rather than here.

Apply this diff so the caller decides the flag:

-    userEmailVerification.isDefaultVerified = true;
+    if (userEmailVerification.isDefaultVerified === undefined) {
+      userEmailVerification.isDefaultVerified = false;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
userEmailVerification.isDefaultVerified = true;
const payload = { userEmailVerification };
return this.natsClient.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload);
if (userEmailVerification.isDefaultVerified === undefined) {
userEmailVerification.isDefaultVerified = false;
}
const payload = { userEmailVerification };
return this.natsClient.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload);
🤖 Prompt for AI Agents
In apps/api-gateway/src/authz/authz.service.ts around lines 45 to 47, the code
currently forces userEmailVerification.isDefaultVerified = true before sending
the message which causes downstream services to skip real verification; remove
that assignment so the DTO's default (false) is preserved and send the payload
as-is, and update any specific flows that legitimately require auto-verification
to set isDefaultVerified = true before calling this method instead of here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants