Skip to content

feat: adds turnstile to deploy-web auth pages#2421

Merged
stalniy merged 4 commits intomainfrom
feat/adds-turnstile-to-auth-pages
Dec 29, 2025
Merged

feat: adds turnstile to deploy-web auth pages#2421
stalniy merged 4 commits intomainfrom
feat/adds-turnstile-to-auth-pages

Conversation

@stalniy
Copy link
Contributor

@stalniy stalniy commented Dec 26, 2025

Why

ref #2400

What

Screen.Recording.2025-12-26.at.17.20.37.mov

Summary by CodeRabbit

  • New Features

    • Turnstile CAPTCHA added across auth flows (client widget + server-side verification); captcha token required for sign-in, sign-up, and password reset. New environment variables for Turnstile and E2E testing included.
  • Bug Fixes / Improvements

    • API routes enforce HTTP methods; server components now read private configuration; E2E runner requires a testing-client token header when not running on localhost.
  • Tests

    • Tests and E2E fixtures updated to mock Turnstile flows and simplify injected-config handling.
  • Chores

    • Removed legacy injected-config signing/startup hook.

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

@stalniy stalniy requested a review from a team as a code owner December 26, 2025 16:17
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 26, 2025

📝 Walkthrough

Walkthrough

Adds Cloudflare Turnstile client widget + server verifier, enforces captchaToken on auth endpoints and service methods, moves server-side config reads to privateConfig, removes signed injected-config flow, and updates tests and Playwright to support an E2E testing token.

Changes

