Skip to content

fix: ensure usesr profile request does not error in case of 401#2490

Merged
stalniy merged 1 commit intomainfrom
fix/user-unauthenticated
Jan 14, 2026
Merged

fix: ensure usesr profile request does not error in case of 401#2490
stalniy merged 1 commit intomainfrom
fix/user-unauthenticated

Conversation

@stalniy
Copy link
Contributor

@stalniy stalniy commented Jan 14, 2026

Why

To improve auth flow UX and reduce amount of sentry errors

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of expired authentication tokens with automatic redirect to the login page.
  • Improvements

    • Refined session and authentication checks for more reliable access to protected pages.
    • Updated runtime authentication configuration.
  • Improvements

    • Enhanced server-side resilience with automatic retries for transient failures.

✏️ Tip: You can customize this high-level summary in your review settings.

@stalniy stalniy requested a review from a team as a code owner January 14, 2026 05:51
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

Refactors authentication/session handling to use service-based lazy session retrieval (getCurrentSession()), replaces withCustomPageAuthRequired wrappers with redirectIfAccessTokenExpired guards, routes login via UrlService.newLogin(), adds QueryClient 5xx retry logic, and updates related tests and pages.

Changes

Cohort / File(s) Change Summary
Environment & Configuration
apps/deploy-web/env/.env
Added NEXT_PUBLIC_AUTH0_LOGIN=/login runtime env var
Client redirect flow
apps/deploy-web/src/components/user/RequiredUserContainer.tsx
Replaced hard-coded "/404" redirect with urlService.newLogin() via useServices
UserProviders (impl & tests)
apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx, .../UserProviders.spec.tsx
Introduced memoized getProfile (useCallback) with 401 handling; adjusted tests to mock unauthenticated flow and AxiosResponse shapes
Server-side session API & types
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts, .../defineServerSideProps.spec.ts
Replaced context.session with `context.getCurrentSession(): Promise<Session
Page guards (impl & tests)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts, .../pageGuards.spec.ts
isFeatureEnabled/isAuthenticated now call getCurrentSession(); redirectIfAccessTokenExpired is async, returns {redirect} or true, uses structured logging and resolvedUrl
Page migrations
apps/deploy-web/src/pages/payment.tsx, apps/deploy-web/src/pages/user/settings/index.tsx, apps/deploy-web/src/pages/user/settings/favorites/index.tsx
Replaced withCustomPageAuthRequired wrappers with defineServerSideProps({ if: redirectIfAccessTokenExpired, route: ... })
Auth API handler
apps/deploy-web/src/pages/api/auth/[...auth0].ts
Switched from module-level getSession(req,res) to services.getSession(req,res) in AUTH_PROFILE handling
DI / QueryClient config
apps/deploy-web/src/services/app-di-container/app-di-container.ts
Added QueryClient retry policy: retry on HTTP errors with status >=500 up to 3 times
Removed utility
apps/deploy-web/src/utils/withCustomPageAuthRequired.ts
Deleted HOC that previously handled server-side session retrieval and redirect-on-expiry logic

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant NextJS_Page as Next.js (getServerSideProps)
  participant DefineSSP as defineServerSideProps
  participant AppServices as Services.getSession
  participant PageGuard as redirectIfAccessTokenExpired
  participant UrlService

  Browser->>NextJS_Page: Request page
  NextJS_Page->>DefineSSP: invoke defineServerSideProps
  DefineSSP->>AppServices: getCurrentSession() (lazy)
  AppServices-->>DefineSSP: Session|null
  DefineSSP->>PageGuard: check accessToken expiry
  alt token expired
    PageGuard->>UrlService: newLogin(resolvedUrl)
    PageGuard-->>NextJS_Page: { redirect: loginUrl }
  else token valid
    PageGuard-->>NextJS_Page: true (allow)
  end
  NextJS_Page-->>Browser: redirect or render page
Loading
sequenceDiagram
  participant Client as Browser (client-side)
  participant RequiredContainer
  participant Services as UrlService
  participant Router

  Client->>RequiredContainer: renders
  RequiredContainer->>Services: resolve urlService.newLogin()
  alt user not authenticated
    RequiredContainer->>Router: router.push(newLoginUrl)
  else authenticated
    RequiredContainer-->>Client: render children
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • ygrishajev
  • baktun14

Poem

🐰 I hop to guard the session door,
Services fetched, no wrappers more.
Tokens checked, redirects in tune,
UrlService hums a login tune. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title contains a typo ('usesr' instead of 'user') and describes the main objective of the PR—handling 401 errors gracefully in the user profile request to reduce Sentry errors.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 14, 2026

Codecov Report

❌ Patch coverage is 51.51515% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.70%. Comparing base (5b68e84) to head (e6f7bbc).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...-web/src/components/user/RequiredUserContainer.tsx 0.00% 3 Missing ⚠️
...tjs/defineServerSideProps/defineServerSideProps.ts 40.00% 3 Missing ⚠️
apps/deploy-web/src/pages/api/auth/[...auth0].ts 0.00% 2 Missing ⚠️
apps/deploy-web/src/pages/payment.tsx 0.00% 2 Missing ⚠️
...oy-web/src/pages/user/settings/favorites/index.tsx 0.00% 2 Missing ⚠️
apps/deploy-web/src/pages/user/settings/index.tsx 0.00% 2 Missing ⚠️
.../src/services/app-di-container/app-di-container.ts 0.00% 2 Missing ⚠️

❌ Your project status has failed because the head coverage (79.59%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2490      +/-   ##
==========================================
- Coverage   50.97%   50.70%   -0.28%     
==========================================
  Files        1066     1055      -11     
  Lines       29459    29109     -350     
  Branches     6535     6489      -46     
==========================================
- Hits        15018    14760     -258     
+ Misses      14095    13949     -146     
- Partials      346      400      +54     
Flag Coverage Δ *Carryforward flag
api 79.59% <ø> (ø) Carriedforward from 5b68e84
deploy-web 31.42% <51.51%> (+0.02%) ⬆️
log-collector ?
notifications 87.94% <ø> (ø) Carriedforward from 5b68e84
provider-console 81.48% <ø> (ø) Carriedforward from 5b68e84
provider-proxy 84.35% <ø> (ø) Carriedforward from 5b68e84

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...rc/components/user/UserProviders/UserProviders.tsx 100.00% <100.00%> (ø)
...deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/pages/api/auth/[...auth0].ts 0.00% <0.00%> (ø)
apps/deploy-web/src/pages/payment.tsx 0.00% <0.00%> (ø)
...oy-web/src/pages/user/settings/favorites/index.tsx 0.00% <0.00%> (ø)
apps/deploy-web/src/pages/user/settings/index.tsx 0.00% <0.00%> (ø)
.../src/services/app-di-container/app-di-container.ts 74.16% <0.00%> (-1.26%) ⬇️
...-web/src/components/user/RequiredUserContainer.tsx 0.00% <0.00%> (ø)
...tjs/defineServerSideProps/defineServerSideProps.ts 90.62% <40.00%> (-9.38%) ⬇️

... and 59 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts (1)

67-71: Unit mismatch: accessTokenExpiresAt should be in seconds, not milliseconds.

The accessTokenExpiresAt value at line 69 is in milliseconds (Date.now() + 1000 * 60 * 60 * 24 * 30), but the implementation at pageGuards.ts line 17 multiplies by 1000, expecting the value to be in seconds. This test passes by accident because the value is so large it remains in the future, but it's inconsistent with the expired token test at line 81 which correctly uses seconds.

🐛 Proposed fix
     it("returns true when access token is not expired", async () => {
       const context = setup({
         session: {
-          accessTokenExpiresAt: Date.now() + 1000 * 60 * 60 * 24 * 30
+          accessTokenExpiresAt: (Date.now() + 1000 * 60 * 60 * 24 * 30) / 1000
         }
       });
🤖 Fix all issues with AI agents
In `@apps/deploy-web/src/components/user/RequiredUserContainer.tsx`:
- Around line 25-29: The useEffect in RequiredUserContainer uses
urlService.newLogin() but urlService is not listed in the dependency array,
violating exhaustive-deps; update the effect dependencies to include urlService
(i.e., change the dependency array from [user, isLoading, router] to [user,
isLoading, router, urlService]) so React correctly re-runs the effect when
urlService changes and remove the lint warning.

In `@apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx`:
- Around line 58-79: The mock for getProfile is returning { status: 401 } which
becomes { data: { status: 401 } } inside setup, so response.status is undefined
and the 401 branch in the real getProfile logic is never exercised; fix by
making test mocks return a full axios-like response shape (e.g.,
Promise.resolve({ status: 401, data: {} })) so getProfile sees response.status
at the top level, and update all other tests that mock getProfile in this file
(and any shared setup helpers) to return the same full response shape;
alternatively, if you prefer changing the helper, update setup to detect and
normalize nested data.status into a top-level status before passing to
useUser/getProfile.
🧹 Nitpick comments (2)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)

19-19: Consider using a more specific type instead of any.

The if option uses GetServerSidePropsResult<any> which violates the coding guidelines that discourage any usage. Consider using a generic type parameter or unknown to maintain type safety.

💡 Suggested improvement
-  if?: (context: AppTypedContext<TSchema, TParams, TPreviewData>) => boolean | GetServerSidePropsResult<any> | Promise<GetServerSidePropsResult<any> | boolean>;
+  if?: (context: AppTypedContext<TSchema, TParams, TPreviewData>) => boolean | GetServerSidePropsResult<TProps> | Promise<GetServerSidePropsResult<TProps> | boolean>;
apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx (1)

15-22: Consider handling other 4xx status codes.

The validateStatus allows all status codes < 500 to pass without throwing, but only 401 is explicitly handled. If other client errors occur (403, 404, etc.), response.data would be returned and might be an error object rather than valid user profile data, potentially causing issues downstream.

If only 401 is expected in practice, this is fine. Otherwise, consider narrowing the check:

♻️ Suggested refinement
 const getProfile = useCallback(
   async (url: string) => {
-    const response = await internalApiHttpClient.get(url, { validateStatus: status => status < 500 });
-    if (response.status === 401) return;
+    const response = await internalApiHttpClient.get(url, { validateStatus: status => status < 400 || status === 401 });
+    if (response.status === 401) return;
     return response.data;
   },
   [internalApiHttpClient]
 );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b68e84 and 210f169.

📒 Files selected for processing (14)
  • apps/deploy-web/env/.env
  • apps/deploy-web/src/components/user/RequiredUserContainer.tsx
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.spec.ts
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/pages/user/settings/favorites/index.tsx
  • apps/deploy-web/src/pages/user/settings/index.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/utils/withCustomPageAuthRequired.ts
💤 Files with no reviewable changes (2)
  • apps/deploy-web/src/utils/withCustomPageAuthRequired.ts
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.spec.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts
  • apps/deploy-web/src/pages/user/settings/index.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/components/user/RequiredUserContainer.tsx
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx
  • apps/deploy-web/src/pages/user/settings/favorites/index.tsx
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use setup function instead of beforeEach in unit and service level tests

Files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
🧠 Learnings (8)
📚 Learning: 2025-08-12T13:52:38.708Z
Learnt from: stalniy
Repo: akash-network/console PR: 1800
File: apps/deploy-web/next.config.js:163-165
Timestamp: 2025-08-12T13:52:38.708Z
Learning: In the Akash Console project, akashnetwork/env-loader is used at the top of next.config.js files to automatically load environment variables from env/.env files into process.env. SENTRY_ORG and SENTRY_PROJECT are stored as public configuration values in apps/deploy-web/env/.env and are loaded this way, while only SENTRY_AUTH_TOKEN is handled as a GitHub secret in workflows.

Applied to files:

  • apps/deploy-web/env/.env
📚 Learning: 2025-08-12T13:52:38.708Z
Learnt from: stalniy
Repo: akash-network/console PR: 1800
File: apps/deploy-web/next.config.js:163-165
Timestamp: 2025-08-12T13:52:38.708Z
Learning: In the Akash Console project, SENTRY_ORG and SENTRY_PROJECT are stored as public configuration values in apps/deploy-web/env/.env file and loaded by akashnetwork/env-loader, not as GitHub secrets. Only SENTRY_AUTH_TOKEN should be handled as a secret.

Applied to files:

  • apps/deploy-web/env/.env
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2026-01-13T17:40:26.436Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T17:40:26.436Z
Learning: Applies to **/*.{test,spec}.{ts,tsx,js,jsx} : Use `setup` function instead of `beforeEach` in unit and service level tests

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
🧬 Code graph analysis (7)
apps/deploy-web/src/pages/payment.tsx (8)
apps/deploy-web/src/pages/user/settings/index.tsx (1)
  • getServerSideProps (12-15)
apps/deploy-web/src/pages/profile/[username]/index.tsx (1)
  • getServerSideProps (19-38)
apps/deploy-web/src/pages/template/[id]/index.tsx (1)
  • getServerSideProps (19-49)
apps/deploy-web/src/pages/providers/[owner]/index.tsx (1)
  • getServerSideProps (19-40)
apps/deploy-web/src/pages/alerts/index.tsx (1)
  • getServerSideProps (8-11)
apps/deploy-web/src/pages/deployments/[dseq]/index.tsx (1)
  • getServerSideProps (8-22)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • defineServerSideProps (43-94)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • redirectIfAccessTokenExpired (15-34)
apps/deploy-web/src/pages/api/auth/[...auth0].ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (2)
apps/api/src/core/services/execution-context/execution-context.service.ts (1)
  • context (18-26)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • AppTypedContext (23-30)
apps/deploy-web/src/components/user/RequiredUserContainer.tsx (1)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (33-35)
apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx (4)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (6-20)
apps/deploy-web/src/types/user.ts (1)
  • CustomUserProfile (19-19)
apps/deploy-web/src/services/user-tracker/user-tracker.service.ts (1)
  • UserTracker (5-19)
apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx (1)
  • UserProviders (13-30)
apps/deploy-web/src/pages/user/settings/favorites/index.tsx (3)
apps/deploy-web/src/pages/payment.tsx (1)
  • getServerSideProps (345-348)
apps/deploy-web/src/pages/user/settings/index.tsx (1)
  • getServerSideProps (12-15)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • redirectIfAccessTokenExpired (15-34)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
apps/api/src/core/services/execution-context/execution-context.service.ts (1)
  • context (18-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (16)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (2)

53-57: Good use of once for lazy session evaluation.

The once wrapper from lodash ensures that session retrieval is memoized per request, preventing redundant calls when multiple guards or handlers access the session. This is an efficient pattern for request-scoped caching.


72-74: Guard result handling logic is correct.

The conditional check properly handles the three expected return types from the if guard:

  • Object results (redirects, notFound) are returned directly
  • false returns NOT_FOUND
  • true or undefined continues to handler
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (2)

15-33: Return type change from null to true aligns well with the guard pattern.

The updated return type Promise<{ redirect: Redirect } | true> is cleaner and more semantically meaningful than returning null for the success case. The defineServerSideProps handler correctly interprets true to continue processing.


16-17: Session null handling defaults to expired token correctly.

When session is null, the fallback (session?.accessTokenExpiresAt || 0) * 1_000 correctly results in epoch time (Jan 1, 1970), which will always be less than new Date(). This ensures unauthenticated users are redirected to login, which is the expected behavior.

apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts (1)

97-107: Test setup follows coding guidelines correctly.

The setup function is positioned at the bottom of the root describe block, uses jest-mock-extended for mocking, accepts a single parameter with inline type definition, and avoids shared state. The mock for getCurrentSession correctly returns a Promise.

Based on learnings, this follows the required pattern.

apps/deploy-web/src/pages/payment.tsx (1)

345-348: Clean migration to the new authentication guard pattern.

The replacement of withCustomPageAuthRequired with defineServerSideProps using the redirectIfAccessTokenExpired guard is consistent with the PR's objective. This approach provides better error handling for 401 responses and reduces unnecessary Sentry errors.

apps/deploy-web/src/pages/user/settings/favorites/index.tsx (1)

11-14: Consistent implementation of the new auth guard pattern.

The migration follows the same pattern established in other pages (payment.tsx, user/settings/index.tsx). The route string correctly reflects the page path.

apps/deploy-web/src/pages/user/settings/index.tsx (2)

4-4: LGTM!

Clean import of the new guard function that aligns with the refactored authentication pattern.


12-15: LGTM!

The declarative approach using defineServerSideProps with the redirectIfAccessTokenExpired guard cleanly handles the authentication check. This aligns well with the PR objective of gracefully handling 401 responses without producing errors.

apps/deploy-web/src/components/user/RequiredUserContainer.tsx (1)

6-6: LGTM!

The import and usage of useServices to retrieve urlService is correct and aligns with the service-based architecture pattern in the codebase.

Also applies to: 23-23

apps/deploy-web/env/.env (1)

37-37: ✓ LGTM! New login path configuration aligns with the updated auth flow.

The addition of NEXT_PUBLIC_AUTH0_LOGIN provides a configurable login path for client-side redirects, which aligns with the PR's goal of improving the authentication flow user experience. The /login route is properly defined at pages/login/index.tsx and is actively used throughout the codebase via the urlService.newLogin() method.

apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx (1)

81-99: Setup function structure follows project conventions.

The setup function is properly positioned at the bottom of the describe block, accepts a single parameter with inline type definition, and avoids shared state. The Content parameter extension allows flexible testing of child component behavior.

apps/deploy-web/src/services/app-di-container/app-di-container.ts (2)

162-168: Good retry policy for server errors.

The retry logic correctly limits retries to HTTP 5xx errors only, avoiding unnecessary retries for client errors (4xx including 401). This aligns well with the PR objective of reducing Sentry noise from authentication failures while maintaining resilience against transient server issues.

Note: With failureCount < 3, queries will make up to 3 total attempts (original request + 2 retries).


7-7: LGTM on the import addition.

The isHttpError import is appropriately added to support the new retry logic and is correctly exported from @akashnetwork/http-sdk.

apps/deploy-web/src/pages/api/auth/[...auth0].ts (2)

8-8: LGTM on import refactoring.

Correctly removed direct getSession import since it's now accessed via the services container, maintaining only the error types needed locally.


74-74: Proper migration to service-based session retrieval.

The change from direct getSession(req, res) to services.getSession(req, res) aligns with the centralized DI pattern shown in server-di-container.service.ts where getSession: () => getSession is registered. This improves testability and maintains consistency with the broader architectural refactoring in this PR.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@stalniy stalniy force-pushed the fix/user-unauthenticated branch from 210f169 to e6f7bbc Compare January 14, 2026 07:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx`:
- Around line 62-65: The AxiosResponse generic is incorrect: change
AxiosResponse<{ data: CustomUserProfile } | undefined> to
AxiosResponse<CustomUserProfile | undefined> so mocks reflect that getProfile
returns response.data (the CustomUserProfile). Update the test/mock where
Promise.resolve(...) is used and also adjust the test helper/setup function
signature (the setup function referenced in the spec) to accept/expect
CustomUserProfile | undefined instead of the nested shape so types align with
getProfile and the Axios mock.
🧹 Nitpick comments (1)
apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx (1)

