keyshade-xyz / keyshade

Realtime secret and configuration management tool, with the best in class security and seamless integration support
https://keyshade.xyz
Mozilla Public License 2.0
196 stars 96 forks source link

feat(api): Add resend otp implementation #445

Open Prakhargarg-2010196 opened 2 weeks ago

Prakhargarg-2010196 commented 2 weeks ago

User description

Description

Base implemented by using present functions to resend otp to the user. Tried using the already present sendotp function. But as the errors returned are different in the resend otp took few other functions and called those instead of calling sendOtp().

Fixes #326 (pending)

Dependencies

Mention any dependencies/packages used

Future Improvements

Developer's checklist

If changes are made in the code:

Documentation Update


PR Type

enhancement, dependencies


Description


Changes walkthrough πŸ“

Relevant files
Enhancement
app.module.ts
Add throttling configuration and guard to AppModule           

apps/api/src/app/app.module.ts
  • Added ThrottlerModule configuration for rate limiting.
  • Introduced ThrottlerGuard as a global guard.
  • +16/-2   
    auth.controller.ts
    Implement resend OTP endpoint with throttling                       

    apps/api/src/auth/controller/auth.controller.ts
  • Added resendOtp endpoint with throttling.
  • Applied ThrottlerGuard to resendOtp endpoint.
  • +12/-1   
    auth.service.ts
    Add resend OTP functionality to AuthService                           

    apps/api/src/auth/service/auth.service.ts
  • Implemented resendOtp method in AuthService.
  • Added error logging for OTP resend failures.
  • +29/-5   
    Configuration changes
    .env.example
    Add throttling configuration variables to .env.example     

    .env.example - Added `THROTTLE_TTL` and `THROTTLE_LIMIT` environment variables.
    +6/-1     
    Dependencies
    package.json
    Update package.json with throttler dependency                       

    apps/api/package.json
  • Added @nestjs/throttler as a dependency.
  • Reordered reflect-metadata in devDependencies.
  • +2/-1     
    pnpm-lock.yaml
    Update pnpm-lock.yaml for new dependencies                             

    pnpm-lock.yaml
  • Updated lock file to include @nestjs/throttler.
  • Reflected changes in dependencies and versions.
  • +237/-83

    πŸ’‘ PR-Agent usage: Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    codiumai-pr-agent-free[bot] commented 2 weeks ago

    PR Reviewer Guide πŸ”

    ⏱️ Estimated effort to review: 3 πŸ”΅πŸ”΅πŸ”΅βšͺβšͺ
    πŸ§ͺ No relevant tests
    πŸ”’ No security concerns identified
    ⚑ Key issues to review

    Configuration Concern
    The ThrottlerModule is configured with environment variables, but there's no validation or default values set. This could lead to runtime errors if the variables are not properly set. Error Handling
    The `resendOtp` method catches all errors and only logs them. This could hide important errors and make debugging difficult. Rate Limiting Configuration
    The `resendOtp` endpoint has a hard-coded rate limit that might not be flexible for different environments or use cases.
    codiumai-pr-agent-free[bot] commented 2 weeks ago

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Input validation
    Add input validation for the email parameter in the resendOtp method ___ **Consider adding input validation for the email parameter in the resendOtp method.
    This can help prevent unnecessary processing and improve security by ensuring only
    valid email addresses are processed.** [apps/api/src/auth/controller/auth.controller.ts [49-58]](https://github.com/keyshade-xyz/keyshade/pull/445/files#diff-ca5c58065b10468a07314a5a9224336ac37df84a4a0e769babb2ed040cf8c82aR49-R58) ```diff @Public() @Post('resend-otp/:email') @UseGuards(ThrottlerGuard) @Throttle({ default: { ttl: seconds(1), limit: 2 } }) async resendOtp( - @Param('email') + @Param('email', new ParseEmailPipe()) email: string ): Promise { return await this.authService.resendOtp(email) } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 9 Why: Adding input validation for the email parameter enhances security and prevents unnecessary processing of invalid data, which is crucial for maintaining the integrity of the application.
    9
    Error handling
    Implement more specific error handling in the catch block ___ **Consider handling specific error types separately in the catch block of the
    resendOtp method. This would allow for more precise error handling and logging,
    potentially improving the ability to debug and respond to different types of errors.** [apps/api/src/auth/service/auth.service.ts [68-74]](https://github.com/keyshade-xyz/keyshade/pull/445/files#diff-b133cdd3d1772bc73698061218512fd024ce1ed7cd9eaeb27858e6acb444b90bR68-R74) ```diff try { const user = await getUserByEmailOrId(email, this.prisma) const otp = await generateOtp(email, user.id, this.prisma) await this.mailService.sendOtp(email, otp.code) } catch (e) { - this.logger.error(`Resending OTP failed ${e}`) + if (e instanceof PrismaClientKnownRequestError) { + this.logger.error(`Database error while resending OTP: ${e.message}`) + } else if (e instanceof MailServiceError) { + this.logger.error(`Mail service error while resending OTP: ${e.message}`) + } else { + this.logger.error(`Unexpected error while resending OTP: ${e}`) + } + throw new InternalServerErrorException('Failed to resend OTP') } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: This suggestion improves error handling by distinguishing between different error types, which enhances debugging and provides more informative logging. It also introduces an InternalServerErrorException, which is a good practice for handling unexpected errors.
    8
    Enhancement
    βœ… Provide default values for throttling configuration ___ **Add default values for the THROTTLE_TTL and THROTTLE_LIMIT variables to provide
    guidance for users setting up the environment.** [.env.example [54-56]](https://github.com/keyshade-xyz/keyshade/pull/445/files#diff-a3046da0d15a27e89f2afe639b25748a7ad4d9290af3e7b1b6c1a5533c8f0a8cR54-R56) ```diff # Enter time in secs -THROTTLE_TTL= -THROTTLE_LIMIT= +THROTTLE_TTL=60 +THROTTLE_LIMIT=10 ``` `[Suggestion has been applied]`
    Suggestion importance[1-10]: 8 Why: Adding default values for environment variables can guide users in setting up their environment correctly and ensure that the application has sensible defaults, improving usability and reducing setup errors.
    8
    Code cleanup
    βœ… Remove TODO comments and rely on controller-level throttling ___ **Remove the TODO comments and implement the actual throttling logic in the resendOtp
    method. The throttling should be handled at the controller level using the @Throttle
    decorator, as shown in the auth.controller.ts file.** [apps/api/src/auth/service/auth.service.ts [64-67]](https://github.com/keyshade-xyz/keyshade/pull/445/files#diff-b133cdd3d1772bc73698061218512fd024ce1ed7cd9eaeb27858e6acb444b90bR64-R67) ```diff -/** - *TODO Resend the otp based on another function send otp but - *TODO with a throttler to rate limit the api - */ +// Throttling is handled at the controller level ``` `[Suggestion has been applied]`
    Suggestion importance[1-10]: 7 Why: Removing the TODO comments clarifies that throttling is already handled at the controller level, which improves code readability and reduces confusion about where throttling logic should be implemented.
    7
    Best practice
    Specify exact version for "@nestjs/throttler" package ___ **Consider adding a specific version for the "@nestjs/throttler" package instead of
    using the caret (^) to ensure consistency across environments.** [apps/api/package.json [35]](https://github.com/keyshade-xyz/keyshade/pull/445/files#diff-2c40985d6d91eed8ae85ec1c8e754a85984ee32e156a600d2b7a467423d7e338R35-R35) ```diff -"@nestjs/throttler": "^6.2.1", +"@nestjs/throttler": "6.2.1", ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: Specifying an exact version can help ensure consistency across different environments, reducing the risk of unexpected behavior due to version changes. However, it may limit flexibility in receiving minor updates and patches.
    7
    Configuration management
    βœ… Use type-safe configuration retrieval for throttle settings ___ **Consider using environment variables or a configuration file for the throttle limit
    and TTL values instead of hardcoding them. This would make the application more
    flexible and easier to configure in different environments.** [apps/api/src/app/app.module.ts [41-50]](https://github.com/keyshade-xyz/keyshade/pull/445/files#diff-edcd2071cfcb26ce4d2c9195a095fd4a86461ee5a66ceceb1d441eaaef6efec9R41-R50) ```diff ThrottlerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => [ { - ttl: seconds(config.get('THROTTLE_TTL')), - limit: config.get('THROTTLE_LIMIT') + ttl: seconds(config.get('THROTTLE_TTL')), + limit: config.get('THROTTLE_LIMIT') } ] }), ``` `[Suggestion has been applied]`
    Suggestion importance[1-10]: 6 Why: Using type-safe configuration retrieval is a minor improvement that enhances code safety and maintainability, ensuring that the configuration values are of the expected type. However, the impact is relatively small compared to other suggestions.
    6

    πŸ’‘ Need additional feedback ? start a PR chat