Cohort / File(s) Summary
Environment & Playwright
apps/deploy-web/env/.env.sample, apps/deploy-web/src/config/env-config.schema.ts, apps/deploy-web/playwright.config.ts
Added Turnstile env vars and E2E_TESTING_CLIENT_TOKEN; schema gains TURNSTILE_SECRET_KEY, TURNSTILE_BYPASS_SECRET_KEY, E2E_TESTING_CLIENT_TOKEN; Playwright requires token and sets X-Testing-Client-Token header.
Turnstile component & tests
apps/deploy-web/src/components/turnstile/Turnstile.tsx, apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx, apps/deploy-web/src/components/turnstile/*
Turnstile now forwards a ref (TurnstileRef) exposing renderAndWaitResponse(), adds onSuccess/onError/onDismissed, event bus, imperative API; tests adapted to drive widget via ref and to assert success/error/dismiss flows.
Turnstile verifier service & tests
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts, .../turnstile-verifier.service.spec.ts
New TurnstileVerifierService posts to Cloudflare verify endpoint, supports remoteIp and bypass-secret behavior; unit tests cover success, failure, and bypass paths.
Auth UI & tests
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx, .../AuthPage.spec.tsx, apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx
AuthPage integrates ClientOnlyTurnstile and uses turnstileRef to obtain captchaToken for sign-in/signup/forgot-password flows; tests wired to TurnstileMock; minor UI/link tweaks.
Auth APIs (captcha enforcement)
apps/deploy-web/src/pages/api/auth/password-login.ts, .../password-signup.ts, .../send-password-reset-email.ts
Added method: "POST" to handlers, extended body schemas with captchaToken, invoked verifyCaptcha(...) before proceeding, and switched handlers to single ctx param.
Auth service signatures
apps/deploy-web/src/services/auth/auth/auth.service.ts
login, signup, and sendPasswordResetEmail signatures updated to accept captchaToken and forward it to APIs.
verifyCaptcha middleware & tests
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts, .../verify-captcha.spec.ts
New verifyCaptcha(captchaToken, { services, req }) deriving remote IP, delegating to services.captchaVerifier.verify, returning Ok/Err and logging failures; comprehensive tests added.
DI container & config migration
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
Added privateConfig provider and captchaVerifier service wired to Turnstile verifier; many server reads moved from config to privateConfig.
OAuth, proxy & page config reads
apps/deploy-web/src/pages/api/*, apps/deploy-web/src/pages/profile/*, apps/deploy-web/src/pages/template/*, apps/deploy-web/src/pages/api/proxy/[...path].ts
Switched configuration sources from services.config to services.privateConfig for client IDs, secrets, redirect URIs, and network IDs.
Injected config removal & replacement
apps/deploy-web/src/hooks/useInjectedConfig.ts (deleted), apps/deploy-web/src/services/decodeInjectedConfig/* (deleted), apps/deploy-web/src/pages/_app.tsx, apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
Removed signed injected-config decoding and hook; _app no longer waits for injected config or client Turnstile; added simple getInjectedConfig() util returning window value.
E2E/test fixture updates
apps/deploy-web/tests/ui/fixture/base-test.ts, apps/deploy-web/tests/ui/fixture/test-env.config.ts, apps/deploy-web/tests/ui/fixture/*
Removed dynamic signing in fixtures; injectUIConfig simplified to injecting a frozen config with NEXT_PUBLIC_TURNSTILE_SITE_KEY; test env schema no longer requires UI signature private key; exported expect.
Misc tests / typing tweaks
apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx, apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts, others
Typing and mock adjustments, minor test refactors, and type assertion fixes.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as User
    participant AuthUI as AuthPage (client)
    participant Turnstile as Turnstile widget
    participant API as Password API (server)
    participant Verifier as CaptchaVerifier (service)
    participant CF as Cloudflare Turnstile

    User->>AuthUI: Click Sign In / Sign Up
    AuthUI->>Turnstile: renderAndWaitResponse()
    Turnstile->>CF: widget loads & user completes captcha
    CF-->>Turnstile: returns token
    Turnstile-->>AuthUI: resolves token
    AuthUI->>API: POST /password-login or /password-signup {..., captchaToken}
    API->>Verifier: verifyCaptcha(captchaToken, ctx)
    Verifier->>CF: POST /siteverify {secret, response, remoteip?}
    CF-->>Verifier: {success: boolean, error-codes?}
    alt success
        Verifier-->>API: Ok
        API->>Auth Service: proceed with auth (login/signup)
        API-->>AuthUI: 200 / set-cookie
    else failure
        Verifier-->>API: Err
        API-->>AuthUI: 400 (captcha failure)
    end
Loading
sequenceDiagram
    autonumber
    participant User as User
    participant AuthUI as AuthPage
    participant Form as ForgotPasswordForm
    participant Turnstile as Turnstile widget
    participant API as SendPasswordResetEmail API
    participant Verifier as CaptchaVerifier
    participant CF as Cloudflare Turnstile

    User->>AuthUI: Select "Forgot password"
    AuthUI->>Form: show forgot view
    User->>Turnstile: complete captcha
    Turnstile-->>Form: token
    Form->>API: POST /send-password-reset-email {email, captchaToken}
    API->>Verifier: verifyCaptcha(...)
    Verifier->>CF: POST /siteverify {secret, response, remoteip?}
    CF-->>Verifier: {success: boolean, error-codes?}
    alt verified
        API->>Service: send reset email
        API-->>Form: 204 No Content
    else failed
        API-->>Form: 400 (captcha verification failed)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • ygrishajev
  • baktun14

Poem

🐰 I hopped to the widget, quick and spry,
Tokens gathered from cloud up high,
Secrets kept safe in private land,
Verifier nods — auth goes as planned,
I nibble a carrot with a sigh. 🥕

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: adds turnstile to deploy-web auth pages' directly and accurately summarizes the main change across the changeset: integrating Cloudflare Turnstile CAPTCHA into authentication pages.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/adds-turnstile-to-auth-pages

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

@codecov
Copy link

codecov bot commented Dec 26, 2025

Codecov Report

❌ Patch coverage is 63.19444% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.96%. Comparing base (b771771) to head (df6ee7b).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ps/deploy-web/src/pages/api/auth/password-login.ts 0.00% 8 Missing ⚠️
...s/deploy-web/src/pages/api/auth/password-signup.ts 0.00% 8 Missing ⚠️
...eb/src/pages/api/auth/send-password-reset-email.ts 0.00% 8 Missing ⚠️
...s/turnstile-verifier/turnstile-verifier.service.ts 72.00% 7 Missing ⚠️
.../deploy-web/src/components/turnstile/Turnstile.tsx 90.24% 4 Missing ⚠️
apps/deploy-web/src/pages/api/auth/[...auth0].ts 0.00% 4 Missing ⚠️
apps/deploy-web/src/pages/api/auth/signup.ts 0.00% 3 Missing ⚠️
.../deploy-web/src/services/auth/auth/auth.service.ts 0.00% 3 Missing ⚠️
...ploy-web/src/components/auth/AuthPage/AuthPage.tsx 88.23% 2 Missing ⚠️
...rc/lib/nextjs/defineApiHandler/defineApiHandler.ts 50.00% 1 Missing ⚠️
... and 5 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2421      +/-   ##
==========================================
- Coverage   51.22%   50.96%   -0.27%     
==========================================
  Files        1071     1062       -9     
  Lines       29354    29044     -310     
  Branches     6450     6431      -19     
==========================================
- Hits        15038    14802     -236     
- Misses      13898    13900       +2     
+ Partials      418      342      -76     
Flag Coverage Δ *Carryforward flag
api 80.05% <ø> (ø) Carriedforward from b771771
deploy-web 31.39% <63.19%> (+0.08%) ⬆️
log-collector ?
notifications 87.94% <ø> (ø) Carriedforward from b771771
provider-console 81.48% <ø> (ø) Carriedforward from b771771
provider-proxy 84.35% <ø> (ø) Carriedforward from b771771

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

Files with missing lines Coverage Δ
...-web/src/components/auth/SignInForm/SignInForm.tsx 87.50% <ø> (ø)
apps/deploy-web/src/config/env-config.schema.ts 72.72% <ø> (+1.29%) ⬆️
...eb/src/middleware/verify-captcha/verify-captcha.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/pages/_app.tsx 0.00% <ø> (ø)
apps/deploy-web/src/pages/api/proxy/[...path].ts 77.41% <ø> (ø)
.../deploy-web/src/pages/profile/[username]/index.tsx 0.00% <ø> (ø)
apps/deploy-web/src/pages/template/[id]/index.tsx 0.00% <ø> (ø)
...es/app-di-container/server-di-container.service.ts 100.00% <100.00%> (ø)
...b/src/utils/getInjectedConfig/getInjectedConfig.ts 100.00% <100.00%> (ø)
...rc/lib/nextjs/defineApiHandler/defineApiHandler.ts 96.00% <50.00%> (-4.00%) ⬇️
... and 14 more

... and 60 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: 7

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/pages/api/github/authenticate.ts (1)

16-18: Remove unsafe type assertions.

The type assertions as string on lines 16-17 bypass TypeScript's type safety. Line 18 (NEXT_PUBLIC_REDIRECT_URI) is used without a cast, creating an inconsistency. If these values can be undefined, validate them at runtime instead of using type assertions.

🔎 Proposed fix
-    const gitHubAuth = new GitHubAuth(
-      NEXT_PUBLIC_GITHUB_CLIENT_ID as string,
-      GITHUB_CLIENT_SECRET as string,
-      NEXT_PUBLIC_REDIRECT_URI,
-      services.externalApiHttpClient
-    );
+    if (!NEXT_PUBLIC_GITHUB_CLIENT_ID || !GITHUB_CLIENT_SECRET || !NEXT_PUBLIC_REDIRECT_URI) {
+      return res.status(500).json({ error: "GitHub authentication is not configured" });
+    }
+    const gitHubAuth = new GitHubAuth(
+      NEXT_PUBLIC_GITHUB_CLIENT_ID,
+      GITHUB_CLIENT_SECRET,
+      NEXT_PUBLIC_REDIRECT_URI,
+      services.externalApiHttpClient
+    );

Based on coding guidelines, TypeScript types should be properly defined rather than using type assertions.

🧹 Nitpick comments (11)
apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx (1)

90-96: Consider using a button element instead of Link for better semantics.

Next.js Link is designed for route navigation, but this element triggers a handler without navigation. A button styled as a link would be more semantically appropriate and eliminate the need for href="#" and preventDefault().

🔎 Alternative implementation using a button
-                     <d.Link
-                       className="text-xs text-current underline hover:no-underline"
-                       prefetch={false}
-                       href="#"
-                       onClick={onForgotPasswordClick}
-                       tabIndex={-1}
-                     >
+                     <button
+                       type="button"
+                       className="text-xs text-current underline hover:no-underline bg-transparent border-0 cursor-pointer p-0"
+                       onClick={onForgotPasswordClick}
+                     >
                        Forgot password?
-                     </d.Link>
+                     </button>
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (1)

9-9: Consider using handler name reference instead of hardcoded string.

The root describe block uses a hardcoded string literal. Per coding guidelines, using proxyHandler.name enables automated refactoring tools to find all references.

🔎 Proposed refactor
-describe("proxy API handler", () => {
+describe(proxyHandler.name, () => {

As per coding guidelines, use <Subject>.name in the root describe suite description.

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

48-53: Consider alphabetical ordering of environment variables.

Static analysis suggests E2E_TESTING_CLIENT_TOKEN should appear before NEXT_PUBLIC_* variables for consistency with typical env file ordering conventions.

🔎 Proposed reordering
 UNLEASH_SERVER_API_TOKEN=

+E2E_TESTING_CLIENT_TOKEN=any-random-string
+
 NEXT_PUBLIC_TURNSTILE_ENABLED=true
 # https://developers.cloudflare.com/turnstile/troubleshooting/testing/#dummy-sitekeys-and-secret-keys
 NEXT_PUBLIC_TURNSTILE_SITE_KEY=1x00000000000000000000AA
 TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA
-E2E_TESTING_CLIENT_TOKEN=any-random-string
apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (1)

62-62: Positional button selector is fragile.

Using getAllByRole("button")[0] relies on DOM order. Consider adding accessible names or data-testid attributes to buttons for more robust selection.

apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)

38-41: Dual ref pattern with fallback.

The component accepts both a forwarded ref and an explicit turnstileRef prop, using ref || externalTurnstileRef in useImperativeHandle. This works but is unconventional—consider documenting why both are needed or simplifying to use only the forwarded ref.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (1)

244-251: Consider extracting TurnstileMock for reusability.

The TurnstileMock implementation is well-structured, but it may be useful in other test files that interact with Turnstile. Consider extracting it to a shared test utility.

🔎 Suggested approach

Create a test utility file (e.g., @tests/unit/mocks/turnstile.mock.ts):

import type { RefObject } from "react";
import type { TurnstileRef } from "@src/components/turnstile/Turnstile";

export function createTurnstileMock(token = "test-captcha-token") {
  return jest.fn(({ turnstileRef }: { turnstileRef?: RefObject<TurnstileRef> }) => {
    if (turnstileRef) {
      (turnstileRef as { current: TurnstileRef }).current = {
        renderAndWaitResponse: jest.fn().mockResolvedValue({ token })
      };
    }
    return null;
  });
}

Then use it in tests:

const TurnstileMock = createTurnstileMock();
apps/deploy-web/src/pages/api/auth/password-login.ts (1)

17-26: Use destructured body consistently.

The handler destructures body from ctx (line 18) and uses it for captchaToken (line 20), but then uses req.body for email and password (lines 24-25). For consistency, use the destructured body throughout.

🔎 Proposed fix
     const result = await services.sessionService.signIn({
-      email: req.body.email,
-      password: req.body.password
+      email: body.email,
+      password: body.password
     });
apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts (1)

15-22: Use destructured body consistently.

The handler destructures body from ctx (line 16) and uses it for captchaToken (line 19), but then uses req.body.email (line 22). For consistency, use the destructured body throughout.

🔎 Proposed fix
-      const result = await services.sessionService.sendPasswordResetEmail({ email: req.body.email });
+      const result = await services.sessionService.sendPasswordResetEmail({ email: body.email });
apps/deploy-web/src/pages/api/auth/password-signup.ts (1)

39-48: Use destructured body consistently.

The handler destructures body from ctx (line 40) and uses it for captchaToken (line 42), but then uses req.body for email and password (lines 46-47). For consistency, use the destructured body throughout.

🔎 Proposed fix
     const result = await services.sessionService.signUp({
-      email: req.body.email,
-      password: req.body.password
+      email: body.email,
+      password: body.password
     });
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)

27-32: Consider adding truthy checks before type casting.

Lines 28-29 cast header values to string without verifying they exist. While this works (returning undefined when the header is missing), it's clearer to add truthy checks for consistency with the typeof check on line 30.

🔎 Proposed fix
 function getRemoteIp(req: IncomingMessage) {
-  if (req.headers["cf-connecting-ip"]) return req.headers["cf-connecting-ip"] as string;
-  if (req.headers["x-real-ip"]) return req.headers["x-real-ip"] as string;
+  const cfConnectingIp = req.headers["cf-connecting-ip"];
+  if (cfConnectingIp) return Array.isArray(cfConnectingIp) ? cfConnectingIp[0] : cfConnectingIp;
+  
+  const xRealIp = req.headers["x-real-ip"];
+  if (xRealIp) return Array.isArray(xRealIp) ? xRealIp[0] : xRealIp;
+  
   if (typeof req.headers["x-forwarded-for"] === "string") return req.headers["x-forwarded-for"].split(",")[0]?.trim();
   return req.socket?.remoteAddress;
 }

Note: Headers can be arrays when multiple values are present. The fix handles both string and array cases.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

82-104: Add resetMutations to setActiveView dependencies.

The setActiveView callback (line 87) calls resetMutations, but resetMutations is not included in its dependency array (line 90). This could cause stale closures.

🔎 Proposed fix
   const setActiveView = useCallback(
     (value: string) => {
       const tabId = value !== "login" && value !== "signup" && value !== "forgot-password" ? "login" : value;
       const newSearchParams = new URLSearchParams(searchParams);
       newSearchParams.set("tab", tabId);
       resetMutations();
       router.replace(`?${newSearchParams.toString()}`, undefined, { shallow: true });
     },
-    [searchParams, router]
+    [searchParams, router, resetMutations]
   );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d155c4 and 87164b3.

📒 Files selected for processing (36)
  • apps/deploy-web/env/.env.sample
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
  • apps/deploy-web/src/config/env-config.schema.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.spec.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.ts
  • apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/pages/api/auth/password-login.ts
  • apps/deploy-web/src/pages/api/auth/password-signup.ts
  • apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts
  • apps/deploy-web/src/pages/api/auth/signup.ts
  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
  • apps/deploy-web/src/pages/api/bitbucket/refresh.ts
  • apps/deploy-web/src/pages/api/github/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/refresh.ts
  • apps/deploy-web/src/pages/api/proxy/[...path].ts
  • apps/deploy-web/src/pages/profile/[username]/index.tsx
  • apps/deploy-web/src/pages/template/[id]/index.tsx
  • apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
  • apps/deploy-web/src/services/auth/auth/auth.service.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.spec.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
💤 Files with no reviewable changes (5)
  • apps/deploy-web/src/hooks/useInjectedConfig.spec.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.spec.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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/components/auth/SignInForm/SignInForm.tsx
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
  • apps/deploy-web/src/pages/api/bitbucket/refresh.ts
  • apps/deploy-web/src/pages/api/proxy/[...path].ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/pages/api/gitlab/refresh.ts
  • apps/deploy-web/src/pages/api/github/authenticate.ts
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/pages/profile/[username]/index.tsx
  • apps/deploy-web/src/services/auth/auth/auth.service.ts
  • apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts
  • apps/deploy-web/src/pages/api/auth/password-login.ts
  • apps/deploy-web/src/config/env-config.schema.ts
  • apps/deploy-web/src/pages/api/auth/signup.ts
  • apps/deploy-web/src/pages/api/gitlab/authenticate.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/pages/api/auth/password-signup.ts
  • apps/deploy-web/src/pages/template/[id]/index.tsx
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
  • apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
  • apps/deploy-web/src/pages/api/auth/send-password-reset-email.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/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
🧠 Learnings (10)
📚 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/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
📚 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.sample
  • apps/deploy-web/src/config/env-config.schema.ts
📚 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/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
📚 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/tests/ui/fixture/base-test.ts
📚 Learning: 2025-10-15T16:39:55.348Z
Learnt from: jzsfkzm
Repo: akash-network/console PR: 2039
File: apps/deploy-web/tests/ui/change-wallets.spec.ts:4-10
Timestamp: 2025-10-15T16:39:55.348Z
Learning: In the Akash Console E2E tests using the context-with-extension fixture, the first wallet is automatically created during fixture setup via `importWalletToLeap` in `apps/deploy-web/tests/ui/fixture/wallet-setup.ts`, so tests that call `frontPage.createWallet()` are creating a second wallet to test wallet switching functionality.

Applied to files:

  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-05-22T14:25:01.336Z
Learnt from: stalniy
Repo: akash-network/console PR: 1353
File: apps/deploy-web/src/config/browser-env.config.ts:0-0
Timestamp: 2025-05-22T14:25:01.336Z
Learning: For the `__AK_INJECTED_CONFIG__` global window property in the Akash Network Console, security is handled through cryptographic signature verification using a public key rather than property protection mechanisms like Object.defineProperty.

Applied to files:

  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.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

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
📚 Learning: 2025-09-10T08:40:53.104Z
Learnt from: stalniy
Repo: akash-network/console PR: 1892
File: apps/deploy-web/src/components/new-deployment/BidCountdownTimer.tsx:20-31
Timestamp: 2025-09-10T08:40:53.104Z
Learning: In TanStack Query v5, the onSuccess and onError callbacks were removed from useQuery options. Instead, use useEffect with the data as a dependency to handle side effects when query data changes.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
🧬 Code graph analysis (24)
apps/deploy-web/src/pages/api/bitbucket/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/bitbucket/refresh.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts (1)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)
  • TurnstileVerifierService (5-56)
apps/deploy-web/src/pages/api/gitlab/refresh.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/github/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/auth/[...auth0].ts (3)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
  • services (24-59)
apps/deploy-web/src/services/auth/auth/rewrite-local-redirect.ts (1)
  • rewriteLocalRedirect (5-15)
apps/deploy-web/src/pages/profile/[username]/index.tsx (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (2)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • AppTypedContext (24-31)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/tests/ui/fixture/base-test.ts (1)
apps/deploy-web/tests/ui/fixture/test-env.config.ts (1)
  • testEnvConfig (16-21)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)
  • config (59-64)
apps/deploy-web/src/pages/api/auth/password-login.ts (2)
apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts (1)
  • defineApiHandler (13-57)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-25)
apps/deploy-web/src/pages/api/auth/signup.ts (2)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/services/auth/auth/rewrite-local-redirect.ts (1)
  • rewriteLocalRedirect (5-15)
apps/deploy-web/src/pages/api/gitlab/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (2)
apps/deploy-web/tests/ui/fixture/base-test.ts (1)
  • expect (15-15)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
  • TurnstileRef (26-28)
apps/deploy-web/src/pages/api/auth/password-signup.ts (1)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-25)
apps/deploy-web/src/pages/template/[id]/index.tsx (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts (1)
apps/deploy-web/src/config/env-config.schema.ts (1)
  • BrowserEnvConfig (78-78)
apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.tsx (1)
  • TrendIndicatorProps (14-19)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts (1)
  • getInjectedConfig (3-5)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (2)
apps/api/test/services/mock-config.service.ts (1)
  • mockConfig (10-17)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (2)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)
  • ClientOnlyTurnstile (158-158)
  • TurnstileRef (26-28)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (33-35)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)
  • TurnstileVerifierService (5-56)
apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts (2)
apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts (1)
  • defineApiHandler (13-57)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-25)
🪛 dotenv-linter (4.0.0)
apps/deploy-web/env/.env.sample

[warning] 53-53: [UnorderedKey] The E2E_TESTING_CLIENT_TOKEN key should go before the NEXT_PUBLIC_TURNSTILE_ENABLED key

(UnorderedKey)

⏰ 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 (26)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)

41-41: LGTM! Configuration migration to privateConfig.

The change correctly migrates the network ID configuration source from services.config to services.privateConfig, which is a good security practice for server-side configuration management. The proxy target URL resolution logic remains unchanged.

apps/deploy-web/src/services/auth/auth/auth.service.ts (1)

32-37: LGTM! Server-side captcha validation and error handling properly implemented.

The captchaToken parameter is correctly added to all three authentication methods with proper TypeScript typing (no any types). All three endpoints (/api/auth/password-login, /api/auth/password-signup, /api/auth/send-password-reset-email) implement server-side validation via the verifyCaptcha middleware, which returns a 400 status code with a clear error message ("Captcha verification failed. Please try again.") when verification fails. The UI properly integrates captcha via the Turnstile component and error handling is managed through the RemoteApiError component in the mutation handlers.

apps/deploy-web/tests/ui/fixture/base-test.ts (1)

15-15: LGTM! Convenience export.

Exposing expect as a named export is a helpful convenience for test files.

apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx (1)

118-119: The as unknown as double cast pattern is necessary and appropriate here. TypeScript's strict mode requires this pattern when types have incompatible structures—the mock functions returning JSX don't structurally match the expected typeof COMPONENTS type. This pattern is established throughout the codebase and is explicitly validated as necessary in strict mode TypeScript.

The original review's suggested fix using (props: any) contradicts the stated guideline against using any, making it an invalid suggestion. The current implementation is correct and should remain unchanged.

apps/deploy-web/src/pages/api/gitlab/refresh.ts (1)

14-15: Config migration looks correct.

The switch to services.privateConfig aligns with the broader security improvement to source credentials from private config. The type assertions are consistent with other authentication handlers in this PR.

apps/deploy-web/src/pages/api/bitbucket/authenticate.ts (1)

14-15: Config migration is correct.

The switch to privateConfig is consistent with the security improvements across auth handlers.

apps/deploy-web/src/pages/api/bitbucket/refresh.ts (1)

14-15: Config migration is consistent with other Bitbucket handlers.

The switch to privateConfig correctly aligns with the authenticate endpoint.

apps/deploy-web/src/pages/api/gitlab/authenticate.ts (1)

14-20: Config migration looks good.

The switch to privateConfig is consistent with the refresh endpoint and other OAuth handlers in this PR.

apps/deploy-web/src/config/env-config.schema.ts (1)

67-76: Well-structured schema additions.

Good documentation linking to Cloudflare's test key reference. The default bypass key facilitates local development while the required error message for E2E_TESTING_CLIENT_TOKEN provides clear guidance.

apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (2)

97-152: Good test coverage for renderAndWaitResponse.

The tests properly cover both the success and error paths with appropriate async handling using act and event triggering.


155-176: Setup function follows guidelines correctly.

The setup function is positioned at the bottom of the describe block, accepts a single parameter with inline type definition, avoids shared state, and has no explicit return type. As per coding guidelines, this is the expected pattern.

apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)

115-115: Injected config takes precedence over prop.

The injectedConfig?.NEXT_PUBLIC_TURNSTILE_SITE_KEY ?? siteKey pattern means runtime-injected config overrides the explicitly passed siteKey prop. Verify this precedence is intentional—typically props would take priority.


158-158: Dynamic import returns component directly.

The dynamic import pattern dynamic(async () => Turnstile, ...) works but the more common pattern is dynamic(() => Promise.resolve({ default: Turnstile }), ...) or exporting the component as default from a separate file. Current approach works with Next.js 14.

apps/deploy-web/src/pages/template/[id]/index.tsx (1)

38-38: LGTM!

The config migration from services.config to services.privateConfig is consistent with the broader refactoring in this PR.

apps/deploy-web/src/pages/profile/[username]/index.tsx (1)

28-28: LGTM!

The config migration from services.config to services.privateConfig is consistent with the broader refactoring in this PR.

apps/deploy-web/src/pages/api/auth/signup.ts (1)

12-13: LGTM!

The config migration from services.config to services.privateConfig is consistent with the broader refactoring in this PR. The rewriteLocalRedirect function signature correctly expects the privateConfig type.

Also applies to: 23-23

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

27-28: LGTM!

The config migration from services.config to services.privateConfig is consistently applied across all usage points in this auth handler.

Also applies to: 47-47, 64-64

apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (2)

115-118: LGTM!

The test expectations correctly verify that captchaToken is included in both login and signup calls, aligning with the Turnstile integration.

Also applies to: 176-179


216-274: LGTM!

The test setup function follows all coding guidelines: positioned at the bottom of the describe block, accepts an inline parameter type, avoids shared state, and has no explicit return type annotation.

Based on coding guidelines for test files.

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

18-20: LGTM! Method guard implementation is correct.

The early method validation with a 405 response follows the fail-fast principle and properly enforces HTTP method constraints before any request processing.

apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts (1)

76-86: LGTM! Test structure follows coding guidelines.

The test suite correctly uses TurnstileVerifierService.name in the root describe, method name in nested describe, present simple 3rd person for test descriptions, and jest-mock-extended for mocking. The setup function is properly positioned at the bottom.

apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)

34-60: LGTM! Configuration migration and Turnstile integration are well-structured.

The introduction of privateConfig properly separates sensitive server-side configuration (Auth0 credentials, Turnstile keys) from public config. The captchaVerifier is correctly wired with the required dependencies and configuration.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

230-235: LGTM! Turnstile integration is properly implemented.

The Turnstile component is correctly configured with the ref for imperative API access, config-driven enabled flag and site key, and appropriate callback for resetting mutations.

apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (3)

42-47: Consider handling network and 5xx failures within the Result type.

Currently, 5xx responses and network failures will throw exceptions that propagate to the caller. Per Cloudflare's API, verification failures return 200 with success: false, so 5xx indicates infrastructure issues. If the caller expects all outcomes via the Result type, unhandled exceptions could be unexpected.

If this is intentional (letting callers handle infrastructure errors separately), the current approach is acceptable. Otherwise, consider wrapping the POST call in a try-catch to return an Err for such cases.


58-71: Well-structured response interface.

The TurnstileVerifyResponse interface properly models Cloudflare's verification response with comprehensive error code types. This provides good type safety for handling various verification failure scenarios.


73-83: Clear configuration interface with helpful documentation.

The config interface is well-documented with references to Cloudflare's testing documentation for the bypass mechanism. This makes the E2E testing support explicit and maintainable.

ygrishajev
ygrishajev previously approved these changes Dec 26, 2025
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: 0

🧹 Nitpick comments (1)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (1)

9-9: Consider using proxyHandler.name in the describe block.

As per coding guidelines, use <Subject>.name instead of hardcoded strings to enable automated refactoring tools. However, since proxyHandler is a default export, verify that its .name property is reliable before making this change.

🔎 Proposed refactor (verify name property first)
-describe("proxy API handler", () => {
+describe(proxyHandler.name || "proxy API handler", () => {

Based on coding guidelines for test descriptions.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87164b3 and da305f9.

📒 Files selected for processing (4)
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/tests/ui/fixture/test-env.config.ts
💤 Files with no reviewable changes (1)
  • apps/deploy-web/tests/ui/fixture/test-env.config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/deploy-web/tests/ui/fixture/base-test.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{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/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/playwright.config.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/lib/nextjs/pages/api/proxy/path.spec.ts
🧠 Learnings (5)
📚 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/lib/nextjs/pages/api/proxy/path.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/lib/nextjs/pages/api/proxy/path.spec.ts
📚 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/pages/api/proxy/path.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/lib/nextjs/pages/api/proxy/path.spec.ts
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.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

Applied to files:

  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
🧬 Code graph analysis (1)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (2)
apps/api/test/services/mock-config.service.ts (1)
  • mockConfig (10-17)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
⏰ 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 (3)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (1)

33-33: LGTM! Property name mismatch resolved.

The changes correctly address the previous review comment by:

  • Creating the mock as services.privateConfig (line 33)
  • Assigning it to the privateConfig property (line 77)
  • Using satisfies instead of as unknown as for better type safety (line 79)

The mock structure now accurately reflects the production DI container where the property is named privateConfig.

Also applies to: 77-77, 79-79

apps/deploy-web/playwright.config.ts (2)

7-11: Runtime guard improves test reliability but localhost check could be more robust.

The guard successfully addresses the previous concern about missing token enforcement. However, the localhost bypass only matches the string "localhost" and won't recognize other local addresses like "127.0.0.1", "0.0.0.0", or "[::1]". Developers using IP-based local URLs would be required to set the token even for local testing.

Consider verifying that the localhost bypass aligns with backend behavior and optionally making the check more inclusive.

🔎 Optional enhancement to recognize additional local addresses
-if (!process.env.E2E_TESTING_CLIENT_TOKEN && !process.env.BASE_URL?.includes("localhost")) {
+const isLocalUrl = process.env.BASE_URL?.match(/localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\]/);
+if (!process.env.E2E_TESTING_CLIENT_TOKEN && !isLocalUrl) {
   throw new Error(
     "E2E_TESTING_CLIENT_TOKEN is a required env variable. Without it, tests will be blocked by captcha verification. Should be set to the same value as app's E2E_TESTING_CLIENT_TOKEN env variable."
   );
 }

36-38: LGTM! Header configuration aligns with runtime guard.

The extraHTTPHeaders configuration correctly pairs with the runtime guard above. The fallback to an empty string is now only used for localhost environments (where the guard allows missing tokens), making this intentional rather than an oversight. This addresses the previous review concern about unintentional empty tokens causing test failures.

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

🧹 Nitpick comments (1)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

38-42: LGTM! Icon dependencies refactored for testability.

Moving icon references into the DEPENDENCIES object improves testability by allowing tests to mock these components if needed.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da305f9 and d87c449.

📒 Files selected for processing (2)
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.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/components/auth/AuthPage/AuthPage.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/auth/AuthPage/AuthPage.spec.tsx
🧠 Learnings (6)
📚 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/auth/AuthPage/AuthPage.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/auth/AuthPage/AuthPage.spec.tsx
📚 Learning: 2025-12-26T20:05:53.126Z
Learnt from: stalniy
Repo: akash-network/console PR: 2421
File: apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx:90-96
Timestamp: 2025-12-26T20:05:53.126Z
Learning: In the SignInForm component (apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx), the "Forgot password?" link intentionally uses tabIndex={-1} to keep it out of the keyboard tab order between email and password fields, ensuring a smooth tab flow through the form inputs without interruption.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.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

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.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/auth/AuthPage/AuthPage.spec.tsx
📚 Learning: 2025-09-10T08:40:53.104Z
Learnt from: stalniy
Repo: akash-network/console PR: 1892
File: apps/deploy-web/src/components/new-deployment/BidCountdownTimer.tsx:20-31
Timestamp: 2025-09-10T08:40:53.104Z
Learning: In TanStack Query v5, the onSuccess and onError callbacks were removed from useQuery options. Instead, use useEffect with the data as a dependency to handle side effects when query data changes.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
🧬 Code graph analysis (2)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (4)
apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx (2)
  • SignInForm (38-123)
  • DEPENDENCIES (27-36)
apps/deploy-web/tests/unit/mocks.tsx (1)
  • ComponentMock (6-8)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)
  • DEPENDENCIES (25-46)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
  • TurnstileRef (26-28)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (2)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)
  • ClientOnlyTurnstile (158-158)
  • TurnstileRef (26-28)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (33-35)
⏰ 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: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (18)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (6)

115-118: LGTM! Test correctly verifies captcha token inclusion.

The test now properly asserts that the captcha token is included in the login payload, ensuring the Turnstile integration works as expected.


176-179: LGTM! Test correctly verifies captcha token inclusion.

The test now properly asserts that the captcha token is included in the signup payload, ensuring the Turnstile integration works as expected.


216-256: LGTM! Comprehensive test coverage for forgot password flow.

The new test suite properly covers:

  • Rendering the forgot password form when requested from SignInForm
  • Submitting the form with captchaToken included in the request

The test structure follows established patterns and coding guidelines.


267-273: LGTM! Router mock enhancement enables URL change verification.

The enhanced router mock now captures URL updates through replace and exposes them via setRouterPageParams, enabling tests to verify routing behavior with updated search parameters.


290-294: LGTM! Stateful search params mock enables dynamic testing.

The stateful mock using useState allows tests to simulate search parameter changes, which is necessary for verifying the forgot password flow and tab switching behavior.


296-303: LGTM! Turnstile mock properly simulates captcha behavior.

The mock correctly:

  • Sets up the turnstileRef.current with a renderAndWaitResponse method
  • Returns the test captcha token consistently across all test scenarios
  • Enables verification of captcha integration without external dependencies
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (12)

3-3: LGTM! useRef import needed for Turnstile integration.

The useRef hook is properly imported for managing the Turnstile component reference.


14-15: LGTM! Turnstile imports properly added.

The TurnstileRef type and ClientOnlyTurnstile component are correctly imported for the captcha integration.


33-33: LGTM! Turnstile added to public dependencies.

Adding Turnstile: ClientOnlyTurnstile to the DEPENDENCIES object makes the component testable by allowing test files to inject mocks.


53-53: LGTM! appConfig retrieved for Turnstile configuration.

The appConfig is properly retrieved from services to access Turnstile configuration values (site key and enabled flag).


58-58: LGTM! Turnstile ref properly initialized.

The turnstileRef is correctly initialized with useRef<TurnstileRef | null>(null) to manage the Turnstile component instance.


69-71: LGTM! Proper guard for captcha availability.

The guard ensures that the Turnstile component has been rendered before attempting to retrieve a captcha token, preventing runtime errors.


74-74: LGTM! Captcha token retrieval implemented correctly.

The captcha token is properly retrieved using the imperative renderAndWaitResponse() API before proceeding with authentication.


77-79: LGTM! Captcha token passed to authentication methods.

The captchaToken is correctly included in both login and signup calls, ensuring server-side verification.


92-92: LGTM! Mutations reset on view change.

Calling resetMutations() when changing views properly clears error states and ensures a clean UI transition.


99-103: LGTM! Forgot password flow includes captcha verification.

The forgot password mutation correctly:

  • Guards against missing Turnstile ref
  • Retrieves captcha token
  • Passes token to sendPasswordResetEmail

106-109: LGTM! Reset mutations helper properly implemented.

The resetMutations callback correctly resets both signInOrSignUp and forgotPassword mutations to clear error states.


236-241: LGTM! Turnstile component properly integrated.

The Turnstile component is correctly rendered with:

  • turnstileRef for imperative API access
  • enabled flag from config
  • siteKey from config
  • onGoBack callback to reset mutations

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: 0

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/components/auth/AuthPage/AuthPage.tsx (1)

67-84: Authentication will fail when Turnstile is disabled (NEXT_PUBLIC_TURNSTILE_ENABLED=false).

The signInOrSignUp and forgotPassword mutations unconditionally throw "Captcha has not been rendered" when turnstileRef.current is null. Since the Turnstile component returns null when disabled (line 90-92 of Turnstile.tsx), the ref is never initialized, causing all authentication attempts to fail. The authService.login(), authService.signup(), and authService.sendPasswordResetEmail() methods all require captchaToken as a mandatory parameter with no fallback mechanism.

Provide a fallback token or conditionally bypass the Turnstile check when the feature is disabled.

🧹 Nitpick comments (1)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

86-96: Add resetMutations to the dependency array.

The setActiveView callback calls resetMutations() on line 92 but doesn't include it in the dependency array on line 95. This violates React's exhaustive-deps rule and could lead to stale closure bugs.

🔎 Proposed fix
  const setActiveView = useCallback(
    (value: string) => {
      const tabId = value !== "login" && value !== "signup" && value !== "forgot-password" ? "login" : value;
      const newSearchParams = new URLSearchParams(searchParams);
      newSearchParams.set("tab", tabId);
      resetMutations();
      router.replace(`?${newSearchParams.toString()}`, undefined, { shallow: true });
    },
-   [searchParams, router]
+   [searchParams, router, resetMutations]
  );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d87c449 and 2612bcc.

📒 Files selected for processing (1)
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{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/components/auth/AuthPage/AuthPage.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-26T20:05:53.126Z
Learnt from: stalniy
Repo: akash-network/console PR: 2421
File: apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx:90-96
Timestamp: 2025-12-26T20:05:53.126Z
Learning: In the SignInForm component (apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx), the "Forgot password?" link intentionally uses tabIndex={-1} to keep it out of the keyboard tab order between email and password fields, ensuring a smooth tab flow through the form inputs without interruption.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.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/auth/AuthPage/AuthPage.tsx
📚 Learning: 2025-09-10T08:40:53.104Z
Learnt from: stalniy
Repo: akash-network/console PR: 1892
File: apps/deploy-web/src/components/new-deployment/BidCountdownTimer.tsx:20-31
Timestamp: 2025-09-10T08:40:53.104Z
Learning: In TanStack Query v5, the onSuccess and onError callbacks were removed from useQuery options. Instead, use useEffect with the data as a dependency to handle side effects when query data changes.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
⏰ 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 (7)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (7)

3-3: LGTM! Imports are correctly structured.

The addition of useRef and Turnstile-related imports follows TypeScript best practices with proper type vs. value import separation.

Also applies to: 14-15


25-46: LGTM! Dependency injection pattern applied consistently.

The addition of Turnstile and UI components to the DEPENDENCIES object maintains the testability pattern already established in this component.


53-53: LGTM! Proper initialization of Turnstile dependencies.

The appConfig and turnstileRef are correctly initialized with appropriate TypeScript types.

Also applies to: 58-58


97-105: LGTM! Consistent captcha integration.

The forgotPassword mutation correctly integrates captcha token retrieval, following the same pattern as signInOrSignUp. Ensure the disabled Turnstile scenario is handled (as noted in the previous comment).


106-109: LGTM! Mutation reset helper is correctly implemented.

The resetMutations helper properly resets both mutations and can be reused across different flows.


119-119: LGTM! UI component references updated consistently.

The changes to use dependency-injected component references (e.g., d.ZapIcon, d.AkashConsoleLogo) maintain consistency with the established pattern. The spacing adjustment on line 167 is appropriate.

Also applies to: 128-128, 137-137, 151-151, 167-167, 212-212


235-240: LGTM! Turnstile component integration is well-structured.

The Turnstile component receives all necessary props (ref, config flags, callback) and is properly positioned in the auth flow.

@stalniy stalniy force-pushed the feat/adds-turnstile-to-auth-pages branch from 2612bcc to 282cf57 Compare December 29, 2025 12:09
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: 5

Caution

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

⚠️ Outside diff range comments (3)
apps/deploy-web/src/pages/api/github/authenticate.ts (1)

14-20: Type assertions bypass safety checks.

The as string casts on lines 16–17 violate the project guideline against type assertions and can cause runtime failures if environment variables are undefined.

Replace assertions with explicit validation.

🔎 Suggested validation approach
  async handler({ body, res, services }) {
    const { NEXT_PUBLIC_GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, NEXT_PUBLIC_REDIRECT_URI } = services.privateConfig;
+   
+   if (!NEXT_PUBLIC_GITHUB_CLIENT_ID || !GITHUB_CLIENT_SECRET || !NEXT_PUBLIC_REDIRECT_URI) {
+     return res.status(500).json({ error: "GitHub OAuth is not configured" });
+   }
+   
    const gitHubAuth = new GitHubAuth(
-     NEXT_PUBLIC_GITHUB_CLIENT_ID as string,
-     GITHUB_CLIENT_SECRET as string,
+     NEXT_PUBLIC_GITHUB_CLIENT_ID,
+     GITHUB_CLIENT_SECRET,
      NEXT_PUBLIC_REDIRECT_URI,
      services.externalApiHttpClient
    );

    const accessToken = await gitHubAuth.exchangeAuthorizationCodeForToken(body.code);
    res.status(200).json({ accessToken });
  }
apps/deploy-web/src/pages/api/gitlab/authenticate.ts (1)

14-20: Type assertions bypass safety checks.

The as string casts on lines 16–17 violate the project guideline against type assertions and can cause runtime failures if environment variables are undefined.

Replace assertions with explicit validation.

🔎 Suggested validation approach
  async handler({ body, res, services }) {
    const { NEXT_PUBLIC_GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET, NEXT_PUBLIC_REDIRECT_URI } = services.privateConfig;
+   
+   if (!NEXT_PUBLIC_GITLAB_CLIENT_ID || !GITLAB_CLIENT_SECRET || !NEXT_PUBLIC_REDIRECT_URI) {
+     return res.status(500).json({ error: "GitLab OAuth is not configured" });
+   }
+   
    const gitlabAuth = new GitlabAuth(
-     NEXT_PUBLIC_GITLAB_CLIENT_ID as string,
-     GITLAB_CLIENT_SECRET as string,
+     NEXT_PUBLIC_GITLAB_CLIENT_ID,
+     GITLAB_CLIENT_SECRET,
      NEXT_PUBLIC_REDIRECT_URI,
      services.externalApiHttpClient
    );

    const tokens = await gitlabAuth.exchangeAuthorizationCodeForTokens(body.code);
    res.status(200).json(tokens);
  }
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

87-96: Missing resetMutations in dependency array causes stale closure.

setActiveView calls resetMutations() but doesn't include it in its dependency array. If resetMutations identity changes (due to its own dependencies changing), this callback will call the stale version.

🔎 Proposed fix
   const setActiveView = useCallback(
     (value: string) => {
       const tabId = value !== "login" && value !== "signup" && value !== "forgot-password" ? "login" : value;
       const newSearchParams = new URLSearchParams(searchParams);
       newSearchParams.set("tab", tabId);
       resetMutations();
       router.replace(`?${newSearchParams.toString()}`, undefined, { shallow: true });
     },
-    [searchParams, router]
+    [searchParams, router, resetMutations]
   );
♻️ Duplicate comments (2)
apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts (1)

4-4: Avoid using any type (duplicate concern).

The cast to any violates the coding guideline. A proper interface declaration for window.__AK_INJECTED_CONFIG__ should be defined instead.

Based on coding guidelines for TypeScript.

apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)

63-88: Stale closure and cleanup concerns were previously flagged.

The past review already noted the stale closure on status (line 80) and potential memory leak if the component unmounts before events fire.

🧹 Nitpick comments (6)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (1)

9-9: Consider using a named reference in the test suite description.

The describe block uses a hardcoded string "proxy API handler". Per coding guidelines, consider using a named reference (e.g., proxyHandler.name or extracting the handler to a named constant) to enable automated refactoring tools to find all references.

🔎 Possible refactor

One approach is to extract the default export to a named constant:

In apps/deploy-web/src/pages/api/proxy/[...path].ts:

export const proxyApiHandler = defineApiHandler({
  // ... existing configuration
});

export default proxyApiHandler;

Then in the test file:

-describe("proxy API handler", () => {
+describe(proxyHandler.name, () => {

As per coding guidelines, this improves maintainability but is not critical to functionality.

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

18-20: Efficient method guard placement.

The early method check before session retrieval and schema validation is well-placed for efficiency.

Consider adding Allow header (optional)

Per HTTP spec, 405 responses should include an Allow header indicating permitted methods. This is optional but improves API discoverability:

 if (options.method && req.method !== options.method) {
+  res.setHeader("Allow", options.method);
   return res.status(405).json({ message: "Method not allowed" } as TResponse);
 }
apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts (1)

16-22: Inconsistent body access: body.captchaToken vs req.body.email.

Line 19 uses the destructured body.captchaToken from the validated context, but line 22 uses req.body.email. For consistency and to ensure you're using the validated data, prefer body.email.

🔎 Proposed fix
-      const result = await services.sessionService.sendPasswordResetEmail({ email: req.body.email });
+      const result = await services.sessionService.sendPasswordResetEmail({ email: body.email });
apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (2)

2-2: Use act from @testing-library/react instead of the deprecated import.

The import from react-dom/test-utils is deprecated in React 18+. The @testing-library/react package re-exports act and is the recommended source.

🔎 Proposed fix
-import { act } from "react-dom/test-utils";
+import { act, fireEvent, render, screen } from "@testing-library/react";

And remove the duplicate import on line 11:

-import { fireEvent, render, screen } from "@testing-library/react";

62-62: Consider adding accessible names to buttons for more robust selectors.

Using positional selectors like getAllByRole("button")[0] and getAllByRole("button")[1] is fragile—if button order changes, tests break silently. Consider adding aria-label attributes to the component's Retry and Go Back buttons, then selecting by name:

fireEvent.click(screen.getByRole("button", { name: /retry/i }));
fireEvent.click(screen.getByRole("button", { name: /go back/i }));

This would also improve accessibility of the actual component.

Also applies to: 89-89

apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)

46-46: Minor: getInjectedConfig() is called on every render.

This function reads from window on each render. Consider memoizing if performance becomes a concern, though the impact is likely negligible.

🔎 Proposed fix
-  const injectedConfig = getInjectedConfig();
+  const injectedConfig = useMemo(() => getInjectedConfig(), []);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2612bcc and 282cf57.

📒 Files selected for processing (37)
  • apps/deploy-web/env/.env.sample
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
  • apps/deploy-web/src/config/env-config.schema.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.spec.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.ts
  • apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/pages/api/auth/password-login.ts
  • apps/deploy-web/src/pages/api/auth/password-signup.ts
  • apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts
  • apps/deploy-web/src/pages/api/auth/signup.ts
  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
  • apps/deploy-web/src/pages/api/bitbucket/refresh.ts
  • apps/deploy-web/src/pages/api/github/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/refresh.ts
  • apps/deploy-web/src/pages/api/proxy/[...path].ts
  • apps/deploy-web/src/pages/profile/[username]/index.tsx
  • apps/deploy-web/src/pages/template/[id]/index.tsx
  • apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
  • apps/deploy-web/src/services/auth/auth/auth.service.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.spec.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/tests/ui/fixture/test-env.config.ts
💤 Files with no reviewable changes (6)
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/hooks/useInjectedConfig.spec.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.spec.ts
  • apps/deploy-web/tests/ui/fixture/test-env.config.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
🚧 Files skipped from review as they are similar to previous changes (11)
  • apps/deploy-web/src/pages/api/gitlab/refresh.ts
  • apps/deploy-web/src/pages/api/bitbucket/refresh.ts
  • apps/deploy-web/src/config/env-config.schema.ts
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
  • apps/deploy-web/src/pages/api/auth/password-signup.ts
  • apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx
  • apps/deploy-web/src/services/auth/auth/auth.service.ts
  • apps/deploy-web/src/pages/api/auth/password-login.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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/signup.ts
  • apps/deploy-web/src/pages/api/proxy/[...path].ts
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/authenticate.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/src/pages/template/[id]/index.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
  • apps/deploy-web/src/pages/profile/[username]/index.tsx
  • apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
  • apps/deploy-web/src/pages/api/github/authenticate.ts
  • apps/deploy-web/src/pages/api/auth/send-password-reset-email.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/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
🧠 Learnings (14)
📚 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/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
📚 Learning: 2025-12-26T20:06:01.746Z
Learnt from: stalniy
Repo: akash-network/console PR: 2421
File: apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx:90-96
Timestamp: 2025-12-26T20:06:01.746Z
Learning: In the SignInForm component (apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx), the "Forgot password?" link intentionally uses tabIndex={-1} to keep it out of the keyboard tab order between email and password fields, ensuring a smooth tab flow through the form inputs without interruption.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.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

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
📚 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/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-05-22T14:25:01.336Z
Learnt from: stalniy
Repo: akash-network/console PR: 1353
File: apps/deploy-web/src/config/browser-env.config.ts:0-0
Timestamp: 2025-05-22T14:25:01.336Z
Learning: For the `__AK_INJECTED_CONFIG__` global window property in the Akash Network Console, security is handled through cryptographic signature verification using a public key rather than property protection mechanisms like Object.defineProperty.

Applied to files:

  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-11-25T17:45:39.561Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T17:45:39.561Z
Learning: Applies to **/*.{ts,tsx,js} : Never use type `any` or cast to type `any`. Always define the proper TypeScript types.