94-96: Default mock missing status property for consistency.

Other mocks (lines 33-34, 62-65) include the status property, but the default fallback doesn't. This inconsistency could cause unexpected behavior if a test relies on the default and the implementation checks response.status.

🔧 Proposed fix
             if (input?.getProfile) return input.getProfile();
             return Promise.resolve({
+              status: 200,
               data: buildUser()
             });
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 210f169 and e6f7bbc.

📒 Files selected for processing (14)
  • apps/deploy-web/env/.env
  • apps/deploy-web/src/components/user/RequiredUserContainer.tsx
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.spec.ts
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/pages/user/settings/favorites/index.tsx
  • apps/deploy-web/src/pages/user/settings/index.tsx
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/utils/withCustomPageAuthRequired.ts
💤 Files with no reviewable changes (2)
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.spec.ts
  • apps/deploy-web/src/utils/withCustomPageAuthRequired.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/deploy-web/src/pages/user/settings/index.tsx
  • apps/deploy-web/env/.env
  • apps/deploy-web/src/services/app-di-container/app-di-container.ts
  • apps/deploy-web/src/components/user/RequiredUserContainer.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{ts,tsx,js}: Never use type any or cast to type any. Always define the proper TypeScript types.
Never use deprecated methods from libraries.
Don't add unnecessary comments to the code.

