-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat(frontend): adding home page and refreshToken in JWT #124
Conversation
WalkthroughThis update implements several authentication enhancements across both backend and frontend codebases. In the backend, JWT secret keys are updated and new refresh token functionality is added, including corresponding TypeORM models and GraphQL mutations. The frontend sees a restructuring of authentication hooks, UI components, GraphQL queries/mutations, and layout modifications. Additionally, environmental configurations, global styles, and various utility modules are updated or reorganized, while obsolete components and code are removed. Changes
Sequence Diagram(s)sequenceDiagram
participant C as Client
participant AR as AuthResolver
participant AS as AuthService
participant DB as Database
C->>AR: refreshToken(refreshToken)
AR->>AS: Invoke refreshToken(refreshToken)
AS->>DB: Validate token & check expiration
DB-->>AS: Return RefreshToken record
AS-->>AR: Generate & return new access token (with original refresh token)
AR-->>C: Respond with RefreshTokenResponse (accessToken, refreshToken)
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
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 using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
bcdbd0e
to
91ad5a2
Compare
c6ec3ea
to
5797224
Compare
backend/.npmrc
Outdated
@@ -0,0 +1,2 @@ | |||
registry=https://registry.npmjs.org/ |
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.
why adding this we don't need it
@@ -30,20 +37,23 @@ export class AuthService { | |||
private menuRepository: Repository<Menu>, | |||
@InjectRepository(Role) | |||
private roleRepository: Repository<Role>, | |||
@InjectRepository(RefreshToken) | |||
private refreshTokenRepository: Repository<RefreshToken>, |
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.
for refresh token, using redis not in memory, different then access token
}, [token]); // ✅ Rebuild client when token updates | ||
|
||
if (!client) return 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.
do we still need apollo provider? we do have lib/client, also have lib/appolo-client. delete others
07ec2d6
to
255d387
Compare
a27a3ee
to
4ec4221
Compare
03d4e34
to
d666365
Compare
f12773e
to
4883088
Compare
47aabb1
to
04e1051
Compare
…date Home component
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: 7
🧹 Nitpick comments (29)
frontend/tsconfig.json (1)
27-28
: Consider enabling strict type checking in the future.While not directly related to this PR, I noticed that
"strict": false
is set. For improved type safety and code quality, consider enabling TypeScript's strict mode in a future update.backend/src/auth/dto/login-user.input.ts (2)
5-6
: Consider adding validation to the email field.Email validation would improve the security and user experience of the authentication system.
@Field() +@IsEmail() email: string;
Don't forget to add the import:
import { IsEmail } from 'class-validator';
8-9
: Consider adding password validation.Adding validation for password complexity would improve security.
@Field() +@MinLength(8) +@Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/, { + message: 'Password is too weak', +}) password: string;Don't forget to add the imports:
import { MinLength, Matches } from 'class-validator';frontend/src/components/user-settings.tsx (1)
34-35
: Ensure redirect logic aligns with new authentication flowThe redirection has been updated to direct users to the home page after logout instead of the login page. This aligns with the PR objectives of adding a home page.
Consider removing the commented-out code to keep the codebase clean unless it's serving a specific documentation purpose.
backend/src/auth/auth.resolver.ts (1)
30-35
: Consider adding validation for the refresh token parameterThe refresh token mutation is correctly implemented, but consider adding validation to ensure the input token is properly formatted before passing it to the service.
@Mutation(() => RefreshTokenResponse) async refreshToken( - @Args('refreshToken') refreshToken: string, + @Args('refreshToken', { description: 'JWT refresh token' }) + @IsNotEmpty() @IsString() refreshToken: string, ): Promise<RefreshTokenResponse> { return this.authService.refreshToken(refreshToken); }backend/src/auth/jwt-cache.service.ts (1)
86-91
: Rename method to be more specific and add JSDocGood job on renaming the method to be more specific about what kind of token is being stored. This aligns well with the JWT refresh token implementation. The JSDoc comment is helpful, but contains a small typo "dbds" in the description.
/** - * The storeAccessToken method stores the access token in the cache dbds + * The storeAccessToken method stores the access token in the cache * @param token the access token * @returns return void */frontend/src/components/AuthChoiceModal.tsx (1)
31-33
: Consider using a constant for the application nameThe hardcoded "CodeFox" name might be better placed in a constants file or configuration to make it easier to update across the application if needed.
frontend/src/app/(main)/chat/Home.tsx (1)
104-158
: Improved conditional rendering logicThe conditional rendering is now clearer with a more straightforward structure. Adding key attributes to both layout options is a good practice for React's reconciliation process.
Consider extracting the common
ChatContent
props into a variable since they're duplicated between both rendering branches:const chatContentProps = { chatId, setSelectedModel, messages, input, handleInputChange, handleSubmit, loadingSubmit, stop, formRef, setInput, setMessages }; // Then use as: // <ChatContent {...chatContentProps} />frontend/src/app/(main)/layout.tsx (1)
1-2
: Consider removing unused imports.
Viewport
is declared but not used. If no longer needed, please remove to avoid confusion.frontend/src/app/(main)/page.tsx (1)
80-128
: Message input and file upload logic.Showing the auth choice modal if the user is not authorized is a nice pattern. Consider clearing the message after send for a better UX.
... onClick={() => { if (!isAuthorized) { setShowAuthChoice(true); } else { console.log('Sending message:', message); - // no reset + setMessage(''); } }} ...frontend/src/hooks/useAuth.ts (2)
18-39
: Consider strengthening token validation approachThe token validation logic is solid, but consider handling token expiration more explicitly, possibly by decoding the JWT to check expiration before making the API call.
const validateToken = useCallback(async () => { const storedToken = localStorage.getItem(LocalStore.accessToken); if (!storedToken) { setIsAuthorized(false); setUser(null); return false; } + // Optionally check token expiration locally first + try { + const tokenData = JSON.parse(atob(storedToken.split('.')[1])); + if (tokenData.exp * 1000 < Date.now()) { + return false; // Token is expired + } + } catch (e) { + console.error('Error decoding token:', e); + } try { const { data } = await checkToken({ variables: { input: { token: storedToken } }, }); if (data?.checkToken) { return true; } return false; } catch (error) { console.error('Token validation error:', error); return false; } }, [checkToken]);
101-122
: Consider adding a timeout to the authentication initializationThe authentication initialization process could potentially hang if network requests take too long. Consider adding a timeout to ensure the loading state is resolved even if requests fail.
useEffect(() => { const initAuth = async () => { setIsLoading(true); + + // Add timeout to ensure loading state resolves + const timeoutId = setTimeout(() => { + if (isLoading) { + console.warn('Auth initialization timed out'); + setIsLoading(false); + setIsAuthorized(false); + } + }, 10000); // 10 second timeout let isValid = await validateToken(); if (!isValid) { isValid = await refreshToken(); } if (isValid) { setIsAuthorized(true); await fetchUserInfo(); } else { setIsAuthorized(false); setUser(null); } setIsLoading(false); + clearTimeout(timeoutId); }; initAuth(); }, [validateToken, refreshToken, fetchUserInfo]);frontend/src/components/SignInModal.tsx (2)
46-47
: Remove or implement commented-out codeEither implement the redirect functionality or remove the commented-out code to maintain clean code standards.
-// If you want to redirect somewhere on success, uncomment: -// router.push("/main");
92-104
: Consider adding input validation for email formatWhile HTML5 validation helps with basic email format checking, consider adding more robust client-side validation to provide better user feedback.
<Input id="email" type="email" value={email} onChange={(e) => { setEmail(e.target.value); setErrorMessage(null); // Clear error when user types }} required + pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" + title="Please enter a valid email address" className="w-full px-4 py-2 rounded-md border" />frontend/src/components/SignUpModal.tsx (2)
40-43
: Consider displaying a success indicator or redirect post-registration.
Currently, the modal closes on successful registration, but providing a success message or redirecting to a different page (e.g., a login view) could improve usability.
50-53
: Enhance validation beyond checking for empty fields.
While "All fields are required" is a good start, consider password strength requirements or specialized email checks to strengthen your user verification process.frontend/src/components/ui/texture-card.tsx (1)
32-57
: Reduce code duplication betweenTextureCardStyled
andTextureCard
.
Since both components have similar nested border patterns, consider merging or sharing internal logic to avoid potential code drift.frontend/src/app/providers/AuthProvider.tsx (1)
8-9
: Remove or revise the placeholder comment for the refresh token mutation.
“Replace this with your real RefreshToken mutation” might cause confusion if this is already the production mutation.backend/src/auth/auth.service.ts (5)
79-82
: Setting a 30-minute expiry for the access token is fine.To improve maintainability, store
'30m'
in a config variable or constant to avoid scattering magic values.
84-85
: Storing refresh token in JWT cache.Consider using a more persistent store (e.g., Redis) for refresh tokens, consistent with the previous recommendation in other review comments.
93-104
: Creating refresh token with a 7-day expiration.Use a config constant for the expiration duration to avoid “magic numbers” and enable easy future adjustments.
119-125
: Logout removes the refresh token from the repository.Currently, the
error
variable in the catch block is unused. Either log the error or remove the variable for clarity.Also applies to: 127-128
371-400
:refreshToken
method implementation works logically.
- Checking existence and expiration is correct.
- Generating a new access token with the same TTL ensures consistency.
- Consider abstracting token creation into a dedicated helper to avoid code duplication.
frontend/src/graphql/request.ts (1)
169-172
: Helper functions for project operations.The approach is straightforward. Consider adding error-handling logic to handle GraphQL errors gracefully.
Also applies to: 174-194
frontend/src/app/hooks/useAuth.ts (5)
8-10
: Naming consistency consideration.
The use ofisAuthorized
andisLoading
is straightforward, but ensure these naming conventions remain consistent throughout the codebase (e.g.,isAuthenticated
,isLoadingAuth
) to maintain clarity across multiple files.
69-81
: Graceful handling of missing or partial user data.
Ifdata?.me
is unexpectedly null or incomplete, the hook will returnfalse
without clarifying the nature of the error. For improved UX, consider returning an explicit error indicator or providing more nuanced feedback for UI logic.
83-91
: AwaitingfetchUserInfo
duringlogin
.
Thelogin
callback triggersfetchUserInfo
without awaiting it. Any immediate logic expecting an up-to-date user might see stale state. You could either await this call or provide a callback to handle post-fetch logic.
100-121
: Potential race condition ininitAuth
.
The sequential checks forvalidateToken
→refreshToken
→fetchUserInfo
are good, but if these calls were to overlap with another authentication event, concurrency might cause unexpected states. You might consider a single, well-synchronized flow or a state machine approach to manage in-flight requests.
124-132
: Review the necessity of exposingrefreshToken
.
While returningrefreshToken
in the hook can be helpful, if you prefer to keep token management behind your hook’s internal logic, consider omitting it from the returned interface to reduce misuse or confusion.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
frontend/ollama-nextjs-ui.gif
is excluded by!**/*.gif
frontend/public/images/github.svg
is excluded by!**/*.svg
frontend/public/images/google.svg
is excluded by!**/*.svg
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (54)
backend/.env
(1 hunks)backend/.env.development
(1 hunks)backend/.gitignore
(1 hunks)backend/src/auth/auth.module.ts
(1 hunks)backend/src/auth/auth.resolver.ts
(2 hunks)backend/src/auth/auth.service.ts
(6 hunks)backend/src/auth/dto/login-user.input.ts
(1 hunks)backend/src/auth/entities/refresh-token.entity.ts
(1 hunks)backend/src/auth/jwt-cache.service.ts
(1 hunks)backend/src/auth/refresh-token/refresh-token.model.ts
(1 hunks)backend/src/auth/role/role.model.ts
(2 hunks)backend/src/decorator/get-auth-token.decorator.ts
(1 hunks)backend/src/main.ts
(1 hunks)backend/src/user/dto/login-user.input.ts
(1 hunks)backend/src/user/user.model.ts
(2 hunks)backend/src/user/user.resolver.ts
(2 hunks)frontend/README.md
(1 hunks)frontend/codegen.ts
(1 hunks)frontend/example.env
(1 hunks)frontend/next.config.mjs
(1 hunks)frontend/package.json
(1 hunks)frontend/src/app/(auth)/login/page.tsx
(0 hunks)frontend/src/app/(auth)/register/page.tsx
(0 hunks)frontend/src/app/(main)/chat/Home.tsx
(3 hunks)frontend/src/app/(main)/chat/MainLayout.tsx
(5 hunks)frontend/src/app/(main)/chat/layout.tsx
(1 hunks)frontend/src/app/(main)/chat/page.tsx
(1 hunks)frontend/src/app/(main)/layout.tsx
(2 hunks)frontend/src/app/(main)/page.tsx
(1 hunks)frontend/src/app/globals.css
(1 hunks)frontend/src/app/hooks/useAuth.ts
(1 hunks)frontend/src/app/hooks/useModels.ts
(2 hunks)frontend/src/app/layout.tsx
(2 hunks)frontend/src/app/providers/AuthProvider.tsx
(1 hunks)frontend/src/app/providers/BaseProvider.tsx
(1 hunks)frontend/src/components/AuthChoiceModal.tsx
(1 hunks)frontend/src/components/SignInModal.tsx
(1 hunks)frontend/src/components/SignUpModal.tsx
(1 hunks)frontend/src/components/chat/chat-list.tsx
(1 hunks)frontend/src/components/code-engine/project-context.tsx
(1 hunks)frontend/src/components/project-modal.tsx
(0 hunks)frontend/src/components/ui/background-gradient.tsx
(1 hunks)frontend/src/components/ui/icons/index.tsx
(1 hunks)frontend/src/components/ui/texture-card.tsx
(1 hunks)frontend/src/components/user-settings.tsx
(1 hunks)frontend/src/graphql/mutations/auth.ts
(1 hunks)frontend/src/graphql/request.ts
(4 hunks)frontend/src/graphql/schema.gql
(4 hunks)frontend/src/graphql/type.tsx
(16 hunks)frontend/src/hooks/useAuth.ts
(1 hunks)frontend/src/lib/client.ts
(5 hunks)frontend/src/lib/storage.ts
(1 hunks)frontend/src/utils/requests.ts
(0 hunks)frontend/tsconfig.json
(1 hunks)
💤 Files with no reviewable changes (4)
- frontend/src/components/project-modal.tsx
- frontend/src/app/(auth)/login/page.tsx
- frontend/src/app/(auth)/register/page.tsx
- frontend/src/utils/requests.ts
✅ Files skipped from review due to trivial changes (7)
- frontend/next.config.mjs
- frontend/src/app/providers/BaseProvider.tsx
- frontend/src/components/chat/chat-list.tsx
- frontend/src/app/(main)/chat/page.tsx
- frontend/example.env
- frontend/src/app/(main)/chat/layout.tsx
- backend/.gitignore
🧰 Additional context used
🪛 Biome (1.9.4)
frontend/src/app/providers/AuthProvider.tsx
[error] 19-19: void is confusing inside a union type.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
🪛 GitHub Check: autofix
backend/src/auth/auth.service.ts
[warning] 128-128:
'error' is defined but never used
🔇 Additional comments (93)
frontend/package.json (1)
39-39
: LGTM! Good addition of accessibility component.The
@radix-ui/react-visually-hidden
component is a valuable addition that will help improve accessibility by providing proper screen reader support while visually hiding elements.frontend/src/lib/storage.ts (1)
3-3
: Good addition for JWT refresh token support.Adding the
refreshToken
enum value toLocalStore
is a necessary change to support the JWT refresh token functionality outlined in this PR.frontend/README.md (1)
6-6
:✅ Verification successful
Documentation updated to reflect new environment file name.
The command has been updated to use
example.env
instead of.env.example
. This ensures developers will use the correct file when setting up their environment.
🏁 Script executed:
#!/bin/bash # Verify if the example.env file actually exists in the frontend directory if [ -f "frontend/example.env" ]; then echo "✅ frontend/example.env exists" else echo "❌ frontend/example.env does not exist" echo "Checking if the old .env.example still exists:" if [ -f "frontend/.env.example" ]; then echo "⚠️ frontend/.env.example exists - documentation may be incorrect" fi fiLength of output: 102
Documentation Environment File Verified
The documentation in
frontend/README.md
correctly reflects the new environment file name. The command:cp example.env .envhas been verified, and
frontend/example.env
exists as expected. No further changes or corrections are needed.frontend/tsconfig.json (1)
28-28
: Good addition of ES2017 target.Setting
"target": "ES2017"
is appropriate as it enables important JavaScript features like async/await which will be beneficial for implementing the JWT refresh token flow.backend/src/main.ts (2)
21-21
: Added x-refresh-token header for CORS configuration.The addition of
x-refresh-token
to the allowed headers list is necessary to implement the refresh token functionality mentioned in the PR title. This allows browsers to send refresh tokens in cross-origin requests.
12-23
: Verify CORS configuration is complete for token-based authentication.I notice that while
x-refresh-token
header has been added, thecredentials
property is not present in the CORS configuration. If you're using HTTP-only cookies for storing refresh tokens (a security best practice), you'll need to addcredentials: true
to the CORS config.backend/src/auth/dto/login-user.input.ts (1)
1-10
: LGTM! Well-structured GraphQL input type for email-based login.The
LoginUserInput
class is correctly implemented with proper GraphQL decorators for the email and password fields.backend/src/auth/entities/refresh-token.entity.ts (1)
1-24
: LGTM! Proper implementation of RefreshToken entity.The implementation includes all necessary fields for a refresh token - identity, token value, user association, expiration, and creation timestamp. Good use of TypeORM decorators.
backend/src/auth/auth.module.ts (1)
16-16
: Consolidated import needed for RefreshToken entity.The RefreshToken entity was added to TypeORM's forFeature array correctly, but we need to ensure we're using a single implementation.
backend/src/auth/role/role.model.ts (2)
1-1
: LGTM! Proper ID type import for GraphQL.Adding the ID type from @nestjs/graphql is appropriate for defining strongly-typed GraphQL schemas.
15-15
: Good improvement to GraphQL type definition.Changing from
@Field()
to@Field(() => ID)
properly specifies that this field should be treated as a GraphQL ID type rather than a generic field. This improves type safety in the GraphQL schema.backend/src/user/dto/login-user.input.ts (1)
2-2
: Good improvement: Migrating to email-based authenticationThe switch from username to email-based authentication is a security and usability improvement. Email addresses are unique identifiers and easier for users to remember than usernames.
Also applies to: 7-8
frontend/src/app/layout.tsx (1)
1-1
:❓ Verification inconclusive
Simplification of RootLayout component
The removal of the Viewport type import and simplification of the function signature improve code readability. However, make sure that:
- The viewport configurations are properly handled elsewhere or not needed
- The application's responsive behavior is not negatively affected by this change
Also applies to: 15-17
🏁 Script executed:
#!/bin/bash # Check if viewport configuration exists elsewhere in the codebase echo "Checking for viewport configuration in other files..." fd -t f -e tsx -e ts "viewport.*=" --exclude node_modulesLength of output: 176
Simplified RootLayout Verified – Confirm Responsive Behavior Manually
The removal of the viewport type import and the simplification of the RootLayout function signature in
frontend/src/app/layout.tsx
(both at line 1 and lines 15–17) improve code readability. A search for viewport configuration across the codebase returned no matches, which suggests that no explicit viewport settings are being relied upon elsewhere.
- Ensure that:
- The absence of viewport configuration is intentional and does not leave out any critical settings.
- You manually verify that the application's responsive behavior remains intact through testing across devices/resolutions.
frontend/src/app/globals.css (1)
116-130
: Nice addition of subtle background gradientsThe background gradient classes add a subtle visual enhancement for both light and dark modes. This is a good UI improvement that enhances the aesthetics without compromising readability.
Verify that these classes are properly used in the new home page components for the intended visual effect.
frontend/src/components/ui/icons/index.tsx (1)
1-22
: Good implementation of icon components!The implementation of
GoogleIcon
andGitHubIcon
components using Next.jsImage
component is clean and follows best practices.Two small suggestions:
- Consider adding TypeScript type annotations (even though the types are inferred correctly here)
- Verify that these image paths (
/images/google.png
and/images/github-icon.png
) exist in your public directoryfrontend/src/app/hooks/useModels.ts (3)
6-6
: Good integration of authentication contextAdding the authentication context import properly integrates the models fetching with the authentication system.
15-15
: Well implemented authentication state integrationThe destructuring of
isAuthorized
andisChecking
from the auth context provides clean access to the authentication state needed for controlling data fetching.
54-54
: Effective authentication-aware query controlThe modified skip condition correctly prevents the query from running when the user is not authorized or when the authorization check is still in progress, which is a good security practice.
backend/src/user/user.model.ts (3)
1-1
: Appropriate GraphQL type importAdding the ID type import from GraphQL is appropriate for properly typing the user ID field.
19-21
: Good GraphQL field type definitionAdding the
@Field(() => ID)
decorator properly exposes the ID field in the GraphQL schema with the correct type.
23-25
: Verify impact of removing username uniqueness constraintThe unique constraint on the username field has been removed. This might be intentional if you're moving to email-based authentication, but ensure this change won't cause issues with existing code that might expect usernames to be unique.
#!/bin/bash # Check if any code depends on username uniqueness echo "Searching for code that might depend on username uniqueness..." rg "find.*username|findBy.*username|findOne.*username" --type tsfrontend/src/graphql/mutations/auth.ts (1)
1-28
: Clean implementation of GraphQL auth mutationsThe implementations for user registration, login, and token refresh are well-structured and follow GraphQL best practices. The mutation structure properly handles the refresh token flow required for JWT authentication.
backend/src/auth/auth.resolver.ts (1)
12-19
: Good type definition for token responseThe
RefreshTokenResponse
class is properly defined with GraphQL decorators and contains all necessary fields for a proper token refresh response.frontend/src/components/ui/background-gradient.tsx (2)
5-21
: Clean UI component implementation with proper ref forwardingThe
BackgroundGradient
component follows React best practices by usingforwardRef
and properly handling class name composition with thecn
utility.
22-22
: Good practice adding displayNameAdding a display name helps with debugging and component identification in React DevTools.
frontend/src/components/code-engine/project-context.tsx (3)
12-17
: Clean up of import statementsThe consolidation of imports improves code organization.
93-102
:✅ Verification successful
Verify authentication is handled centrally after removing context headers
The Authorization header has been removed from the mutation context. Ensure that authentication is properly configured at the Apollo Client level to handle JWT tokens for all requests.
🏁 Script executed:
#!/bin/bash # Find Apollo client setup to ensure token handling is centralized rg -A 15 "ApolloClient|createHttpLink|authLink|setContext" --type tsLength of output: 4831
Authentication Handling Confirmed
The removal of the Authorization header from the mutation context in
frontend/src/components/code-engine/project-context.tsx
is correct. The Apollo Client setup infrontend/src/lib/client.ts
clearly shows that token injection is now handled centrally using thesetContext
method. No further changes are required on this front.
104-106
:✅ Verification successful
Ensure consistent authentication approach across queries
Similar to the mutation, the Authorization header has been removed from the query context. Verify that all GraphQL operations use a consistent authentication approach.
🏁 Script executed:
#!/bin/bash # Check if any GraphQL operations still use Authorization headers in context rg "Authorization.*Bearer" --type tsLength of output: 312
Authentication Approach Consistency Confirmed
After verifying the codebase, it’s clear that the GraphQL client in
frontend/src/lib/client.ts
is responsible for automatically adding theAuthorization
header when a valid token is present. In theproject-context.tsx
file, the query intentionally omits an explicit header—matching the pattern used for mutations and ensuring a centralized authentication strategy.
- The client configuration in
frontend/src/lib/client.ts
consistently injects the header.- A backend occurrence (in
backend/src/build-system/handlers/backend/requirements-document/prompt.ts
) appears unrelated to GraphQL queries and may need separate review if applicable.Please confirm that this centralized approach is intended for all GraphQL operations.
frontend/src/components/AuthChoiceModal.tsx (2)
1-57
: Well-structured authentication modal componentThis is a well-implemented modal component with good structure, proper TypeScript typing, and accessibility features. The use of
VisuallyHidden
for screen readers is particularly good practice.
38-43
: Ensure consistency in button stylingThe sign-in button uses red color theming, while the sign-up button uses the default styling. Make sure this color choice aligns with your design system and that red isn't typically associated with errors in your UI.
frontend/codegen.ts (1)
36-36
: Simplify GraphQL code generation watch configurationGood change to focus the watch pattern only on the schema file. This will prevent unnecessary code generation runs when other files change.
frontend/src/app/(main)/chat/Home.tsx (1)
16-22
: Simplified importsGood job cleaning up the imports. Removing unused imports and organizing them improves code readability and maintenance.
backend/src/user/user.resolver.ts (4)
18-19
: Use the logger with caution.Ensure no sensitive information, such as user tokens or personal data, is exposed in logs.
20-27
: Well-defined LoginResponse object.Defining a dedicated return type for tokens is a clear approach. Just be mindful to avoid inadvertently exposing these tokens in logs or other channels.
43-47
: Verify downstream usage of the new return type.The return type is now
LoginResponse
instead ofUser
. Check that any consuming code expecting aUser
object is updated accordingly.
57-57
: Avoid potential PII leakage in logs.Logging the user ID may be acceptable, but confirm that it is not considered sensitive based on your data policy.
frontend/src/app/(main)/layout.tsx (3)
4-4
: Title update looks good.No issues with updating the title to be more descriptive.
14-14
: Renaming the layout function.Renaming from
Layout
toHomeLayout
aligns well with the new user flow.
19-23
: Minimal wrapper structure is straightforward.Returning a simple container and
<main>
section is a clean approach for your layout.frontend/src/app/(main)/chat/MainLayout.tsx (9)
3-5
: New imports.Imports for authentication and navigation are appropriate and streamline the layout logic.
11-13
: Additional imports for project context and GraphQL.Good use of context and queries to keep the code modular.
20-20
: Using isAuthorized and isChecking.Destructuring from the auth context is clear and helps manage conditional rendering.
28-28
: Refetch usage.Extracting
refetch
from the GraphQL query is good, but ensure you handle potential errors and loading states.
38-38
: useRouter instantiation.No issues with assigning the router instance for navigation.
40-44
: Redirection logic.Be cautious about potential redirect loops on the home page. Verify that the logic doesn't trap users.
61-67
: Loading fallback.Displaying a loading state during auth checks is user-friendly.
69-71
: Return null on unauthorized.This prevents unauthorized rendering. Just ensure you handle the user flow properly elsewhere.
104-104
: Modal refetch integration.Passing
refetch
to refresh data is a good approach to keep the project list up to date.frontend/src/app/(main)/page.tsx (6)
1-1
: Client-side rendering directive.No concerns; marking this file as a client component is standard for interactive pages.
3-7
: Utility imports.No issues with the new hooks and icon imports.
9-12
: Auth and modal components.Excellent modular approach for sign-in, sign-up, and choice flows.
14-21
: State and context usage.Storing UI states (modals, message) and using
useAuthContext
is straightforward and clean.
23-78
: Navigation bar structure.The theme toggle, sign-in/up controls, and brand elements are implemented cleanly with responsive classes.
129-145
: Modal workflow.Using dedicated modals for sign-in, sign-up, and an auth choice is well-structured.
frontend/src/graphql/schema.gql (5)
62-64
: Good addition of refreshToken field to LoginResponseThe inclusion of
refreshToken
in the LoginResponse type is a strong security enhancement that allows for token rotation and shorter-lived access tokens.
67-69
: Appropriate shift to email-based authenticationSwitching from username to email for authentication is a good practice as emails are guaranteed to be unique and are commonly used for account recovery.
100-101
: Well-defined refreshToken mutationThe refreshToken mutation provides a clear API endpoint for token renewal, which is essential for maintaining user sessions securely without requiring frequent re-authentication.
155-158
: Well-structured RefreshTokenResponse typeThe RefreshTokenResponse type provides a clean interface for returning both the new access and refresh tokens, maintaining consistency with the LoginResponse type.
186-190
: Added important ID field to User typeAdding an ID field to the User type is essential for uniquely identifying users in the frontend. This will improve component rendering and data management.
frontend/src/hooks/useAuth.ts (2)
8-17
: Well-structured authentication hook with appropriate state managementThis hook establishes a solid foundation for managing authentication state. The comment about preventing repeated requests is helpful context.
41-68
: Robust token refresh implementationThe refresh token implementation is well-structured with appropriate error handling and return values.
frontend/src/lib/client.ts (5)
1-1
: Appropriate use of 'use client' directiveThe 'use client' directive is correctly added to ensure this code runs on the client side in Next.js.
17-25
: Good fallback URL configuration and proper Content-Type headerThe fallback URL ensures the client works in development environments, and the Content-Type header is essential for proper request formatting.
27-40
: Improved WebSocket link with proper typingThe WebSocket link is now properly typed and includes a fallback URL, improving type safety and configuration flexibility.
57-72
: Enhanced auth middleware preserves existing headersThe modification to use a function for context setting ensures existing headers are preserved, which is important when combining multiple middleware components.
103-110
: Correct Apollo client export with no-cache policyDirectly exporting the client simplifies imports. The no-cache fetch policy ensures fresh data on each request, which is appropriate for authentication-related operations.
frontend/src/components/SignInModal.tsx (2)
36-53
: Well-implemented login mutation with proper success and error handlingThe login mutation is correctly set up with appropriate callbacks for completion and error states. The toast notification provides good user feedback.
144-167
: Implement social login functionality or add TODO commentsThe social login buttons (Google and GitHub) are visually implemented but don't have actual functionality. Either implement the functionality or add TODO comments for future implementation.
Are these social login options intended to be functional in this PR? If not, consider adding a TODO comment or disabled state to indicate they're not yet implemented:
<Button variant="outline" className="flex items-center gap-2 w-full" + disabled={true} + title="Coming soon" > <img src="/images/google.svg" alt="Google" className="w-5 h-5" /> <span>Google</span> </Button>frontend/src/components/ui/texture-card.tsx (1)
5-30
: Well-structured card design with forwardRef.
The layered borders and nested structure create a polished look, and using forwardRef ensures flexibility for consumer components.frontend/src/app/providers/AuthProvider.tsx (1)
64-64
: Await therefreshAccessToken()
call for improved error handling.
SincerefreshAccessToken()
is asynchronous, consider awaiting to ensure errors or success states are correctly propagated.backend/src/auth/auth.service.ts (5)
19-22
: New imports for refresh token logic look good.Using
RefreshToken
,randomUUID
,compare
, andhash
is appropriate for the updated authentication flow. Be mindful to handle errors properly when using these utilities.
36-37
: InjectingRefreshToken
repository.Confirm that your entity configuration is correct and tested thoroughly, especially if you expect concurrency in refresh token creation.
43-49
: Email uniqueness check and ConflictException.Switching from username-based checks to email-based checks is a reliable approach. This ensures you uniquely identify users by their email.
62-66
: Login now returningRefreshTokenResponse
.The shift to use email instead of username aligns with the register logic. Please verify all frontend calls now properly pass
87-91
: Returning bothaccessToken
andrefreshToken
.This aligns with standard JWT flows where refresh tokens are handled separately. Please ensure your client code expects both tokens.
frontend/src/graphql/type.tsx (8)
102-106
: AddedrefreshToken
toLoginResponse
and replacedusername
withLoginUserInput
.Ensures alignment with backend changes that now rely on email-based login and produce both tokens on login.
142-174
: NewrefreshToken
mutation in the schema.This is consistent with the backend’s refresh token flow. Ensure the client invokes this mutation only when the access token is expired or nearing expiration.
203-203
:user
field onProject
and renaminggetProjectDetails
togetProject
.Consolidating user information under project queries is helpful, but confirm that the frontend is updated for the newly named query.
Also applies to: 231-231, 251-251
259-264
: NewRefreshTokenResponse
type.Matches the backend’s response structure. This consistency makes it easier to maintain authentication flows across client and server.
434-435
: Schema definitions forRefreshTokenResponse
and user resolvers.Double-check that the resolvers for these new fields match how they are generated and returned on the server.
Also applies to: 442-443
553-553
: Resolver forrefreshToken
inLoginResponse
.Ensures the schema consistently exposes the refresh token along with the initial login response.
Also applies to: 559-560
756-764
:RefreshTokenResponseResolvers
.The resolvers mapping is properly typed. Ensure you have tests verifying correct resolver behavior.
788-788
: Addingid
andprojects
fields toUser
.Make sure the backend resolvers properly load user projects to avoid empty arrays or partial data.
Also applies to: 794-795
frontend/src/graphql/request.ts (5)
1-2
: Import statements look standard.Using
TypedDocumentNode
helps ensure type safety across GraphQL operations.
53-67
: Renamed subscription toCHAT_STREAM
and addedstatus
field.Keep your subscription consumer updated to parse the new
status
field.
127-138
:GET_USER_PROJECTS
query.Fetches essential project data. Make sure to handle cases where the user has no projects.
141-153
:GET_PROJECT_DETAILS
query.Retrieves project details by ID. Confirm that the backend is returning exactly what the front end expects.
155-167
:CREATE_PROJECT
mutation.Returning the newly created project’s data is good for immediate UI updates. Verify that the field name (
path
vs.projectPath
) is correct.frontend/src/app/hooks/useAuth.ts (5)
1-6
: Looks good on imports.
No major findings here. These imports are standard and appropriate for the use cases in this file.
13-15
: Lazy queries are a solid choice.
UsinguseLazyQuery
here provides a nice balance of control and optimization. Ensure any potential Apollo-related error states (e.g., network errors, partial refetch logic) are handled or considered upstream or downstream if necessary.
17-38
: Refine error handling forvalidateToken
.
Currently, token validation errors are only logged to console without returning them up the chain. Consider either re-throwing the error or returning an error state to enable the consuming logic (or UI) to handle these failures more gracefully.
[refactor_suggestion_good_to_have, architecture_advice]
40-67
: Clarify therefreshToken
variable naming and usage.
The function namerefreshToken
is colliding with the local variable name also calledrefreshToken
(retrieved from localStorage). This can be confusing. Renaming the local variable to something likestoredRefreshToken
makes it clearer.
[nitpick, architecture_advice]
Here is a suggested diff:-const refreshToken = localStorage.getItem(LocalStore.refreshToken); +const storedRefreshToken = localStorage.getItem(LocalStore.refreshToken); -variables: { refreshToken }, +variables: { refreshToken: storedRefreshToken },
93-98
: Validate server-side session state on logout.
This logout approach effectively clears local tokens and resets context, which is good. However, verify if the server also maintains any session that should be invalidated to fully complete the logout process.
@@ -8,11 +8,12 @@ import { AuthService } from './auth.service'; | |||
import { User } from 'src/user/user.model'; | |||
import { AuthResolver } from './auth.resolver'; | |||
import { JwtCacheService } from 'src/auth/jwt-cache.service'; | |||
import { RefreshToken } from './refresh-token/refresh-token.model'; |
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.
Imported the duplicated RefreshToken entity.
This import references the model from refresh-token/refresh-token.model.ts
, but there's a duplicate definition in entities/refresh-token.entity.ts
. You need to decide which implementation to use and update imports accordingly.
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: 0
🧹 Nitpick comments (2)
frontend/src/app/hooks/useAuth.ts (2)
18-39
: Token validation looks good but consider security enhancements.The validation function is well-structured with proper error handling. However, storing the token in localStorage makes it vulnerable to XSS attacks.
Consider using HttpOnly cookies for token storage instead of localStorage for better security. This would require server-side changes but provides significantly better protection against XSS attacks.
101-122
: Consider adding proactive token refresh.The authentication initialization flow is well-structured, first validating the token and then attempting to refresh if needed.
Consider implementing a proactive token refresh mechanism that refreshes the token before it expires, perhaps using a timer based on the token's expiration time. This would prevent disruption during active user sessions.
// Example implementation to add useEffect(() => { if (!isAuthorized) return; // Assuming token payload can be decoded to get expiration time const token = localStorage.getItem(LocalStore.accessToken); const payload = token ? JSON.parse(atob(token.split('.')[1])) : null; if (!payload || !payload.exp) return; // Refresh 5 minutes before expiration const expiresIn = payload.exp * 1000 - Date.now() - 5 * 60 * 1000; if (expiresIn <= 0) { refreshToken(); return; } const timer = setTimeout(() => refreshToken(), expiresIn); return () => clearTimeout(timer); }, [isAuthorized, refreshToken]);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
frontend/src/app/hooks/useAuth.ts
(1 hunks)frontend/src/components/chat/chat-list.tsx
(1 hunks)frontend/src/components/code-engine/project-context.tsx
(1 hunks)frontend/src/components/ui/sidebar.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- frontend/src/components/ui/sidebar.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- frontend/src/components/chat/chat-list.tsx
- frontend/src/components/code-engine/project-context.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: autofix
🔇 Additional comments (7)
frontend/src/app/hooks/useAuth.ts (7)
1-6
: Good import organization.The imports are well-organized with a clear separation between Apollo client, GraphQL operations, local utilities, and React hooks.
8-12
: Clear state management with improved loading indicator.Good refactoring to use a standard function declaration instead of an arrow function. The addition of
isLoading
state is a valuable improvement that allows UI components to show appropriate loading states during authentication operations.
14-16
: Good use of lazy queries.Using
useLazyQuery
instead ofuseQuery
is a better approach here as it gives more control over when queries are executed, preventing unnecessary network requests on component render.
41-68
: Well-implemented token refresh functionality.The refresh token implementation is clean with proper error handling. Good job checking for the existence of the refresh token before attempting to refresh.
70-82
: User information fetching looks good.The
fetchUserInfo
function is well-structured with proper error handling and state updates.
84-99
: Login and logout functions are clean and concise.Both functions handle token storage/removal appropriately and update the auth state correctly.
124-133
: Return object contains all necessary auth-related functions and state.The hook returns all the needed elements for authentication management in the application.
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced file operation security with a unified validation process, ensuring robust handling of file actions. - **Refactor** - Streamlined file validation by consolidating multiple checks into one efficient routine for improved consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Optimized the success rate of generation - Added overall theme analysis - Added project size analysis - Increase support for single-page projects and distinguish multi-page projects <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced project build and document generation with dynamic configuration for tailored code, architecture, and UX outputs. - Improved Docker integration with updated file mounting for better file access. - Introduced new handlers and updated configurations for generating file structures and architecture documents. - Added new properties for project size and model selection in build configurations. - Expanded prompt generation for UX Sitemap and Product Requirement Document (PRD) with detailed guidelines. - **Bug Fixes** - Resolved issues with file handling and asynchronous processes, ensuring smoother performance and more reliable error reporting. - Improved error messaging for model-related issues to aid debugging. These updates contribute to a more stable and responsive experience. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: ZHallen122 <zhallen12261@gmail.com>
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Chores