Applied to files:

  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
📚 Learning: 2025-11-25T17:45:39.561Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T17:45:39.561Z
Learning: Applies to **/*.{ts,tsx,js} : Never use deprecated methods from libraries.

Applied to files:

  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
📚 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.sample
📚 Learning: 2025-09-10T08:40:53.104Z
Learnt from: stalniy
Repo: akash-network/console PR: 1892
File: apps/deploy-web/src/components/new-deployment/BidCountdownTimer.tsx:20-31
Timestamp: 2025-09-10T08:40:53.104Z
Learning: In TanStack Query v5, the onSuccess and onError callbacks were removed from useQuery options. Instead, use useEffect with the data as a dependency to handle side effects when query data changes.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.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/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
📚 Learning: 2025-10-15T16:39:55.348Z
Learnt from: jzsfkzm
Repo: akash-network/console PR: 2039
File: apps/deploy-web/tests/ui/change-wallets.spec.ts:4-10
Timestamp: 2025-10-15T16:39:55.348Z
Learning: In the Akash Console E2E tests using the context-with-extension fixture, the first wallet is automatically created during fixture setup via `importWalletToLeap` in `apps/deploy-web/tests/ui/fixture/wallet-setup.ts`, so tests that call `frontPage.createWallet()` are creating a second wallet to test wallet switching functionality.

Applied to files:

  • apps/deploy-web/tests/ui/fixture/base-test.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/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
🧬 Code graph analysis (16)
apps/deploy-web/src/pages/api/auth/signup.ts (2)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/services/auth/auth/rewrite-local-redirect.ts (1)
  • rewriteLocalRedirect (5-15)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx (1)
apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.tsx (1)
  • TrendIndicatorProps (14-19)
apps/deploy-web/src/pages/api/bitbucket/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/gitlab/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (3)
apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx (2)
  • SignInForm (38-123)
  • DEPENDENCIES (27-36)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)
  • DEPENDENCIES (25-46)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
  • TurnstileRef (26-28)
apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts (1)
apps/deploy-web/src/config/env-config.schema.ts (1)
  • BrowserEnvConfig (78-78)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (2)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • AppTypedContext (24-31)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (2)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)
  • ClientOnlyTurnstile (158-158)
  • TurnstileRef (26-28)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (33-35)
apps/deploy-web/src/pages/template/[id]/index.tsx (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts (1)
  • getInjectedConfig (3-5)
apps/deploy-web/src/pages/profile/[username]/index.tsx (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (2)
apps/api/test/services/mock-config.service.ts (1)
  • mockConfig (10-17)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (1)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)
  • TurnstileRef (26-28)
  • Turnstile (38-156)
apps/deploy-web/src/pages/api/github/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts (2)
apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts (1)
  • defineApiHandler (13-57)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-25)
🪛 dotenv-linter (4.0.0)
apps/deploy-web/env/.env.sample

[warning] 53-53: [UnorderedKey] The E2E_TESTING_CLIENT_TOKEN key should go before the NEXT_PUBLIC_TURNSTILE_ENABLED key

(UnorderedKey)

⏰ 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 (18)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)

41-41: Configuration migration looks correct.

The change from services.config to services.privateConfig correctly aligns with the PR's objective of moving server configuration reads to privateConfig. The server-di-container.service.ts confirms that privateConfig is properly defined and contains NEXT_PUBLIC_MANAGED_WALLET_NETWORK_ID.

apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (1)

33-33: Test configuration correctly updated to match production code.

The changes successfully resolve the property name mismatch flagged in the previous review. Both the mock type (line 33) and the test object property (line 77) now correctly use privateConfig, mirroring the structure in server-di-container.service.ts.

The change from as unknown as typeof services to satisfies typeof services on line 79 is also a good improvement—satisfies provides stronger type checking while preserving the inferred type.

Also applies to: 77-77, 79-79

apps/deploy-web/src/pages/template/[id]/index.tsx (1)

37-40: Configuration migration consistent with the codebase pattern.

This change mirrors the migration in apps/deploy-web/src/pages/profile/[username]/index.tsx and aligns with the server DI container configuration. The template fetching logic and authorization flow remain intact.

apps/deploy-web/src/pages/profile/[username]/index.tsx (1)

27-29: Configuration migration is complete and consistent across server-side code.

The change from services.config to services.privateConfig for NEXT_PUBLIC_MANAGED_WALLET_NETWORK_ID is properly implemented. All server-side references use services.privateConfig (including the template page, proxy route, and DI container), while client-side code correctly uses browserEnvConfig. The configuration is properly initialized in the server environment setup.

apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx (1)

118-119: This type cast pattern is appropriate and does not violate TypeScript guidelines. The as unknown as pattern uses unknown (type-safe) rather than any, which the coding guidelines specifically forbid. Double casts through unknown are necessary when types are structurally incompatible, as is the case here: the mock is a function returning JSX while the actual GraphUp and GraphDown are icon components from the iconoir-react library. This pattern is established throughout the test suite and aligns with strict mode typing practices.

Likely an incorrect or invalid review comment.

apps/deploy-web/src/pages/api/auth/signup.ts (1)

12-13: LGTM! Config access migrated to privateConfig.

The migration from services.config to services.privateConfig is consistent with the server-side configuration pattern established in the DI container.

Also applies to: 23-23

apps/deploy-web/tests/ui/fixture/base-test.ts (1)

15-22: Clean implementation using Cloudflare's testing site key.

The approach of injecting a frozen config with the always-pass Turnstile site key (1x00000000000000000000AA) is well-aligned with Cloudflare's testing documentation. The Object.freeze prevents accidental mutation during tests.

The (window as any) cast on line 17 is acceptable here since TypeScript doesn't provide native typing for custom window properties, and declaring a global augmentation for test-only code would be overkill.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (2)

296-303: Well-implemented TurnstileMock with ref-based token injection.

The mock correctly implements the TurnstileRef interface by assigning to turnstileRef.current, enabling the component under test to call renderAndWaitResponse() and receive the test token. This approach follows the dependency injection pattern without using jest.mock().


216-256: Comprehensive ForgotPassword workflow tests.

The tests properly cover:

  1. Navigation from SignInForm to ForgotPasswordForm via onForgotPasswordClick
  2. Form submission with captchaToken verification

Using getByText for presence assertions aligns with the project's testing guidelines for better error diagnostics.

apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (2)

6-25: Clean CAPTCHA middleware implementation.

The middleware correctly:

  • Extracts client IP with proper priority for Cloudflare environments
  • Passes bypass token for E2E testing support
  • Logs verification failures before returning an error
  • Uses ts-results for consistent error handling

The integration with AppTypedContext ensures type safety for the services and request objects.


27-32: IP extraction handles common proxy headers correctly.

The priority order (CF-Connecting-IP → X-Real-IP → X-Forwarded-For → socket) is appropriate for Cloudflare-fronted deployments. The optional return type aligns with the remoteIp?: string parameter in the verifier.

apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)

42-47: No issue. The Cloudflare Turnstile siteverify endpoint accepts both application/x-www-form-urlencoded and application/json per official documentation, so the implementation is correct.

apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (2)

97-152: Well-structured tests for the imperative handle.

The renderAndWaitResponse tests properly verify both the success and error paths using the ref-based pattern. The use of triggerSuccess and triggerError closures to simulate the underlying ReactTurnstile callbacks is a clean approach.


155-176: Setup function follows guidelines correctly.

The setup function is positioned at the bottom of the describe block, accepts a single parameter with an inline type definition, avoids shared state, and has no explicit return type. Good adherence to the coding guidelines.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (2)

67-84: Turnstile integration in mutation flow is well-implemented.

The captcha token acquisition flow correctly:

  • Guards against null ref before calling renderAndWaitResponse
  • Awaits the token before proceeding with auth
  • Passes the token to the service methods

235-240: Turnstile component wiring looks correct.

The component is properly configured with the ref, enabled flag from config, site key, and the onGoBack callback to reset mutations when the user dismisses the captcha.

apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)

121-124: The expired event won't resolve or reject the pending promise.

onExpire dispatches an "expired" event, but renderAndWaitResponse only listens for "success" and "error". When a token expires, the promise remains pending while useWhen resets the widget for another attempt.

If this is intentional (letting the user retry without the caller knowing), consider documenting this behavior. Otherwise, either:

  1. Dispatch "error" instead of "expired" to reject the promise, or
  2. Add an "expired" listener in renderAndWaitResponse that rejects with a distinct reason.

38-41: Clean forwardRef implementation with imperative handle.

The component correctly exposes renderAndWaitResponse via forwardRef and useImperativeHandle, allowing parent components to trigger the captcha flow imperatively. The dual ref support (ref || externalTurnstileRef) provides flexibility for different usage patterns.

Also applies to: 156-156

@stalniy stalniy force-pushed the feat/adds-turnstile-to-auth-pages branch from 282cf57 to df6ee7b Compare December 29, 2025 15:00
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

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/pages/api/proxy/path.spec.ts (1)

9-9: Use proxyHandler.name instead of hardcoded string in describe block.

As per coding guidelines, the root describe suite description should use <Subject>.name instead of a hardcoded string to enable automated refactoring tools to find all references.

🔎 Proposed fix
-describe("proxy API handler", () => {
+describe(proxyHandler.name, () => {

Based on coding guidelines: "Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings".

♻️ Duplicate comments (3)
apps/deploy-web/src/pages/api/bitbucket/authenticate.ts (1)

14-15: Non-null assertion still risks runtime failure.

The non-null assertion on NEXT_PUBLIC_BITBUCKET_CLIENT_ID remains from the previous review. If this environment variable is missing, the code will fail at runtime when BitbucketAuth attempts to use it.

Add runtime validation to ensure these values are defined before use.

🔎 Proposed validation
  async handler({ body, res, services }) {
    const { NEXT_PUBLIC_BITBUCKET_CLIENT_ID, BITBUCKET_CLIENT_SECRET } = services.privateConfig;
+   
+   if (!NEXT_PUBLIC_BITBUCKET_CLIENT_ID || !BITBUCKET_CLIENT_SECRET) {
+     return res.status(500).json({ error: "Bitbucket OAuth is not configured" });
+   }
-   const bitbucketAuth = new BitbucketAuth(NEXT_PUBLIC_BITBUCKET_CLIENT_ID!, BITBUCKET_CLIENT_SECRET, services.externalApiHttpClient);
+   const bitbucketAuth = new BitbucketAuth(NEXT_PUBLIC_BITBUCKET_CLIENT_ID, BITBUCKET_CLIENT_SECRET, services.externalApiHttpClient);
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

170-170: Remove leftover debug text.

Line 170 contains "test me here?" which is debug text that should be removed before merging.

🔎 Proposed fix
-                test me here?
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)

65-90: Stale closure in error handler.

Line 82 captures status from the closure, which may be stale when the error event fires. The status state variable could have changed between when renderAndWaitResponse is called and when the error event is dispatched.

Consider removing status from the rejection payload since it's captured at render time, not at error time:

🔎 Proposed fix
           eventBus.current.addEventListener(
             "error",
             event => {
               const details = (event as CustomEvent<{ reason: string; error?: string }>).detail;
-              reject({ status, ...details });
+              reject(details);
             },
             { once: true }
           );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 282cf57 and df6ee7b.

📒 Files selected for processing (38)
  • apps/deploy-web/env/.env.sample
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
  • apps/deploy-web/src/config/env-config.schema.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.spec.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.ts
  • apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.spec.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/pages/api/auth/password-login.ts
  • apps/deploy-web/src/pages/api/auth/password-signup.ts
  • apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts
  • apps/deploy-web/src/pages/api/auth/signup.ts
  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
  • apps/deploy-web/src/pages/api/bitbucket/refresh.ts
  • apps/deploy-web/src/pages/api/github/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/authenticate.ts
  • apps/deploy-web/src/pages/api/gitlab/refresh.ts
  • apps/deploy-web/src/pages/api/proxy/[...path].ts
  • apps/deploy-web/src/pages/profile/[username]/index.tsx
  • apps/deploy-web/src/pages/template/[id]/index.tsx
  • apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
  • apps/deploy-web/src/services/auth/auth/auth.service.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.spec.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/tests/ui/fixture/test-env.config.ts
💤 Files with no reviewable changes (6)
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.ts
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.spec.ts
  • apps/deploy-web/src/hooks/useInjectedConfig.spec.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/tests/ui/fixture/test-env.config.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • apps/deploy-web/src/pages/api/gitlab/authenticate.ts
  • apps/deploy-web/src/pages/api/auth/[...auth0].ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts
  • apps/deploy-web/src/pages/api/bitbucket/refresh.ts
  • apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx
  • apps/deploy-web/src/components/billing-usage/TrendIndicator/TrendIndicator.spec.tsx
  • apps/deploy-web/src/pages/api/auth/signup.ts
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.spec.ts
  • apps/deploy-web/src/pages/api/gitlab/refresh.ts
  • apps/deploy-web/src/config/env-config.schema.ts
  • apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts
  • apps/deploy-web/src/pages/template/[id]/index.tsx
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/pages/api/github/authenticate.ts
  • apps/deploy-web/src/pages/api/auth/password-login.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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/proxy/[...path].ts
  • apps/deploy-web/src/pages/api/auth/password-signup.ts
  • apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts
  • apps/deploy-web/src/middleware/verify-captcha/verify-captcha.spec.ts
  • apps/deploy-web/src/services/app-di-container/server-di-container.service.ts
  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
  • apps/deploy-web/src/services/auth/auth/auth.service.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts
  • apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
  • apps/deploy-web/src/pages/profile/[username]/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/middleware/verify-captcha/verify-captcha.spec.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
🧠 Learnings (15)
📚 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/middleware/verify-captcha/verify-captcha.spec.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/middleware/verify-captcha/verify-captcha.spec.ts
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx
📚 Learning: 2025-09-04T04:27:40.858Z
Learnt from: stalniy
Repo: akash-network/console PR: 1868
File: apps/api/src/billing/services/managed-signer/managed-signer.service.ts:98-107
Timestamp: 2025-09-04T04:27:40.858Z
Learning: In the Akash protocol, when processing MsgCreateLease messages, the bidId.dseq field is always required and guaranteed to be present at runtime, even though TypeScript types may suggest it could be undefined. The non-null assertion operator (!) is appropriate to use in this context.

Applied to files:

  • apps/deploy-web/src/pages/api/bitbucket/authenticate.ts
📚 Learning: 2025-12-26T20:06:01.746Z
Learnt from: stalniy
Repo: akash-network/console PR: 2421
File: apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx:90-96
Timestamp: 2025-12-26T20:06:01.746Z
Learning: In the SignInForm component (apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx), the "Forgot password?" link intentionally uses tabIndex={-1} to keep it out of the keyboard tab order between email and password fields, ensuring a smooth tab flow through the form inputs without interruption.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.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/auth/AuthPage/AuthPage.spec.tsx
  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx
  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-09-10T08:40:53.104Z
Learnt from: stalniy
Repo: akash-network/console PR: 1892
File: apps/deploy-web/src/components/new-deployment/BidCountdownTimer.tsx:20-31
Timestamp: 2025-09-10T08:40:53.104Z
Learning: In TanStack Query v5, the onSuccess and onError callbacks were removed from useQuery options. Instead, use useEffect with the data as a dependency to handle side effects when query data changes.

Applied to files:

  • apps/deploy-web/src/components/auth/AuthPage/AuthPage.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/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/src/components/turnstile/Turnstile.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/lib/nextjs/pages/api/proxy/path.spec.ts
  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-11-25T17:45:58.258Z
Learnt from: CR
Repo: akash-network/console PR: 0
File: .cursor/rules/test-descriptions.mdc:0-0
Timestamp: 2025-11-25T17:45:58.258Z
Learning: Applies to **/*.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