Files:

  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts
  • apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts
  • apps/deploy-web/src/pages/payment.tsx
  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
  • apps/deploy-web/src/pages/user/settings/favorites/index.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test

Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

**/*.spec.{ts,tsx}: Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references
Use either a method name or a condition starting with 'when' for nested suite descriptions in tests
Use present simple, 3rd person singular for test descriptions without prepending 'should'

Files:

  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use setup function instead of beforeEach in unit and service level tests

Files:

  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
{apps/deploy-web,apps/provider-console}/**/*.spec.tsx

📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)

Use queryBy methods instead of getBy methods in test expectations

Files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
🧠 Learnings (6)
📚 Learning: 2025-11-25T17:45:49.180Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-11-25T17:45:49.180Z
Learning: Applies to {apps/deploy-web,apps/provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations

Applied to files:

  • apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts
  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2025-07-11T10:46:43.711Z
Learnt from: stalniy
Repo: akash-network/console PR: 1660
File: apps/deploy-web/src/components/alerts/DeploymentAlertsContainer/DeploymentAlertsContainer.spec.tsx:54-56
Timestamp: 2025-07-11T10:46:43.711Z
Learning: In apps/{deploy-web,provider-console}/**/*.spec.tsx files: Use `getBy` methods instead of `queryBy` methods when testing element presence with `toBeInTheDocument()` because `getBy` throws an error and shows DOM state when element is not found, providing better debugging information than `queryBy` which returns null.

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2025-11-25T17:45:44.790Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-11-25T17:45:44.790Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2025-11-19T15:15:07.283Z
Learnt from: ygrishajev
Repo: akash-network/console PR: 2254
File: apps/api/test/functional/sign-and-broadcast-tx.spec.ts:4-4
Timestamp: 2025-11-19T15:15:07.283Z
Learning: In the Akash Network Console project, when tests use native Node.js fetch (available in Node 18+), fetch-mock should be used for HTTP mocking instead of nock, as nock does not support intercepting native fetch calls. This applies to apps/api/test/functional/sign-and-broadcast-tx.spec.ts and any other tests using native fetch.

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2026-01-13T17:40:26.436Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T17:40:26.436Z
Learning: Applies to **/*.{test,spec}.{ts,tsx,js,jsx} : Use `setup` function instead of `beforeEach` in unit and service level tests

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
📚 Learning: 2025-11-25T17:45:52.965Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-11-25T17:45:52.965Z
Learning: Applies to **/*.spec.{ts,tsx} : Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

Applied to files:

  • apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx
🧬 Code graph analysis (4)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (2)
apps/api/src/core/services/execution-context/execution-context.service.ts (1)
  • context (18-26)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • AppTypedContext (23-30)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
apps/api/src/core/services/execution-context/execution-context.service.ts (1)
  • context (18-26)
apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx (3)
apps/deploy-web/src/types/user.ts (1)
  • CustomUserProfile (19-19)
apps/deploy-web/src/hooks/useUser.ts (1)
  • useUser (6-20)
apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx (1)
  • UserProviders (13-30)
apps/deploy-web/src/pages/user/settings/favorites/index.tsx (4)
apps/deploy-web/src/pages/payment.tsx (1)
  • getServerSideProps (345-348)
apps/deploy-web/src/pages/user/settings/index.tsx (1)
  • getServerSideProps (12-15)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • defineServerSideProps (43-94)
apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)
  • redirectIfAccessTokenExpired (15-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (12)
apps/deploy-web/src/pages/api/auth/[...auth0].ts (2)

7-9: LGTM!

The import change correctly removes the direct getSession import while retaining AccessTokenError and AccessTokenErrorCode which are still needed for the isInvalidSessionError function.


71-79: LGTM!

The switch to services.getSession(req, res) aligns well with the DI pattern used throughout the codebase. The subsequent null check gracefully handles unauthenticated users by returning a clean 401 JSON response rather than throwing an error, which addresses the PR objective of reducing Sentry noise for expected unauthenticated states.

apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.spec.ts (2)

66-76: LGTM!

The test correctly verifies that redirectIfAccessTokenExpired returns true when the access token is not expired, aligning with the updated function signature that returns Promise<{ redirect: Redirect } | true>.


97-107: LGTM!

The setup function follows the coding guidelines: placed at the bottom of the root describe block, accepts a single parameter with an inline type definition, uses jest-mock-extended for mocking, and avoids shared state.

apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (2)

53-57: LGTM!

Using once() to wrap getCurrentSession is a good pattern for lazy evaluation and memoization. This ensures the session is fetched only once per request, even if multiple guards or handlers call getCurrentSession().


19-19: LGTM!

The updated if signature correctly supports both synchronous and asynchronous guards that can return boolean or GetServerSidePropsResult (for redirects/not-found responses).

apps/deploy-web/src/lib/nextjs/pageGuards/pageGuards.ts (1)

15-34: LGTM!

The refactored redirectIfAccessTokenExpired correctly handles the authentication flow:

  • Returns true for valid sessions, allowing the request to proceed
  • Returns a redirect object for expired/missing sessions
  • Properly converts accessTokenExpiresAt from seconds to milliseconds
  • Uses structured logging for better observability

The distinction between context.req.url (for logging the raw request) and context.resolvedUrl (for the redirect destination with resolved dynamic routes) is appropriate.

apps/deploy-web/src/pages/payment.tsx (1)

345-348: LGTM!

Clean migration from withCustomPageAuthRequired to the new defineServerSideProps pattern with redirectIfAccessTokenExpired guard. This aligns with the PR's goal of improving 401 handling.

apps/deploy-web/src/pages/user/settings/favorites/index.tsx (1)

11-14: LGTM!

Consistent application of the new defineServerSideProps pattern with redirectIfAccessTokenExpired guard, matching the approach used in other pages in this PR.

apps/deploy-web/src/components/user/UserProviders/UserProviders.tsx (1)

15-22: Clean implementation for graceful 401 handling.

The validateStatus callback ensures Axios won't throw for 4xx responses, and returning undefined on 401 allows the Auth0 UserProvider to handle the unauthenticated state without triggering an error. The useCallback memoization with the correct dependency is appropriate.

apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx (2)

59-81: Good test coverage for 401 handling.

This test validates the core PR objective by confirming that a 401 response results in user being undefined without triggering an error state. The use of a custom Content component to inspect useUser state is a clean approach.


31-34: Mock shape now correctly simulates Axios responses.

The mocks properly return full response objects with status and data properties, ensuring the 401 handling logic in getProfile is correctly exercised.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +62 to +65
Promise.resolve({
status: 401,
data: undefined
} as AxiosResponse<{ data: CustomUserProfile } | undefined>)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incorrect generic type for AxiosResponse.

The type AxiosResponse<{ data: CustomUserProfile } | undefined> suggests response.data.data would contain the user profile. However, getProfile returns response.data directly (the CustomUserProfile), not a nested structure.

🔧 Proposed fix
       getProfile: jest.fn(() =>
         Promise.resolve({
           status: 401,
           data: undefined
-        } as AxiosResponse<{ data: CustomUserProfile } | undefined>)
+        } as AxiosResponse<CustomUserProfile | undefined>)
       ),

