-
Notifications
You must be signed in to change notification settings - Fork 0
Add Emailing #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Emailing #7
Conversation
…rification templates - Added email package with templates for password reset and email verification. - Integrated email sending functionality in the auth module for password reset and verification emails. - Updated environment configuration to include email-related keys. - Created new Forgot Password and Reset Password pages in the web app with corresponding forms and validation. - Enhanced existing signup and login forms to include password confirmation validation.
… email functionality integration
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe changes add new email-related environment variables and update various authentication components. New forgot password and reset password components are introduced with form validation via react-hook-form and zod. The UI components are adjusted to streamline button properties and layout structures. The authentication client now exposes additional password management methods. A new email package is established offering templates for contact, password reset, and verification emails, while the auth server’s configuration gains email functionality improvements. Minor adjustments to the signup process and UI components (e.g., password input disable prop) complete the update. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant F as ForgotPassword Component
participant A as AuthClient (forgetPassword)
U->>F: Enter email & submit form
F->>A: Call forgetPassword(email, redirectURL)
alt Success
A-->>F: Return success
F->>U: Display success message
else Error
A-->>F: Return error
F->>U: Display error alert
end
sequenceDiagram
participant U as User
participant R as ResetPassword Component
participant A as AuthClient (resetPassword)
U->>R: Submit new password & confirm password
R->>A: Call resetPassword(token, newPassword)
alt Success
A-->>R: Return success
R->>U: Show success message and redirect to login
else Error
A-->>R: Return error
R->>U: Display error message
end
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🔇 Additional comments (2)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (4)
apps/web/.env.example (1)
6-7: Good addition of email environment variablesThe environment variables for Resend have been properly added. Consider adding brief comments to explain the expected format for these variables (especially that RESEND_FROM should be a valid email address).
# Server BETTER_AUTH_SECRET="" DATABASE_URL="" GOOGLE_CLIENT_ID="" GOOGLE_CLIENT_SECRET="" -RESEND_FROM="" -RESEND_TOKEN="" +# Email address that will appear as the sender (e.g., "no-reply@yourdomain.com") +RESEND_FROM="" +# API token from Resend dashboard +RESEND_TOKEN="" BETTERSTACK_API_KEY=""packages/auth/client.ts (1)
5-12: Enhanced authentication API with password managementGood addition of
forgetPasswordandresetPasswordfunctions to support the new password management features.Minor naming suggestion: Consider renaming
forgetPasswordtoforgotPasswordas it's more commonly used in authentication flows and would improve developer experience.apps/web/app/(unauthenticated)/reset-password/reset-password.tsx (1)
23-42: Well-implemented token validation and redirection.The component correctly validates the presence of a token and redirects users when no token is found. However, users might be confused by the sudden redirection.
Consider adding a brief explanatory message before redirecting, or using a toast notification to inform users why they're being redirected.
// Redirect if no token is present if (!token) { + // Show a message briefly before redirecting + setGeneralError('No reset token found. Redirecting to login page...'); + setTimeout(() => { router.push('/login') + }, 1500); return null }packages/email/templates/password-reset.tsx (1)
95-100: Fix typo in example email address.There's a typo in the example email address used in the demo component.
- email="exmaple@blackhead.com" + email="example@blackhead.com"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (27)
apps/web/.env.example(1 hunks)apps/web/app/(unauthenticated)/components/header.tsx(1 hunks)apps/web/app/(unauthenticated)/forgot-password/forgot-password.tsx(1 hunks)apps/web/app/(unauthenticated)/forgot-password/page.tsx(1 hunks)apps/web/app/(unauthenticated)/forgot-password/schema.ts(1 hunks)apps/web/app/(unauthenticated)/layout.tsx(1 hunks)apps/web/app/(unauthenticated)/login/email/login-email.tsx(1 hunks)apps/web/app/(unauthenticated)/login/login.tsx(1 hunks)apps/web/app/(unauthenticated)/reset-password/page.tsx(1 hunks)apps/web/app/(unauthenticated)/reset-password/reset-password.tsx(1 hunks)apps/web/app/(unauthenticated)/reset-password/schema.ts(1 hunks)apps/web/app/(unauthenticated)/signup/schema.ts(1 hunks)apps/web/app/(unauthenticated)/signup/signup.tsx(3 hunks)apps/web/lib/env.ts(1 hunks)apps/web/package.json(1 hunks)packages/auth/client.ts(1 hunks)packages/auth/keys.ts(1 hunks)packages/auth/package.json(1 hunks)packages/auth/server.ts(2 hunks)packages/email/index.ts(1 hunks)packages/email/keys.ts(1 hunks)packages/email/package.json(1 hunks)packages/email/templates/contact.tsx(1 hunks)packages/email/templates/password-reset.tsx(1 hunks)packages/email/templates/verification.tsx(1 hunks)packages/email/tsconfig.json(1 hunks)packages/ui/components/password-input.tsx(3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (16)
apps/web/app/(unauthenticated)/forgot-password/page.tsx (1)
apps/web/app/(unauthenticated)/forgot-password/forgot-password.tsx (1)
ForgotPassword(22-102)
packages/email/keys.ts (1)
packages/auth/keys.ts (1)
keys(5-29)
apps/web/app/(unauthenticated)/reset-password/schema.ts (2)
apps/web/app/(unauthenticated)/signup/schema.ts (1)
formSchema(6-19)packages/ui/lib/password-validation.ts (1)
passwordSchema(14-22)
apps/web/app/(unauthenticated)/reset-password/page.tsx (1)
apps/web/app/(unauthenticated)/reset-password/reset-password.tsx (1)
ResetPassword(23-136)
apps/web/app/(unauthenticated)/forgot-password/schema.ts (2)
apps/web/app/(unauthenticated)/reset-password/schema.ts (1)
formSchema(4-14)apps/web/app/(unauthenticated)/signup/schema.ts (1)
formSchema(6-19)
packages/auth/keys.ts (1)
packages/email/keys.ts (1)
keys(4-14)
apps/web/lib/env.ts (4)
apps/api/lib/env.ts (1)
env(7-12)packages/analytics/posthog/server.ts (1)
analytics(6-12)packages/auth/server.ts (1)
auth(10-73)packages/database/index.ts (1)
database(11-11)
apps/web/app/(unauthenticated)/signup/signup.tsx (2)
packages/ui/components/ui/form.tsx (5)
FormField(166-166)FormItem(161-161)FormLabel(162-162)FormControl(163-163)FormMessage(165-165)packages/ui/components/password-input.tsx (1)
PasswordInput(17-194)
apps/web/app/(unauthenticated)/login/email/login-email.tsx (5)
packages/ui/components/ui/alert.tsx (1)
Alert(66-66)packages/ui/components/ui/form.tsx (6)
Form(160-160)FormField(166-166)FormItem(161-161)FormLabel(162-162)FormControl(163-163)FormMessage(165-165)packages/ui/components/ui/input.tsx (1)
Input(21-21)packages/ui/components/password-input.tsx (1)
PasswordInput(17-194)packages/ui/components/ui/button.tsx (1)
Button(59-59)
apps/web/app/(unauthenticated)/signup/schema.ts (2)
apps/web/app/(unauthenticated)/reset-password/schema.ts (1)
formSchema(4-14)packages/ui/lib/password-validation.ts (1)
passwordSchema(14-22)
apps/web/app/(unauthenticated)/reset-password/reset-password.tsx (4)
apps/web/app/(unauthenticated)/reset-password/schema.ts (1)
formSchema(4-14)packages/ui/components/ui/alert.tsx (1)
Alert(66-66)packages/ui/components/ui/form.tsx (6)
Form(160-160)FormField(166-166)FormItem(161-161)FormLabel(162-162)FormControl(163-163)FormMessage(165-165)packages/ui/components/ui/button.tsx (1)
Button(59-59)
apps/web/app/(unauthenticated)/forgot-password/forgot-password.tsx (5)
apps/web/app/(unauthenticated)/forgot-password/schema.ts (1)
formSchema(3-5)packages/ui/components/ui/alert.tsx (1)
Alert(66-66)packages/ui/components/ui/form.tsx (5)
Form(160-160)FormItem(161-161)FormLabel(162-162)FormControl(163-163)FormMessage(165-165)packages/ui/components/ui/input.tsx (1)
Input(21-21)packages/ui/components/ui/button.tsx (1)
Button(59-59)
packages/email/templates/password-reset.tsx (2)
apps/web/components/section.tsx (1)
Section(19-37)packages/ui/components/ui/button.tsx (1)
Button(59-59)
packages/email/templates/verification.tsx (2)
apps/web/components/section.tsx (1)
Section(19-37)packages/ui/components/ui/button.tsx (1)
Button(59-59)
packages/email/templates/contact.tsx (1)
apps/web/components/section.tsx (1)
Section(19-37)
packages/auth/server.ts (4)
packages/email/index.ts (1)
resend(4-4)packages/email/keys.ts (1)
keys(4-14)packages/email/templates/password-reset.tsx (1)
PasswordResetEmail(20-93)packages/email/templates/verification.tsx (1)
VerificationEmail(20-89)
🔇 Additional comments (57)
packages/auth/package.json (1)
18-18: New dependency added for email functionalityAdding
@repo/emailas a dependency aligns with the PR's objective to implement email services for password reset and verification. This is an appropriate change as the auth package will now use email functionality.packages/email/keys.ts (1)
1-14: Well-structured environment validation for Resend email serviceThe environment variables required for the Resend email service are properly defined and validated:
RESEND_FROMis validated as a non-empty email stringRESEND_TOKENis validated as a non-empty string starting with 're_' (Resend's token format)This implementation is consistent with the pattern used in other parts of the application, like
packages/auth/keys.ts.packages/email/tsconfig.json (1)
1-8: Standard TypeScript configuration for the new email packageThis TypeScript configuration appropriately extends the base configuration and sets up the compiler options needed for the new email package. The includes and excludes are properly configured to handle all TypeScript files in the directory.
apps/web/lib/env.ts (2)
4-4: Import added for email environment keysThe new import for email keys from
@repo/email/keysis correctly added to support the email functionality being implemented in this PR.
9-9: Extension order changed while adding email environmentWhile adding the email environment extension is necessary, note that the ordering of extensions has been changed from the original. The new order places
analytics()beforeauth()(previously it was after), withemail()added at the end.This reordering could potentially affect how environment variables are merged or overridden if there are any conflicts between these different configurations.
Please verify that no environment variables in these different configurations would conflict in a way that the new ordering would change the expected behavior.
packages/email/index.ts (1)
1-4: Clean implementation of the email clientGood job setting up the Resend client with proper separation of concerns. The implementation correctly retrieves the token from a separate configuration module and exports the initialized client for use throughout the application.
apps/web/package.json (1)
17-17: Correctly added email package dependencyThe addition of the
@repo/emailpackage dependency is appropriate for implementing the email functionality in the web application.apps/web/app/(unauthenticated)/forgot-password/schema.ts (1)
1-5: Well-defined schema for forgot passwordThe schema correctly validates the email field using Zod, following the same pattern as other form schemas in the application. The implementation is appropriately minimal for the forgot password functionality, requiring only a valid email address.
apps/web/app/(unauthenticated)/forgot-password/page.tsx (1)
1-9: Clean implementation of the ForgotPassword page with dynamic import.The implementation follows Next.js best practices by using dynamic imports for code splitting, which improves initial page load performance by only loading the component when needed. The structure is clean and follows a proper separation of concerns by keeping the page component separate from the implementation.
apps/web/app/(unauthenticated)/reset-password/page.tsx (1)
1-9: Well-structured ResetPassword page with consistent pattern.The implementation maintains consistency with the ForgotPassword page pattern, using dynamic imports correctly for code splitting. This approach ensures better performance and maintainability across the authentication-related pages.
apps/web/app/(unauthenticated)/layout.tsx (1)
25-27: Good improvement to layout structure with semantic HTML.Adding the
<main>element improves semantic HTML structure while providing consistent layout styling for all unauthenticated pages. The flexbox styling ensures that content properly fills the available space and maintains consistent vertical alignment across different authentication-related pages.apps/web/app/(unauthenticated)/login/login.tsx (1)
10-10: Good refactoring of layout responsibilities.The className changes appropriately remove positioning and height constraints that are now handled by the parent layout component. This refactoring creates better separation of concerns where the layout component manages the overall container constraints while this component focuses on its specific layout needs.
packages/ui/components/password-input.tsx (4)
13-14: Good addition of thedisabledprop to PasswordInputPropsAdding this prop enhances the component's flexibility and makes it more consistent with standard form input behavior.
18-19: Appropriate default value for the disabled propSetting
disabled = falseas default ensures backward compatibility with existing usage of the component.
98-99: Correctly applying disabled state to the Input componentThis ensures the input field respects the disabled state passed from parent components.
107-108: Well-implemented disabled state for the visibility toggle buttonGood implementation that ensures both the input field and its associated visibility toggle button are disabled together, maintaining proper accessibility and user experience.
apps/web/app/(unauthenticated)/reset-password/schema.ts (3)
1-3: Good imports for form schema validationProperly importing the reusable
passwordSchemapromotes code reuse across the application.
4-10: Well-structured password reset form schemaThe schema properly validates both the password and confirmation fields. Using the existing
passwordSchemaensures consistent password requirements across the application.
11-14: Excellent password matching validation with targeted errorThe refinement correctly ensures passwords match and provides a clear error message. The
path: ['confirmPassword']properly targets the error to the confirmPassword field, which improves user experience by showing the error in the right location.packages/email/package.json (5)
1-5: Good package configuration for the new email moduleThe package is properly named following the repo's naming convention, and marked as private to prevent accidental publishing.
5-9: Well-organized exports structureThe exports configuration clearly defines the module's public API, making it easy for other packages to import and use the email functionality.
10-15: Comprehensive scripts for email developmentThe scripts provide all necessary commands for development, building, and type checking of the email templates.
24-30: Well-configured development dependenciesThe devDependencies include all necessary tools for TypeScript development and email template creation.
16-23:Details
✅ Verification successful
Verify React version compatibility
The package uses React 19.1.0, which is a very recent version. Ensure this is compatible with other packages in the monorepo.
🏁 Script executed:
#!/bin/bash # Check React versions across the monorepo echo "Checking React versions across packages:" find . -name "package.json" -not -path "*/node_modules/*" -exec grep -l "\"react\":" {} \; | xargs grep -A 1 "\"react\":"Length of output: 896
React Version Compatibility Confirmed
After verifying the React versions across the monorepo, all packages—including
packages/email/package.json—consistently use React^19.1.0. No further action is required.apps/web/app/(unauthenticated)/signup/schema.ts (2)
6-15: Enhanced signup schema with password confirmationThe updated schema now properly validates password confirmation, improving user security and reducing user errors during signup.
16-19: Consistent implementation of password matching validationThis refinement uses the same pattern as in the reset-password schema, ensuring consistent behavior across similar forms. The targeted error path improves the user experience by showing errors in the right location.
apps/web/app/(unauthenticated)/signup/signup.tsx (3)
34-35: Password confirmation field addedGood addition of the
confirmPasswordfield to the form's default values. This follows security best practices by requiring users to enter their password twice to prevent typos.
63-63: UI layout adjustment looks goodThe flex container's class adjustments create a more consistent layout that centers the signup form appropriately.
131-143:Details
✅ Verification successful
Password confirmation field implementation is complete
The implementation of the confirmPassword field follows the same pattern as other form fields, maintaining consistency in the UI. The PasswordInput component is appropriately reused without the strength indicator for the confirmation field.
However, verify that the schema validation (not shown here) properly ensures the confirmation matches the original password:
🏁 Script executed:
#!/bin/bash # Check if the schema properly validates password matching grep -A 10 "confirmPassword" apps/web/app/\(unauthenticated\)/signup/schema.tsLength of output: 310
Schema validation and field implementation verified
- The confirmPassword field in
apps/web/app/(unauthenticated)/signup/signup.tsxis implemented consistently with other form fields.- The validation schema in
apps/web/app/(unauthenticated)/signup/schema.tscorrectly enforces matching passwords using a.refinecheck with the appropriate error message.No further changes are required.
packages/auth/keys.ts (1)
1-1:Details
✅ Verification successful
Email configuration integration
The change from core keys to email keys properly integrates the email functionality into the authentication system. This enables password reset and verification emails.
The imported email configuration correctly validates essential fields:
- RESEND_FROM: Validates it's a proper email
- RESEND_TOKEN: Validates the token format starts with 're_'
Verify that these environment variables are properly documented in the project's README or .env.example files:
Also applies to: 7-7
🏁 Script executed:
#!/bin/bash # Check if the email environment variables are documented grep -r "RESEND_" --include="*.md" --include="*.env*" .Length of output: 134
Email configuration integration approved
The change from core keys to email keys successfully integrates the email functionality (supporting password reset and verification emails) into the authentication system. The validations for both
RESEND_FROM(ensuring it's a valid email) andRESEND_TOKEN(ensuring it starts with're_') are correctly implemented. Additionally, the environment variables are properly documented in the project, as confirmed by their presence inapps/web/.env.example.apps/web/app/(unauthenticated)/components/header.tsx (1)
48-48: Button size standardizationRemoving the
size="sm"prop simplifies the button implementation and allows it to use the default sizing from the design system, improving consistency across the UI.apps/web/app/(unauthenticated)/login/email/login-email.tsx (2)
58-132: Layout restructuring improves component organization.The refactored layout with React fragments improves the component structure by eliminating unnecessary wrapper divs and organizing the content into logical sections.
123-130: Good addition of "Forgot password?" link.Adding the forgot password link improves user experience by providing a direct path for users who need to reset their password.
apps/web/app/(unauthenticated)/reset-password/reset-password.tsx (4)
44-68: Comprehensive error handling in form submission.The implementation properly handles potential errors during password reset, providing clear feedback to users in various scenarios.
82-87: Well-designed success feedback with redirection.Good implementation of success feedback with automatic redirection. The use of the PartyPopper icon is a nice touch for positive reinforcement.
97-102: Password strength indicator enhances security awareness.Using the PasswordInput with showStrengthIndicator provides valuable feedback to users about password security, encouraging stronger passwords.
125-127: Comprehensive button disabled state.The button is properly disabled based on form submission state, validity, and success status, preventing multiple submissions and improving user experience.
packages/email/templates/contact.tsx (3)
13-17: Well-typed props interface.The ContactTemplateProps type clearly defines the required properties with appropriate types, making the component API clear and type-safe.
19-46: Clean and accessible email template structure.The email template uses proper semantic structure with preview text and clear content organization. The template renders well for contact emails.
However, consider adding alt text for better accessibility in email clients that may not fully render the styling:
<Text className="mt-0 mb-4 font-semibold text-2xl text-zinc-950"> - New email from {name} + New email from {name} {/* #contact-email-heading */} </Text>
48-56: Helpful example component.Including an example component with sample data makes it easier for developers to understand how to use the template and visualize the output.
apps/web/app/(unauthenticated)/forgot-password/forgot-password.tsx (4)
32-51: Comprehensive error handling in forgot password flow.The implementation correctly handles API errors and connection issues, providing clear feedback to users. The use of the redirectTo parameter ensures users will be properly directed to the reset password page.
65-70: Clear success messaging.The success message clearly informs users to check their email, and the use of the PartyPopper icon adds a positive visual cue.
80-80: Appropriate form field disabling.Good practice to disable the email input when the form has been successfully submitted, preventing users from making additional submissions.
86-96: Well-implemented submit button with proper state management.The button correctly displays different text based on the submission state and is properly disabled when appropriate.
packages/email/templates/verification.tsx (6)
1-13: Good use of React Email components.The imports are properly structured and include all necessary components for building the email template.
15-18: LGTM! Well-defined interface.The interface for
VerificationEmailPropsis appropriately defined with readonly properties to ensure immutability.
20-22: Good implementation of dynamic year calculation.The current year is correctly calculated for use in the copyright notice.
23-49: Well-structured email template with clear user instructions.The template has a logical flow with informative heading, clear instructions, and both button and URL options for verification.
50-55: Good security practice including expiration information.Including the link expiration time and advice for unrequested emails is a security best practice.
91-96: Good example implementation for testing and documentation.The
ExampleVerificationEmailcomponent provides a clear demonstration of how to use theVerificationEmailcomponent.packages/email/templates/password-reset.tsx (5)
1-13: Good use of React Email components.The imports are properly structured and include all necessary components for building the email template.
15-18: LGTM! Well-defined interface.The interface for
PasswordResetEmailPropsis appropriately defined with readonly properties to ensure immutability.
20-22: Good implementation of dynamic year calculation.The current year is correctly calculated for use in the copyright notice.
23-50: Well-structured password reset email with clear instructions.The template has a logical flow with informative heading, clear instructions, and both button and URL options for password reset.
51-58: Excellent security practices in the email template.The template includes important security information: link expiration time, advice for unrequested emails, and a warning against forwarding the email.
packages/auth/server.ts (2)
2-4: Good imports for email functionality.The necessary imports for email functionality have been correctly added, including the Resend client and email templates.
16-17: Verify sign-up configuration for email verification flow.The code includes
disableSignUp: truewith a comment "Disable sign up for now", which might conflict with the new email verification flow. If sign-up is disabled, users won't be able to register and receive verification emails. Ensure this is the intended behavior or consider enabling sign-up to utilize the new verification flow.
| form.formState.isSubmitting || !form.formState.isValid | ||
| } | ||
| > | ||
| {form.formState.isSubmitting ? 'Signing up...' : 'Continue'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect loading text for login form.
The button displays "Signing up..." during submission, but this is a login form, not a signup form.
- {form.formState.isSubmitting ? 'Signing up...' : 'Continue'}
+ {form.formState.isSubmitting ? 'Logging in...' : 'Continue'}📝 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.
| {form.formState.isSubmitting ? 'Signing up...' : 'Continue'} | |
| {form.formState.isSubmitting ? 'Logging in...' : 'Continue'} |
| <a | ||
| href="https://yourapp.com/unsubscribe" | ||
| className="text-zinc-500 underline" | ||
| > | ||
| Unsubscribe | ||
| </a>{' '} | ||
| ·{' '} | ||
| <a | ||
| href="https://yourapp.com/terms" | ||
| className="text-zinc-500 underline" | ||
| > | ||
| Terms | ||
| </a>{' '} | ||
| ·{' '} | ||
| <a | ||
| href="https://yourapp.com/privacy" | ||
| className="text-zinc-500 underline" | ||
| > | ||
| Privacy | ||
| </a> | ||
| </Text> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Update placeholder URLs with actual application URLs.
The unsubscribe, terms, and privacy links currently point to placeholder URLs (yourapp.com), which should be updated to the actual application URLs before deployment.
- href="https://yourapp.com/unsubscribe"
+ href="https://blackhead-web.vercel.app/unsubscribe"
- href="https://yourapp.com/terms"
+ href="https://blackhead-web.vercel.app/terms"
- href="https://yourapp.com/privacy"
+ href="https://blackhead-web.vercel.app/privacy"📝 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.
| <a | |
| href="https://yourapp.com/unsubscribe" | |
| className="text-zinc-500 underline" | |
| > | |
| Unsubscribe | |
| </a>{' '} | |
| ·{' '} | |
| <a | |
| href="https://yourapp.com/terms" | |
| className="text-zinc-500 underline" | |
| > | |
| Terms | |
| </a>{' '} | |
| ·{' '} | |
| <a | |
| href="https://yourapp.com/privacy" | |
| className="text-zinc-500 underline" | |
| > | |
| Privacy | |
| </a> | |
| </Text> | |
| <a | |
| href="https://blackhead-web.vercel.app/unsubscribe" | |
| className="text-zinc-500 underline" | |
| > | |
| Unsubscribe | |
| </a>{' '} | |
| ·{' '} | |
| <a | |
| href="https://blackhead-web.vercel.app/terms" | |
| className="text-zinc-500 underline" | |
| > | |
| Terms | |
| </a>{' '} | |
| ·{' '} | |
| <a | |
| href="https://blackhead-web.vercel.app/privacy" | |
| className="text-zinc-500 underline" | |
| > | |
| Privacy | |
| </a> | |
| </Text> |
| disableSignUp: true, // Disable sign up for now | ||
| requireEmailVerification: true, | ||
| sendResetPassword: async ({ user, url }) => { | ||
| await resend.emails.send({ | ||
| from: keys().RESEND_FROM, | ||
| to: user.email, | ||
| tags: [ | ||
| { | ||
| name: 'password', | ||
| value: 'reset' | ||
| } | ||
| ], | ||
| subject: 'Reset your password', | ||
| react: PasswordResetEmail({ | ||
| email: user.email, | ||
| url: url | ||
| }) | ||
| }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Well-implemented password reset functionality.
The password reset email implementation is well-structured with appropriate tags and uses the imported email template correctly.
However, consider adding error handling to the sendResetPassword function to gracefully handle email sending failures.
sendResetPassword: async ({ user, url }) => {
- await resend.emails.send({
- from: keys().RESEND_FROM,
- to: user.email,
- tags: [
- {
- name: 'password',
- value: 'reset'
- }
- ],
- subject: 'Reset your password',
- react: PasswordResetEmail({
- email: user.email,
- url: url
- })
- })
+ try {
+ await resend.emails.send({
+ from: keys().RESEND_FROM,
+ to: user.email,
+ tags: [
+ {
+ name: 'password',
+ value: 'reset'
+ }
+ ],
+ subject: 'Reset your password',
+ react: PasswordResetEmail({
+ email: user.email,
+ url: url
+ })
+ })
+ } catch (error) {
+ console.error('Failed to send reset password email:', error)
+ // Consider how to handle this failure (retry, notify admin, etc.)
+ }
}📝 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.
| disableSignUp: true, // Disable sign up for now | |
| requireEmailVerification: true, | |
| sendResetPassword: async ({ user, url }) => { | |
| await resend.emails.send({ | |
| from: keys().RESEND_FROM, | |
| to: user.email, | |
| tags: [ | |
| { | |
| name: 'password', | |
| value: 'reset' | |
| } | |
| ], | |
| subject: 'Reset your password', | |
| react: PasswordResetEmail({ | |
| email: user.email, | |
| url: url | |
| }) | |
| }) | |
| } | |
| disableSignUp: true, // Disable sign up for now | |
| requireEmailVerification: true, | |
| sendResetPassword: async ({ user, url }) => { | |
| try { | |
| await resend.emails.send({ | |
| from: keys().RESEND_FROM, | |
| to: user.email, | |
| tags: [ | |
| { | |
| name: 'password', | |
| value: 'reset' | |
| } | |
| ], | |
| subject: 'Reset your password', | |
| react: PasswordResetEmail({ | |
| email: user.email, | |
| url: url | |
| }) | |
| }) | |
| } catch (error) { | |
| console.error('Failed to send reset password email:', error) | |
| // Consider how to handle this failure (retry, notify admin, etc.) | |
| } | |
| } |
| emailVerification: { | ||
| sendOnSignUp: true, | ||
| requireEmailVerification: true, | ||
| expiresIn: 60 * 60 * 24, // 1 day | ||
| sendVerificationEmail: async ({ user, url }) => { | ||
| await resend.emails.send({ | ||
| from: keys().RESEND_FROM, | ||
| to: user.email, | ||
| tags: [ | ||
| { | ||
| name: 'verification', | ||
| value: 'email' | ||
| } | ||
| ], | ||
| subject: 'Verify your email', | ||
| react: VerificationEmail({ | ||
| email: user.email, | ||
| url: url | ||
| }) | ||
| }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Comprehensive email verification configuration.
The email verification configuration is thorough with appropriate settings:
- Sending on signup
- Requiring verification
- Setting reasonable expiration time (1 day)
- Well-implemented verification email sending
Similar to the password reset functionality, consider adding error handling to the sendVerificationEmail function.
sendVerificationEmail: async ({ user, url }) => {
- await resend.emails.send({
- from: keys().RESEND_FROM,
- to: user.email,
- tags: [
- {
- name: 'verification',
- value: 'email'
- }
- ],
- subject: 'Verify your email',
- react: VerificationEmail({
- email: user.email,
- url: url
- })
- })
+ try {
+ await resend.emails.send({
+ from: keys().RESEND_FROM,
+ to: user.email,
+ tags: [
+ {
+ name: 'verification',
+ value: 'email'
+ }
+ ],
+ subject: 'Verify your email',
+ react: VerificationEmail({
+ email: user.email,
+ url: url
+ })
+ })
+ } catch (error) {
+ console.error('Failed to send verification email:', error)
+ // Consider how to handle this failure
+ }
}📝 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.
| emailVerification: { | |
| sendOnSignUp: true, | |
| requireEmailVerification: true, | |
| expiresIn: 60 * 60 * 24, // 1 day | |
| sendVerificationEmail: async ({ user, url }) => { | |
| await resend.emails.send({ | |
| from: keys().RESEND_FROM, | |
| to: user.email, | |
| tags: [ | |
| { | |
| name: 'verification', | |
| value: 'email' | |
| } | |
| ], | |
| subject: 'Verify your email', | |
| react: VerificationEmail({ | |
| email: user.email, | |
| url: url | |
| }) | |
| }) | |
| } | |
| emailVerification: { | |
| sendOnSignUp: true, | |
| requireEmailVerification: true, | |
| expiresIn: 60 * 60 * 24, // 1 day | |
| sendVerificationEmail: async ({ user, url }) => { | |
| try { | |
| await resend.emails.send({ | |
| from: keys().RESEND_FROM, | |
| to: user.email, | |
| tags: [ | |
| { | |
| name: 'verification', | |
| value: 'email' | |
| } | |
| ], | |
| subject: 'Verify your email', | |
| react: VerificationEmail({ | |
| email: user.email, | |
| url: url | |
| }) | |
| }) | |
| } catch (error) { | |
| console.error('Failed to send verification email:', error) | |
| // Consider how to handle this failure | |
| } | |
| } | |
| } |
This pull request includes significant updates to the authentication and password management features, as well as some UI adjustments. The most important changes include the addition of forgot password and reset password functionalities, integration of email services for password reset and email verification, and minor layout improvements.
Authentication and Password Management:
ForgotPasswordand its associated schema (apps/web/app/(unauthenticated)/forgot-password/forgot-password.tsx,apps/web/app/(unauthenticated)/forgot-password/schema.ts). [1] [2]ResetPasswordand its associated schema (apps/web/app/(unauthenticated)/reset-password/reset-password.tsx,apps/web/app/(unauthenticated)/reset-password/schema.ts). [1] [2]apps/web/app/(unauthenticated)/signup/schema.ts,apps/web/app/(unauthenticated)/signup/signup.tsx). [1] [2]Email Integration:
resendlibrary (packages/email/index.ts,packages/auth/server.ts). [1] [2]UI Adjustments:
apps/web/app/(unauthenticated)/components/header.tsx,apps/web/app/(unauthenticated)/layout.tsx). [1] [2]apps/web/app/(unauthenticated)/login/email/login-email.tsx).Environment Configuration:
apps/web/.env.example,apps/web/lib/env.ts). [1] [2]These changes enhance the user experience by providing essential password management features and improving the overall layout and usability of the application.
Summary by CodeRabbit
New Features
Style
Chores