Applied to files:

  • apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts
📚 Learning: 2025-10-15T16:39:55.348Z
Learnt from: jzsfkzm
Repo: akash-network/console PR: 2039
File: apps/deploy-web/tests/ui/change-wallets.spec.ts:4-10
Timestamp: 2025-10-15T16:39:55.348Z
Learning: In the Akash Console E2E tests using the context-with-extension fixture, the first wallet is automatically created during fixture setup via `importWalletToLeap` in `apps/deploy-web/tests/ui/fixture/wallet-setup.ts`, so tests that call `frontPage.createWallet()` are creating a second wallet to test wallet switching functionality.

Applied to files:

  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-05-22T14:25:01.336Z
Learnt from: stalniy
Repo: akash-network/console PR: 1353
File: apps/deploy-web/src/config/browser-env.config.ts:0-0
Timestamp: 2025-05-22T14:25:01.336Z
Learning: For the `__AK_INJECTED_CONFIG__` global window property in the Akash Network Console, security is handled through cryptographic signature verification using a public key rather than property protection mechanisms like Object.defineProperty.

Applied to files:

  • apps/deploy-web/tests/ui/fixture/base-test.ts
📚 Learning: 2025-10-31T11:26:42.138Z
Learnt from: stalniy
Repo: akash-network/console PR: 2138
File: apps/api/src/billing/lib/batch-signing-client/batch-signing-client.service.ts:379-382
Timestamp: 2025-10-31T11:26:42.138Z
Learning: In TypeScript/JavaScript, the pattern of checking a cached value and then performing an async operation to fetch it without proper synchronization is race condition unsafe:
```typescript
private async getAddress() {
  if (!this.address) {
    this.address = await this.wallet.getFirstAddress();
  }
  return this.address;
}
```
Multiple concurrent calls can all pass the `if (!this.address)` check before any of them sets the value, leading to duplicate async operations. This should be flagged as a race condition. Proper synchronization (mutex, atomic promise caching, or guaranteed single-threaded execution) is required.