Also update the setup function signature at line 84:

   async function setup(input?: {
-    getProfile?: () => Promise<AxiosResponse<{ data: CustomUserProfile } | undefined>>;
+    getProfile?: () => Promise<AxiosResponse<CustomUserProfile | undefined>>;
     userTracker?: UserTracker;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Promise.resolve({
status: 401,
data: undefined
} as AxiosResponse<{ data: CustomUserProfile } | undefined>)
Promise.resolve({
status: 401,
data: undefined
} as AxiosResponse<CustomUserProfile | undefined>)
🤖 Prompt for AI Agents
In `@apps/deploy-web/src/components/user/UserProviders/UserProviders.spec.tsx`
around lines 62 - 65, The AxiosResponse generic is incorrect: change
AxiosResponse<{ data: CustomUserProfile } | undefined> to
AxiosResponse<CustomUserProfile | undefined> so mocks reflect that getProfile
returns response.data (the CustomUserProfile). Update the test/mock where
Promise.resolve(...) is used and also adjust the test helper/setup function
signature (the setup function referenced in the spec) to accept/expect
CustomUserProfile | undefined instead of the nested shape so types align with
getProfile and the Axios mock.

@stalniy stalniy merged commit 64b704e into main Jan 14, 2026
64 of 65 checks passed
@stalniy stalniy deleted the fix/user-unauthenticated branch January 14, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments