Implements JWT auth flow with 7 day tokens#187
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis set of changes introduces a new authentication system based on JWT tokens and authentication requests, replacing the previous NEAR signature-based flow. It adds backend routes and services for login initiation, verification, and logout, updates middleware to use JWT cookies, and refactors frontend authentication context and UI to support sign-in and authorization as separate steps. Supporting database schema, repository, and Docker configurations are also introduced or updated. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend
participant API
participant AuthService
participant AuthRequestRepo
participant UserService
participant JWT
User->>Frontend: Clicks "Sign In"
Frontend->>User: NEAR wallet sign-in flow
User->>Frontend: Signs in with NEAR
Frontend->>API: POST /auth/initiate-login (accountId)
API->>AuthService: createAuthRequest(accountId)
AuthService->>UserService: ensureUserProfile(accountId)
AuthService->>AuthRequestRepo: create(nonce, accountId, expiresAt)
AuthService-->>API: { nonce, recipient }
API-->>Frontend: { nonce, recipient }
Frontend->>User: Prompts to sign message (nonce)
User->>Frontend: Signs nonce with NEAR key
Frontend->>API: POST /auth/verify-login (token, accountId)
API->>AuthService: verifyAuthRequest(token, accountId)
AuthService->>AuthRequestRepo: findLatestByAccountId(accountId)
AuthService->>NEAR: Verify token signature
AuthService->>AuthRequestRepo: deleteById(id)
AuthService->>JWT: Sign JWT (accountId)
AuthService-->>API: JWT token
API-->>Frontend: Set "token" cookie (JWT)
Frontend->>User: User is now "authorized"
Possibly related PRs
Poem
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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.
Actionable comments posted: 5
🧹 Nitpick comments (10)
apps/api/src/utils/service-provider.ts (1)
91-93: Clean service registration following established pattern.The AuthService registration correctly follows the dependency injection pattern used throughout the class. Consider adding a dedicated getter method like
getAuthService()for consistency with other services.Add a dedicated getter method for consistency:
+ /** + * Get the auth service + * @returns The auth service + */ + public getAuthService(): AuthService { + return this.getService<AuthService>("authService"); + }packages/shared-db/src/schema/auth.ts (2)
11-11: Consider removing or documenting the unusedstatefield.The
statefield is defined as unique but doesn't appear to be used anywhere in the authentication flow. If it's intended for future OAuth-like state parameter support, consider adding a comment explaining its purpose. Otherwise, consider removing it to avoid confusion.
8-15: Add an index for efficient auth request lookups.The
findLatestByAccountIdmethod queries byaccountIdandcreatedAt. Consider adding a composite index to optimize this common query pattern.Add an index after the table definition:
import { index } from "drizzle-orm/pg-core"; export const authRequestsIndexes = { accountIdCreatedAt: index("auth_requests_account_id_created_at_idx") .on(authRequests.accountId, authRequests.createdAt), };apps/api/src/routes/api/auth.ts (1)
19-53: Consider adding rate limiting to prevent brute force attacks.Authentication endpoints are susceptible to brute force attacks. Consider implementing rate limiting based on IP address or account ID.
packages/shared-db/src/repositories/authRequest.repository.ts (1)
6-76: Consider implementing cleanup for expired auth requests.Auth requests have an expiration time but there's no mechanism to clean up expired entries. This could lead to database bloat over time.
Consider adding a method to delete expired auth requests that can be called periodically:
async deleteExpired(): Promise<number> { return withErrorHandling( async () => { return executeWithRetry(async (dbInstance) => { const now = new Date(); const result = await dbInstance .delete(authRequests) .where(lt(authRequests.expiresAt, now)) .returning(); return result.length; }, this.db); }, { operationName: "delete expired auth requests", }, 0, ); }apps/api/src/services/auth.service.ts (1)
37-37: Use constants for time calculations.Magic numbers make the code less maintainable. Define constants for time durations.
Add constants at the top of the file:
const AUTH_REQUEST_EXPIRY_MS = 5 * 60 * 1000; // 5 minutes const JWT_EXPIRY_SECONDS = 60 * 60 * 24 * 7; // 7 daysThen use them:
- const expiresAt = new Date(Date.now() + 5 * 60 * 1000); // 5 minutes + const expiresAt = new Date(Date.now() + AUTH_REQUEST_EXPIRY_MS);- exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, // 7 days + exp: Math.floor(Date.now() / 1000) + JWT_EXPIRY_SECONDS,Also applies to: 82-82
apps/api/src/middlewares/auth.middleware.ts (1)
12-16: Consider making JWT_SECRET validation a startup check.The middleware returns 500 if JWT_SECRET is missing, which means the application is misconfigured. This should ideally be caught during application startup rather than at runtime.
apps/app/src/contexts/auth-context.tsx (2)
45-52: Consider differentiating error types in authorization check.The current implementation treats all errors equally. Consider logging errors or differentiating between authentication failures (401/403) and other errors (network, 500) for better debugging and user experience.
const checkAuthorization = useCallback(async () => { try { await apiClient.makeRequest("GET", "/users/me"); setIsAuthorized(true); - } catch { + } catch (error) { + // Log error for debugging while keeping user experience unchanged + console.error("Authorization check failed:", error); setIsAuthorized(false); } }, []);
75-117: Consider making the authorization message configurable.The implementation is solid with proper error handling. However, the hardcoded message "Authorize Curate.fun" at line 90 could be made configurable for better reusability across different environments or applications.
Consider extracting the message to a configuration constant or environment variable:
-const message = "Authorize Curate.fun"; +const message = process.env.NEXT_PUBLIC_AUTH_MESSAGE || "Authorize Curate.fun";packages/shared-db/migrations/meta/0017_snapshot.json (1)
1404-1471: Well-designed auth_requests table schema.The table structure properly supports the JWT authentication flow with:
- Unique constraints on nonce and state for security
- Expiration timestamp for token validity
- No foreign key constraint allows authentication before user creation
Consider implementing a cleanup job to remove expired auth requests periodically.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (18)
apps/api/package.json(1 hunks)apps/api/src/middlewares/auth.middleware.ts(1 hunks)apps/api/src/routes/api/auth.ts(1 hunks)apps/api/src/routes/api/index.ts(2 hunks)apps/api/src/services/auth.service.ts(1 hunks)apps/api/src/services/users.service.ts(1 hunks)apps/api/src/utils/service-provider.ts(3 hunks)apps/app/package.json(1 hunks)apps/app/src/components/UserMenu.tsx(2 hunks)apps/app/src/contexts/auth-context.tsx(2 hunks)apps/app/src/lib/api-client.ts(0 hunks)packages/shared-db/migrations/0017_loud_lady_vermin.sql(1 hunks)packages/shared-db/migrations/meta/0017_snapshot.json(1 hunks)packages/shared-db/migrations/meta/_journal.json(1 hunks)packages/shared-db/src/index.ts(1 hunks)packages/shared-db/src/repositories/authRequest.repository.ts(1 hunks)packages/shared-db/src/schema/auth.ts(1 hunks)packages/shared-db/src/schema/index.ts(1 hunks)
💤 Files with no reviewable changes (1)
- apps/app/src/lib/api-client.ts
🔇 Additional comments (16)
apps/api/package.json (1)
63-63: Bumpnear-sign-verifyto ^0.4.1 for auth flow compatibility.The minor version upgrade aligns with the NEAR signature verification enhancements in your new JWT auth implementation. Ensure this version is available in your registry and that no breaking changes affect your build.
apps/app/package.json (1)
41-41: Sync frontendnear-sign-verifyto ^0.4.1.Updating to the same version used by your API prevents signature mismatches during the
handleAuthorizestep. Confirm the new package version supports your frontend flow without regressions.apps/api/src/routes/api/index.ts (1)
17-17: MountauthRoutesunder/auth.Importing and routing
authRoutesat/authcorrectly integrates your login, verify, and logout endpoints. Verify that middleware order and path hierarchy don’t interfere with existing routes.Also applies to: 40-40
packages/shared-db/migrations/meta/_journal.json (1)
123-130: Append migration journal entry for0017_loud_lady_vermin.New entry at
idx: 17tracks creation of theauth_requeststable. Please verify that the corresponding SQL file (0017_loud_lady_vermin.sql) and snapshot (0017_snapshot.json) exist and reflect the intended schema changes.packages/shared-db/src/index.ts (1)
18-18: ExportauthRequest.repositoryin shared-db index.Exposing the new
AuthRequestRepositorymakes it available for your API service. Ensure any consumers import it correctly and that unit tests cover its methods.packages/shared-db/src/schema/index.ts (1)
9-9: LGTM! Clean export addition.The auth schema export follows the established pattern and correctly exposes the authentication-related schema definitions.
packages/shared-db/migrations/0017_loud_lady_vermin.sql (1)
1-11: Excellent table design for secure authentication flow.The
auth_requeststable schema demonstrates good security practices:
- Unique constraints on
nonceandstateprevent replay attacks and CSRF- Non-null
expires_atensures proper cleanup of expired requests- Standard audit fields support request tracking
The structure aligns well with OAuth-like authentication patterns.
apps/api/src/services/users.service.ts (1)
49-57: Well-implemented upsert pattern.The
ensureUserProfilemethod cleanly handles both existing and new user scenarios by reusing existing methods. The implementation is concise, follows established patterns, and maintains type safety.apps/api/src/utils/service-provider.ts (1)
3-3: LGTM! Proper import additions for auth functionality.The imports follow the established pattern and bring in the necessary auth-related dependencies.
Also applies to: 15-15
apps/app/src/components/UserMenu.tsx (3)
24-31: Good separation of authentication concerns.The expanded auth context usage cleanly separates sign-in and authorization states, aligning well with the new JWT-based backend flow.
50-67: Excellent conditional rendering for auth states.The progressive authentication flow is well-implemented:
- "Login" for unauthenticated users
- "Authorize App" for signed-in but unauthorized users
- Full user menu for fully authorized users
This provides clear user guidance through the authentication process.
69-124: Clean user menu implementation.The dropdown menu maintains the existing design patterns and functionality while properly integrating with the new authorization state. The conditional rendering and event handling are well-structured.
apps/app/src/contexts/auth-context.tsx (4)
1-22: Well-structured authentication interface with proper separation of concerns.The addition of
isAuthorizedstate and the new authorization methods properly separates NEAR wallet authentication from backend JWT authorization. The promise-based method signatures are appropriate for async operations.
41-43: Good practice: Lazy initialization of authentication state.Initializing states as null/false instead of directly calling NEAR methods prevents potential race conditions and ensures predictable component initialization.
119-137: Excellent error handling in sign-out flow.The implementation correctly prioritizes user experience by ensuring client-side sign-out succeeds even if the backend logout fails. The error is logged for debugging while the user sees a successful logout.
98-101: ```shell
#!/bin/bashSearch for any jsonwebtoken usage and token generation patterns in the backend
echo "=== jsonwebtoken imports ==="
rg "jsonwebtoken" -n apps/apiecho "=== .sign calls (possible token generation) ==="
rg ".sign" -n apps/apiecho "=== expiresIn usages ==="
rg "expiresIn" -n apps/apiecho "=== Environment variables referencing JWT ==="
rg "JWT" -n apps/api</details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
* moderation handle platform_user_id and near account id * standardize activity * fmt * delete tests * fix shared types * activity leaderboard * throw not error * fix services * feat: use tanstack table for leaderboard (#183) * fix: mobile layout improvement feed page (#185) * Refactors create feed flow, steps use router (#188) * wip * feed types * better feed form * Update packages/shared-db/tsconfig.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/settings.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * set lock * nitpicks * fmt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Implements JWT auth flow with 7 day tokens (#187) * better auth services * nit picks * nonce validation * nitpicks * clean up * fix error types * import error * fix auth requests * fix: toast colors not correct (#189) * fix: toast colors not corrent * fmt * fix feed * fix zod type * fix @ and config * fmt --------- Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* moderation handle platform_user_id and near account id * standardize activity * fmt * delete tests * fix shared types * activity leaderboard * throw not error * fix services * feat: use tanstack table for leaderboard (#183) * fix: mobile layout improvement feed page (#185) * Refactors create feed flow, steps use router (#188) * wip * feed types * better feed form * Update packages/shared-db/tsconfig.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/settings.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * set lock * nitpicks * fmt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Implements JWT auth flow with 7 day tokens (#187) * better auth services * nit picks * nonce validation * nitpicks * clean up * fix error types * import error * fix auth requests * fix: toast colors not correct (#189) * fix: toast colors not corrent * fmt * fix feed * fix zod type * fix @ and config * fmt * feat: add settings page UI * feat: add route based tab navigation * feat: welcome route for new feed (#192) * feat: welcome route for new feed * fix: feed overflow in top feeds column of leaderboard * fix: coderabbit comments * moderate submissions * fmt * fmt --------- Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* moderation handle platform_user_id and near account id * standardize activity * fmt * delete tests * fix shared types * activity leaderboard * throw not error * fix services * feat: use tanstack table for leaderboard (#183) * fix: mobile layout improvement feed page (#185) * Refactors create feed flow, steps use router (#188) * wip * feed types * better feed form * Update packages/shared-db/tsconfig.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/settings.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * set lock * nitpicks * fmt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Implements JWT auth flow with 7 day tokens (#187) * better auth services * nit picks * nonce validation * nitpicks * clean up * fix error types * import error * fix auth requests * fix: toast colors not correct (#189) * fix: toast colors not corrent * fmt * fix feed * fix zod type * fix @ and config * fmt * feat: add settings page UI * feat: add route based tab navigation * feat: welcome route for new feed (#192) * feat: welcome route for new feed * fix: feed overflow in top feeds column of leaderboard * fix: coderabbit comments * moderate submissions * fmt * fmt * adds auto approval * auto approval * upgrade fastintear * fix auth flow * upgrade packages * nitpicks * Introduces worker service w/ queues, enables auto-approval (#196) * init * clean up * fmt * build fixes * init * running * working auto approval * init * clean up * fmt * build fixes * init * running * working auto approval * clean up * nitpicks * update pnpm lock * add @roamhq/wrtc * docker and type module * agent-twitter-client * add rspack * REDIS_URL * bullmq workaround * clean config * fix auth flow * same flow * logger * better logger * railway logger --------- Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Uses near-sign-verify
Summary by CodeRabbit