Applied to files:

  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
📚 Learning: 2025-09-29T03:58:26.414Z
Learnt from: stalniy
Repo: akash-network/console PR: 1971
File: apps/deploy-web/src/components/home/YourAccount.tsx:234-239
Timestamp: 2025-09-29T03:58:26.414Z
Learning: In the Akash Network Console project, the UI components use CSS approach for disabling elements with aria-disabled="true" using "aria-[disabled='true']:pointer-events-none aria-[disabled='true']:opacity-50" classes, as seen in the button component. This pattern should be extended to links for consistency.

Applied to files:

  • apps/deploy-web/src/components/turnstile/Turnstile.tsx
📚 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.sample
📚 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.sample
🧬 Code graph analysis (13)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/pages/api/auth/password-signup.ts (1)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-29)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.spec.ts (3)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-29)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)
  • TurnstileVerifierService (5-57)
apps/deploy-web/src/lib/nextjs/defineServerSideProps/defineServerSideProps.ts (1)
  • AppTypedContext (24-31)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (2)
apps/deploy-web/src/services/session/session.service.ts (1)
  • SessionService (10-217)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)
  • TurnstileVerifierService (5-57)
apps/deploy-web/src/pages/api/bitbucket/authenticate.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (3)
apps/deploy-web/src/components/auth/SignInForm/SignInForm.tsx (2)
  • SignInForm (38-123)
  • DEPENDENCIES (27-36)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)
  • DEPENDENCIES (25-46)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
  • TurnstileRef (26-28)
apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (2)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (2)
  • ClientOnlyTurnstile (160-160)
  • TurnstileRef (26-28)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (33-35)
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)
apps/deploy-web/src/pages/api/proxy/[...path].ts (1)
  • config (59-64)
apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts (2)
apps/deploy-web/src/lib/nextjs/defineApiHandler/defineApiHandler.ts (1)
  • defineApiHandler (13-57)
apps/deploy-web/src/middleware/verify-captcha/verify-captcha.ts (1)
  • verifyCaptcha (6-29)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (2)
apps/api/test/services/mock-config.service.ts (1)
  • mockConfig (10-17)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)
apps/deploy-web/src/utils/getInjectedConfig/getInjectedConfig.ts (1)
  • getInjectedConfig (3-5)
apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (1)
apps/deploy-web/src/components/turnstile/Turnstile.tsx (3)
  • COMPONENTS (20-24)
  • TurnstileRef (26-28)
  • Turnstile (38-158)
apps/deploy-web/src/pages/profile/[username]/index.tsx (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
  • services (25-61)
🪛 dotenv-linter (4.0.0)
apps/deploy-web/env/.env.sample

[warning] 53-53: [UnorderedKey] The E2E_TESTING_CLIENT_TOKEN key should go before the NEXT_PUBLIC_TURNSTILE_ENABLED key

(UnorderedKey)

⏰ 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 (24)
apps/deploy-web/src/lib/nextjs/pages/api/proxy/path.spec.ts (1)

33-33: LGTM! Property name mismatch resolved and type safety improved.

The changes correctly address the previous review feedback by:

  • Renaming the mock type to services.privateConfig (line 33)
  • Updating the property name to privateConfig (line 77) to match the production structure in server-di-container.service.ts
  • Improving type safety by using satisfies instead of type assertion (line 79), which provides better compile-time checking

Also applies to: 77-77, 79-79

apps/deploy-web/src/pages/profile/[username]/index.tsx (1)

26-29: LGTM! Config migration correctly applied and consistent across codebase.

The migration from services.config to services.privateConfig on line 28 is correct and properly separates server-side configuration from client-exposed config. This pattern has been consistently applied across all server-side handlers in the codebase—no remaining references to the old pattern exist, and type safety is maintained throughout with proper GetServerSidePropsResult<Props> typing.

apps/deploy-web/tests/ui/fixture/base-test.ts (1)

13-22: LGTM! Config injection simplified correctly.

The changes successfully remove the complex signing flow in favor of a straightforward frozen config injection. The dummy Turnstile site key is correctly sourced from Cloudflare's testing documentation, and past review concerns (guard removal and typo fix) have been addressed.

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

18-20: LGTM! Method validation correctly positioned before request processing.

The method guard correctly returns a 405 status before session retrieval and schema validation, which is the appropriate order for HTTP method enforcement.


64-64: LGTM! HTTP method constraint added to API handler options.

The optional method field provides a clean way to enforce HTTP method constraints at the handler definition level, preventing method-based routing errors.

apps/deploy-web/src/pages/api/proxy/[...path].ts (1)

41-41: LGTM! Config source correctly migrated to privateConfig.

The change from services.config to services.privateConfig is consistent with the broader configuration migration pattern across the codebase, aligning with the server DI container updates.

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

49-53: LGTM! Turnstile environment variables correctly configured.

The new environment variables for Turnstile integration are properly documented with dummy test keys from Cloudflare's official documentation. The grouping of related variables together is more intuitive than strict alphabetical ordering.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.spec.tsx (4)

115-118: LGTM! Captcha token correctly verified in sign-in flow.

The assertion now includes captchaToken: "test-captcha-token" from the mocked Turnstile component, ensuring the authentication payload includes the captcha token.


176-179: LGTM! Captcha token correctly verified in sign-up flow.

The assertion includes the captcha token from the mocked Turnstile, verifying the complete authentication payload structure.


216-256: LGTM! Comprehensive forgot password flow coverage.

The new test suite properly verifies:

  • Rendering transition from SignInForm to ForgotPasswordForm
  • Router state updates via replace
  • Captcha token inclusion in password reset email payload

296-303: LGTM! TurnstileMock correctly implements test interface.

The mock properly exposes the renderAndWaitResponse method through the ref, returning a test captcha token that flows through to authentication assertions. The direct ref mutation (line 298) is a pragmatic approach for test mocking.

apps/deploy-web/src/services/auth/auth/auth.service.ts (3)

32-37: LGTM! Captcha token correctly added to login flow.

The login method signature and payload correctly include the captchaToken parameter, aligning with the server-side captcha verification in the password-login API endpoint.


40-46: LGTM! Captcha token correctly added to signup flow.

The signup method signature and payload correctly include the captchaToken parameter, aligning with the server-side captcha verification in the password-signup API endpoint.


49-54: LGTM! Captcha token correctly added to password reset flow.

The sendPasswordResetEmail method signature and payload correctly include the captchaToken parameter, aligning with the server-side captcha verification in the send-password-reset-email API endpoint.

apps/deploy-web/src/pages/api/auth/password-signup.ts (3)

14-14: LGTM! HTTP method constraint correctly enforces POST.

The explicit method: "POST" declaration leverages the new API handler method validation, ensuring only POST requests are accepted for signup operations.


36-36: LGTM! Captcha token correctly added to request schema.

The captchaToken: z.string() field ensures the captcha token is present and validated before handler execution.


39-43: LGTM! Captcha verification correctly positioned before signup logic.

The verification happens immediately after extracting the context, short-circuiting the signup flow with a 400 response if verification fails. This prevents unnecessary processing and protects the signup endpoint from abuse.

apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts (1)

1-17: LGTM! Clean integration of captcha verification.

The API handler properly enforces POST method, validates the request schema including captchaToken, and integrates captcha verification middleware.

apps/deploy-web/src/middleware/verify-captcha/verify-captcha.spec.ts (1)

1-186: Excellent test coverage following all coding guidelines.

The test suite comprehensively covers:

  • Disabled state bypass
  • Success and failure scenarios
  • Bypass token propagation
  • Remote IP extraction precedence (cf-connecting-ip → x-real-ip → x-forwarded-for → socket)

The implementation correctly uses the setup function pattern, jest-mock-extended, and proper test descriptions.

Based on coding guidelines, the setup function and test structure align with project conventions.

apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)

