-
Notifications
You must be signed in to change notification settings - Fork 196
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
Add login/registration forms #284
Conversation
WalkthroughThe recent updates introduce comprehensive enhancements to the authentication and organization creation functionalities within a web application. Key improvements include the addition of login and registration pages with corresponding routes, form components with validation for user authentication and organization setup, and backend adjustments for user management. These changes streamline the user experience for registration and login processes, enforce data integrity through schema validations, and optimize session management with a new session store. Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 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 as PR comments)
Additionally, you can add CodeRabbit Configration 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.
Review Status
Actionable comments generated: 6
Configuration used: CodeRabbit UI
Files ignored due to path filters (2)
apps/webapp/src/assets/login.jpeg
is excluded by:!**/*.jpeg
apps/webapp/src/assets/register.jpeg
is excluded by:!**/*.jpeg
Files selected for processing (15)
- apps/webapp/src/App.tsx (2 hunks)
- apps/webapp/src/components/auth/login/login-schema.ts (1 hunks)
- apps/webapp/src/components/auth/login/login-user-form.tsx (1 hunks)
- apps/webapp/src/components/auth/register/create-organization-form.tsx (1 hunks)
- apps/webapp/src/components/auth/register/create-organization-schema.ts (1 hunks)
- apps/webapp/src/components/auth/register/register-form.tsx (1 hunks)
- apps/webapp/src/components/auth/register/register-schema.ts (1 hunks)
- apps/webapp/src/components/auth/register/register-user-form.tsx (1 hunks)
- apps/webapp/src/hooks/mutations/useLoginMutation.tsx (1 hunks)
- apps/webapp/src/hooks/mutations/useRegisterMutations.tsx (1 hunks)
- apps/webapp/src/routes/auth_.login.tsx (1 hunks)
- apps/webapp/src/routes/auth_.register.tsx (1 hunks)
- apps/webapp/src/state/sessionStore.ts (1 hunks)
- packages/api/prisma/schema.prisma (4 hunks)
- packages/api/src/@core/auth/auth.service.ts (4 hunks)
Additional comments: 10
apps/webapp/src/components/auth/login/login-schema.ts (1)
- 4-7: Ensure that the
registerSchema
import and itspick
method usage are correctly extracting only thepassword
fields for theloginSchema
. This approach is efficient for reusability but verify thatregisterSchema
includes these fields and no additional unnecessary fields are being included.apps/webapp/src/components/auth/register/register-form.tsx (1)
- 6-11: The implementation of the registration form with a conditional rendering based on the
registered
state is straightforward and effective. However, ensure that there is a mechanism in place for handling errors during the registration process and providing feedback to the user.apps/webapp/src/state/sessionStore.ts (1)
- 22-32: The implementation of
useSessionStore
with Zustand and its persistence middleware is correctly set up for session management. Ensure that sensitive information, such as theaccessToken
, is securely handled and not exposed to the client-side unnecessarily.apps/webapp/src/App.tsx (1)
- 39-40: The addition of routes for
/auth/register
and/auth/login
is correctly implemented, ensuring that users can navigate to the registration and login pages. This change aligns with the PR objectives to enhance user authentication and account management.apps/webapp/src/components/auth/register/create-organization-form.tsx (1)
- 33-33: The hardcoded
stripe_customer_id
in the mutation request is a placeholder. Ensure that this value is dynamically generated or obtained from the user's input or session if it's meant to represent a real Stripe customer ID.apps/webapp/src/components/auth/login/login-user-form.tsx (1)
- 13-89: The
LoginUserForm
component is well-structured and uses form validation effectively. Ensure that error messages from the login process are displayed to the user to improve the user experience.apps/webapp/src/components/auth/register/register-user-form.tsx (1)
- 14-121: The
RegisterUserForm
component correctly implements form handling and submission. Ensure that error handling and user feedback mechanisms are in place for both the registration and login processes.packages/api/src/@core/auth/auth.service.ts (2)
- 46-52: The check for an existing user by email before registration is a critical security measure to prevent duplicate accounts. This implementation correctly throws a
BadRequestException
if the email already exists.- 78-113: The login method's flexibility to allow login by
id_user
orpackages/api/prisma/schema.prisma (1)
- 531-531: Adding a unique constraint to the
users
model is a good practice for ensuring data integrity and preventing duplicate accounts. This change supports the PR objectives related to enhancing user authentication and account management.
export const organizationFormSchema = z.object({ | ||
name: z.string().min(1, 'Name is required'), | ||
}); |
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.
Consider adding more validation rules to the name
field in organizationFormSchema
to ensure data integrity, such as a maximum length constraint.
- name: z.string().min(1, 'Name is required'),
+ name: z.string().min(1, 'Name is required').max(100, 'Name must be less than 100 characters'),
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.
export const organizationFormSchema = z.object({ | |
name: z.string().min(1, 'Name is required'), | |
}); | |
export const organizationFormSchema = z.object({ | |
name: z.string().min(1, 'Name is required').max(100, 'Name must be less than 100 characters'), | |
}); |
export const registerSchema = z.object({ | ||
firstName: z.string().min(1, 'First name is required'), | ||
lastName: z.string().min(1, 'Last name is required'), | ||
email: z.string().min(1, 'Email is required').email('Email is invalid'), | ||
password: z.string().min(8, 'Password must be at least 8 characters'), | ||
}); |
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.
The registerSchema
includes basic validation for firstName
, lastName
, email
, and password
. Consider adding more comprehensive validation rules for email
and password
to enhance security, such as regex patterns for email format and password complexity requirements.
- email: z.string().min(1, 'Email is required').email('Email is invalid'),
+ email: z.string().min(1, 'Email is required').email('Email is invalid').regex(/Your-Regex-Here/, 'Email format is invalid'),
- password: z.string().min(8, 'Password must be at least 8 characters'),
+ password: z.string().min(8, 'Password must be at least 8 characters').regex(/Your-Password-Regex-Here/, 'Password format is invalid'),
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.
export const registerSchema = z.object({ | |
firstName: z.string().min(1, 'First name is required'), | |
lastName: z.string().min(1, 'Last name is required'), | |
email: z.string().min(1, 'Email is required').email('Email is invalid'), | |
password: z.string().min(8, 'Password must be at least 8 characters'), | |
}); | |
export const registerSchema = z.object({ | |
firstName: z.string().min(1, 'First name is required'), | |
lastName: z.string().min(1, 'Last name is required'), | |
email: z.string().min(1, 'Email is required').email('Email is invalid').regex(/Your-Regex-Here/, 'Email format is invalid'), | |
password: z.string().min(8, 'Password must be at least 8 characters').regex(/Your-Password-Regex-Here/, 'Password format is invalid'), | |
}); |
export default function RegisterPage() { | ||
return ( | ||
<div className='min-h-screen grid lg:grid-cols-2 mx-auto text-left'> | ||
<div className='flex-1 flex flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'> | ||
<RegisterForm /> | ||
</div> | ||
<div className='hidden lg:block relative flex-1'> | ||
<img className='absolute inset-0 h-full w-full object-cover' src={RegisterImage} alt='' /> | ||
</div> | ||
</div> | ||
); |
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.
The structure and layout of the RegisterPage
are well-defined, ensuring a responsive design with the use of Tailwind CSS classes. Ensure that the alt
attribute for the img
tag in line 11 is filled with a descriptive text for accessibility purposes.
- <img className='absolute inset-0 h-full w-full object-cover' src={RegisterImage} alt='' />
+ <img className='absolute inset-0 h-full w-full object-cover' src={RegisterImage} alt='Registration Page Background' />
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.
export default function RegisterPage() { | |
return ( | |
<div className='min-h-screen grid lg:grid-cols-2 mx-auto text-left'> | |
<div className='flex-1 flex flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'> | |
<RegisterForm /> | |
</div> | |
<div className='hidden lg:block relative flex-1'> | |
<img className='absolute inset-0 h-full w-full object-cover' src={RegisterImage} alt='' /> | |
</div> | |
</div> | |
); | |
export default function RegisterPage() { | |
return ( | |
<div className='min-h-screen grid lg:grid-cols-2 mx-auto text-left'> | |
<div className='flex-1 flex flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'> | |
<RegisterForm /> | |
</div> | |
<div className='hidden lg:block relative flex-1'> | |
<img className='absolute inset-0 h-full w-full object-cover' src={RegisterImage} alt='Registration Page Background' /> | |
</div> | |
</div> | |
); |
export default function LoginPage() { | ||
return ( | ||
<div className='min-h-screen grid lg:grid-cols-2 mx-auto text-left'> | ||
<div className='hidden lg:block relative flex-1'> | ||
<img className='absolute inset-0 h-full w-full object-cover border-l' src={LoginImage} alt='login image' /> | ||
</div> | ||
<div className='flex-1 flex flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'> | ||
<LoginUserForm /> | ||
</div> | ||
</div> | ||
); |
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.
The LoginPage
implementation is consistent with the RegisterPage
in terms of layout and responsive design. Similar to the previous comment, ensure the alt
attribute for the img
tag in line 8 is filled with descriptive text for accessibility.
- <img className='absolute inset-0 h-full w-full object-cover border-l' src={LoginImage} alt='login image' />
+ <img className='absolute inset-0 h-full w-full object-cover border-l' src={LoginImage} alt='Login Page Background' />
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.
export default function LoginPage() { | |
return ( | |
<div className='min-h-screen grid lg:grid-cols-2 mx-auto text-left'> | |
<div className='hidden lg:block relative flex-1'> | |
<img className='absolute inset-0 h-full w-full object-cover border-l' src={LoginImage} alt='login image' /> | |
</div> | |
<div className='flex-1 flex flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'> | |
<LoginUserForm /> | |
</div> | |
</div> | |
); | |
export default function LoginPage() { | |
return ( | |
<div className='min-h-screen grid lg:grid-cols-2 mx-auto text-left'> | |
<div className='hidden lg:block relative flex-1'> | |
<img className='absolute inset-0 h-full w-full object-cover border-l' src={LoginImage} alt='Login Page Background' /> | |
</div> | |
<div className='flex-1 flex flex-col justify-center py-12 px-4 sm:px-6 lg:flex-none lg:px-20 xl:px-24'> | |
<LoginUserForm /> | |
</div> | |
</div> | |
); |
password_hash: data.password, | ||
}), |
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.
The password_hash
field in the request body should be named password
instead of password_hash
to match the expected field in the backend and to avoid confusion, as hashing should be handled server-side.
- password_hash: data.password,
+ password: data.password,
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.
password_hash: data.password, | |
}), | |
password: data.password, |
method: 'POST', | ||
body: JSON.stringify({ | ||
email: data.email, | ||
password_hash: data.password, |
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.
Similar to the previous comment in useRegisterMutations.tsx
, the password_hash
field in the request body should be named password
for clarity and consistency.
- password_hash: data.password,
+ password: data.password,
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.
password_hash: data.password, | |
password: data.password, |
@mohamedsalem401 Thank you very much for everything you're doing since the start ! When it comes to this PR its impressive but we would like to user something like https://stytch.com/ in addition. If you have ideas, welcome to hear them here ! |
|
New and removed dependencies detected. Learn more about Socket for GitHub ↗︎
|
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.
Review Status
Actionable comments generated: 4
Configuration used: CodeRabbit UI
Files ignored due to path filters (5)
apps/webapp/package.json
is excluded by:!**/*.json
docker-compose.dev.yml
is excluded by:!**/*.yml
packages/api/package.json
is excluded by:!**/*.json
packages/api/swagger/swagger-spec.json
is excluded by:!**/*.json
pnpm-lock.yaml
is excluded by:!**/*.yaml
Files selected for processing (21)
- .env.example (2 hunks)
- apps/webapp/Dockerfile (1 hunks)
- apps/webapp/Dockerfile.dev (1 hunks)
- apps/webapp/src/App.tsx (2 hunks)
- apps/webapp/src/components/auth/login/login-user-form.tsx (1 hunks)
- apps/webapp/src/components/auth/register/create-organization-schema.ts (1 hunks)
- apps/webapp/src/components/root-layout.tsx (2 hunks)
- apps/webapp/src/hooks/mutations/useLoginMutation.tsx (1 hunks)
- apps/webapp/src/main.tsx (2 hunks)
- apps/webapp/src/routes/auth_.login.tsx (1 hunks)
- apps/webapp/src/routes/auth_.register.tsx (1 hunks)
- apps/webapp/src/utils/config.ts (1 hunks)
- packages/api/scripts/init.sql (2 hunks)
- packages/api/src/@core/auth/auth.controller.ts (2 hunks)
- packages/api/src/@core/auth/auth.module.ts (2 hunks)
- packages/api/src/@core/auth/auth.service.ts (4 hunks)
- packages/api/src/@core/auth/guards/stytch.guard.ts (1 hunks)
- packages/api/src/@core/auth/stytch/stytch.module.ts (1 hunks)
- packages/api/src/@core/auth/stytch/stytch.service.ts (1 hunks)
- packages/api/src/app.controller.ts (2 hunks)
- packages/api/src/main.ts (2 hunks)
Files skipped from review as they are similar to previous changes (6)
- apps/webapp/src/App.tsx
- apps/webapp/src/components/auth/login/login-user-form.tsx
- apps/webapp/src/components/auth/register/create-organization-schema.ts
- apps/webapp/src/hooks/mutations/useLoginMutation.tsx
- apps/webapp/src/routes/auth_.login.tsx
- apps/webapp/src/routes/auth_.register.tsx
Additional comments: 16
packages/api/src/@core/auth/stytch/stytch.module.ts (1)
- 1-9: The implementation of the
StytchModule
as a global module is correctly done, ensuring thatStytchService
can be easily injected and used across the application. Good job on structuring this module.apps/webapp/src/utils/config.ts (1)
- 7-7: The addition of
STYTCH_TOKEN
to theconfig
object is correctly implemented, following the existing pattern for environment variable access. This ensures consistency in configuration management.packages/api/src/@core/auth/stytch/stytch.service.ts (1)
- 1-13: The implementation of
StytchService
is well-done, correctly extendingStytchClient
and utilizingConfigService
for accessing environment variables. This approach ensures secure and flexible configuration management.apps/webapp/Dockerfile.dev (1)
- 15-15: The addition of
VITE_STYTCH_TOKEN
as both an argument and an environment variable in the Dockerfile configuration is correctly done. This ensures that the application can access the Stytch token at runtime, aligning with best practices for Dockerfile configurations.Also applies to: 19-19
apps/webapp/src/main.tsx (1)
- 4-13: > 📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [7-24]
The integration of Stytch authentication using
StytchProvider
andStytchHeadlessClient
is correctly implemented. Configuring the client withSTYTCH_TOKEN
ensures secure and flexible management of the token. This is a solid approach to enhancing authentication in the application.packages/api/src/@core/auth/guards/stytch.guard.ts (1)
- 1-30: The implementation of
StytchGuard
for session validation usingStytchService
is well-done. It correctly follows NestJS best practices for creating custom guards and ensures secure session validation by throwingUnauthorizedException
on authentication failure.packages/api/src/@core/auth/auth.module.ts (1)
- 25-25: The addition of
StytchModule
to theAuthModule
's imports array is correctly done, ensuring thatStytchService
is available for authentication-related functionalities. This modular approach enhances the authentication capabilities of the application.packages/api/src/app.controller.ts (1)
- 36-41: The addition of the
/stytch
endpoint protected byStytchGuard
is correctly implemented. Using@UseGuards
to apply route protection and@ApiOperation
for Swagger documentation demonstrates adherence to NestJS best practices for secure and well-documented APIs.packages/api/src/main.ts (1)
- 30-38: The addition of
cookie-parser
middleware and the configuration of CORS usingFRONT_END_URL
fromConfigService
are correctly implemented. These changes enhance the application's security and flexibility in handling cookies and cross-origin requests, adhering to best practices.apps/webapp/Dockerfile (1)
- 31-31: The addition of
VITE_STYTCH_TOKEN
as both an argument and an environment variable in the Dockerfile is correctly done, mirroring the approach in Dockerfile.dev. This consistency ensures that the application can access the Stytch token at runtime across different environments.Also applies to: 34-34
.env.example (1)
- 16-18: The addition of
STYTCH_PROJECT_ID
,STYTCH_SECRET
,FRONT_END_URL
, andVITE_STYTCH_TOKEN
to the.env.example
file is correctly done. This documentation of required environment variables is essential for clear and effective application setup, ensuring that all necessary configurations for Stytch integration and frontend URLs are well-documented.Also applies to: 58-58
apps/webapp/src/components/root-layout.tsx (1)
- 5-10: > 📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [1-1]
Assuming the
Toaster
component was unused or replaced, its removal contributes to maintaining a clean and efficient codebase. It's good practice to remove unused imports and components.packages/api/src/@core/auth/auth.service.ts (3)
- 48-67: The modifications to the
register
method to integrate with Stytch and check for existing emails are correctly implemented. However, ensure that the handling of user data, especially sensitive information, aligns with security best practices.- 91-126: The modifications to the
login
method to support login byid_user
or- 136-145: The addition of the
validateStytchToken
method for Stytch token validation is correctly implemented, enhancing the service's capabilities to support modern authentication flows.packages/api/scripts/init.sql (1)
- 236-236: Making the
users
tableUNIQUE
is a good practice to enforce the uniqueness of user emails, which is essential for authentication systems. This change helps prevent duplicate accounts and supports the integrity of the login process. Ensure that the application logic gracefully handles cases where a user attempts to register with an email that already exists in the system, providing a clear and user-friendly error message.
id_user text NOT NULL, | ||
email text UNIQUE NOT NULL, |
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.
The change from uuid
to text
for the id_user
column in both the users
and api_keys
tables may have implications for data integrity and performance. UUIDs are generally preferred for their uniqueness across databases without additional context. If the change to text
is intended to accommodate a specific format or external system integration, ensure that there are mechanisms in place (e.g., application logic or database triggers) to enforce the uniqueness and format of these text-based identifiers.
@@ -895,7 +895,7 @@ | |||
api_key_hash text NOT NULL, | |||
name text NULL, | |||
id_project uuid NOT NULL, | |||
id_user uuid NOT NULL, | |||
id_user text NOT NULL, |
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.
The change in the id_user
column data type in the api_keys
table to text
should be carefully considered for the same reasons mentioned for the users
table. Additionally, ensure that the foreign key constraint (CONSTRAINT FK_8 FOREIGN KEY (id_user) REFERENCES users (id_user)
) is correctly updated to reflect this change in data type. This is crucial for maintaining referential integrity between the api_keys
and users
tables.
@Get('/callback') | ||
async callback(@Query() query: { token: string }, @Res() res: Response) { | ||
const user = await this.authService.validateStytchToken(query.token); | ||
|
||
await this.authService.createUser({ | ||
email: user.emails[0].email, | ||
first_name: user.name.first_name, | ||
last_name: user.name.last_name, | ||
password_hash: '', | ||
}); | ||
|
||
//TODO make it dynamic | ||
res.redirect('http://localhost/callback/?token=' + query.token); |
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.
The implementation of the callback
method to handle Stytch token validation and redirection is correctly done. However, consider making the redirect URL (http://localhost/callback/
) configurable to support different environments more flexibly.
- res.redirect('http://localhost/callback/?token=' + query.token);
+ const redirectUrl = this.configService.get('FRONT_END_CALLBACK_URL');
+ res.redirect(`${redirectUrl}/?token=${query.token}`);
Ensure ConfigService
is injected and used to retrieve the FRONT_END_CALLBACK_URL
from the environment configuration.
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.
@Get('/callback') | |
async callback(@Query() query: { token: string }, @Res() res: Response) { | |
const user = await this.authService.validateStytchToken(query.token); | |
await this.authService.createUser({ | |
email: user.emails[0].email, | |
first_name: user.name.first_name, | |
last_name: user.name.last_name, | |
password_hash: '', | |
}); | |
//TODO make it dynamic | |
res.redirect('http://localhost/callback/?token=' + query.token); | |
@Get('/callback') | |
async callback(@Query() query: { token: string }, @Res() res: Response) { | |
const user = await this.authService.validateStytchToken(query.token); | |
await this.authService.createUser({ | |
email: user.emails[0].email, | |
first_name: user.name.first_name, | |
last_name: user.name.last_name, | |
password_hash: '', | |
}); | |
//TODO make it dynamic | |
const redirectUrl = this.configService.get('FRONT_END_CALLBACK_URL'); | |
res.redirect(`${redirectUrl}/?token=${query.token}`); |
async createUser(user: CreateUserDto, id_user?: string) { | ||
try { | ||
const foundUser = await this.prisma.users.findUnique({ | ||
where: { id_user: user.id_user }, | ||
const salt = await bcrypt.genSalt(); | ||
const hashedPassword = await bcrypt.hash(user.password_hash, salt); | ||
|
||
return await this.prisma.users.create({ | ||
data: { | ||
...user, | ||
id_user: id_user || uuidv4(), | ||
password_hash: hashedPassword, | ||
}, | ||
}); | ||
} catch (error) { | ||
handleServiceError(error, this.logger); | ||
} | ||
} |
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.
The addition of the createUser
method is well-implemented, facilitating user creation with flexibility for Stytch integration. Consider reviewing the handling of password_hash
, especially for users authenticated through external services like Stytch, to ensure security best practices are followed.
@nael Now you should register an account on Stytch and add the secrets/projectID to the Let me know if you have any suggestions on how we can improve this (we can discuss this on Discord, but I sent a couple of messages on Discord, but I don't think you guys check it very often). |
WebApp
Added login/registration pages for users. you might use this as a draft to implement login/register functionality.
You can also guide me through the changes you want to make.
I think the biggest breaking change was changing Prisma to allow a single user for every email
Update:
Registration Page
Created a Registration Page which consists of two steps
Login Page
Created Login Page
Code
State Management
created new sessionState which handle authed user and his access token
Hooks
Created new useLoginMutation and useRegisterMutation to handle user authentication
Api
Schema
modify users model by adding unique constraints to the user
Services
/auth/login
/auth/register
update create user constraints to throw an error if email already exists
Note
All new forms have client-side validation using react-hook-form and Zod.
Summary by CodeRabbit
email
field in theusers
model to enforce email uniqueness.