13-61: LGTM! Clean DI container integration.

The changes properly:

  • Introduce privateConfig provider exposing server-side environment configuration
  • Wire TurnstileVerifierService with appropriate secrets from privateConfig
  • Migrate Auth0 and network ID configuration to use privateConfig consistently
apps/deploy-web/src/services/turnstile-verifier/turnstile-verifier.service.ts (1)

33-34: Bypass logic correctly prevents undefined comparison.

The current implementation properly guards against the undefined === undefined issue mentioned in past reviews by checking bypassSecretKeyVerificationToken is truthy before performing the equality check. This ensures the bypass secret is only used when explicitly configured.

apps/deploy-web/src/components/turnstile/Turnstile.spec.tsx (1)

1-187: Well-structured tests following coding guidelines.

The test suite properly exercises the new TurnstileRef API including renderAndWaitResponse flow. Tests correctly use the setup function pattern, jest-mock-extended, and proper test descriptions.

Based on coding guidelines, the implementation aligns with project test conventions.

apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx (1)

69-79: Clean captcha integration with proper error handling.

The implementation correctly guards against missing turnstileRef, awaits the captcha token via renderAndWaitResponse, and passes it to the authentication services.

apps/deploy-web/src/components/turnstile/Turnstile.tsx (1)

144-149: Accessibility improved with aria-labels.

The action buttons now include proper aria-label attributes ("Reload captcha" and "Dismiss captcha"), addressing the accessibility concern from past reviews.

const verification = await verifyCaptcha(body.captchaToken, ctx);
if (verification.err) return res.status(400).json(verification.val);

const result = await services.sessionService.sendPasswordResetEmail({ email: req.body.email });
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 | 🔴 Critical

Use validated body.email instead of req.body.email.

Line 22 accesses req.body.email, but body was already destructured from the validated context at line 16. This is inconsistent with line 19's use of body.captchaToken and bypasses the Zod validation.

🔎 Proposed fix
-      const result = await services.sessionService.sendPasswordResetEmail({ email: req.body.email });
+      const result = await services.sessionService.sendPasswordResetEmail({ email: body.email });
📝 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
const result = await services.sessionService.sendPasswordResetEmail({ email: req.body.email });
const result = await services.sessionService.sendPasswordResetEmail({ email: body.email });
🤖 Prompt for AI Agents
In apps/deploy-web/src/pages/api/auth/send-password-reset-email.ts around line
22, the code calls services.sessionService.sendPasswordResetEmail with
req.body.email which bypasses the previously validated and destructured body
variable; replace req.body.email with the validated body.email so the call uses
the Zod-validated input (and update any other occurrences to consistently use
body rather than req.body).

@stalniy stalniy merged commit 7d14431 into main Dec 29, 2025
73 checks passed
@stalniy stalniy deleted the feat/adds-turnstile-to-auth-pages branch December 29, 2025 15:15
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