Skip to content

feat: auto-fill auth code when opening KiloClaw gateway#745

Merged
pandemicsyn merged 5 commits intomainfrom
feat/claw-auto-auth-code
Mar 3, 2026
Merged

feat: auto-fill auth code when opening KiloClaw gateway#745
pandemicsyn merged 5 commits intomainfrom
feat/claw-auto-auth-code

Conversation

@kilo-code-bot
Copy link
Contributor

@kilo-code-bot kilo-code-bot bot commented Mar 2, 2026

Summary

  • Eliminates the manual copy-paste step when accessing claw.kilosessions.ai
  • The Open button now generates a fresh access code and embeds it as an auth_code query parameter in the gateway URL
  • The worker validates the code on GET and sets the auth cookie directly, skipping the manual form
  • Falls back to showing the manual code entry form if the code is invalid or expired

Changes

src/app/(app)/claw/components/AccessCodeActions.tsx

  • The "Open" button now generates a code via the API before opening the gateway URL
  • Code is appended as &auth_code=... to the gateway URL
  • Shows a loading spinner while generating/opening
  • The separate "Access Code" button is removed

src/app/(app)/claw/hooks/useAccessCode.ts

  • generateAccessCode() now returns Promise<string | null> so callers can use the generated code

kiloclaw/src/routes/access-gateway.ts

  • Extracted shared redeemCodeAndSetCookie() helper used by both GET and POST handlers
  • GET handler now checks for auth_code query parameter and validates it directly (auto-auth flow)
  • If valid: sets cookie and shows loading page with redirect
  • If invalid/expired: falls through to manual form with error message
  • POST handler refactored to use the same shared helper

Security

  • auth_code parameter is already redacted in worker logs (matches the existing /auth/i sensitive pattern — verified by existing test)
  • Codes are single-use (redeemed on first validation) and expire after 10 minutes
  • HTTPS-only transport
  • Code requires matching userId to validate

Eliminate the manual copy-paste step when accessing claw.kilosessions.ai.
The Open button now generates a fresh access code and embeds it as an
auth_code query parameter in the gateway URL. The worker validates it
on GET and sets the auth cookie directly, falling back to the manual
form if the code is invalid or expired.
@kilo-code-bot
Copy link
Contributor Author

kilo-code-bot bot commented Mar 2, 2026

Code Review Summary

Status: No New Issues Found | Recommendation: Address existing comments before merge

Overview

This PR refactors the KiloClaw access flow to auto-authenticate users. Instead of displaying a one-time access code for manual copy/paste, the Open button now generates a code behind the scenes, opens a blank window synchronously (to avoid popup blockers), and navigates it to the gateway URL with the code embedded as an auth_code query parameter. The server-side GET handler redeems the code automatically, skipping the manual form entry.

Key changes:

  • Extracted redeemCodeAndSetCookie() helper to share validation logic between GET and POST handlers
  • Added auth_code query parameter support to the GET /kilo-access-gateway route
  • Replaced AccessCodeActions component (code display + copy) with OpenClawButton (one-click open)
  • Simplified useAccessCode hook to return the code directly instead of storing in state

Architecture assessment: The refactoring is clean. The redeemCodeAndSetCookie extraction is well-typed with a discriminated union return ({ redirectUrl } | { error, status }), and the type narrowing via 'redirectUrl' in result is correct. The popup-blocker mitigation (synchronous window.open before async code generation) is the right approach.

Existing review comments (9) already cover the significant concerns:

  • Access code exposed in URL query parameters (security/logging risk)
  • Popup blocker can silently waste the one-time code
  • Race condition on button during code generation
  • Misleading error messages in catch blocks
  • Fragile URL construction assumptions

No additional issues were found beyond what's already flagged.

Fix these issues in Kilo Cloud

Files Reviewed (6 files)
  • kiloclaw/src/routes/access-gateway.ts — refactored: extracted redeemCodeAndSetCookie, added auth_code GET param support
  • src/app/(app)/claw/components/AccessCodeActions.tsx — deleted (replaced by OpenClawButton)
  • src/app/(app)/claw/components/OpenClawButton.tsx — new: one-click open with auto-auth
  • src/app/(app)/claw/components/ClawHeader.tsx — updated import/usage
  • src/app/(app)/claw/components/index.ts — updated export
  • src/app/(app)/claw/hooks/useAccessCode.ts — simplified: returns code directly, removed copy/state logic

Address PR feedback:
- Use URL + searchParams.set() instead of string concatenation to
  safely append auth_code, avoiding breakage if gatewayUrl has no
  existing query string.
- Remove 400 from redeemCodeAndSetCookie return type since no code
  path returns it.
if (code) {
const url = new URL(gatewayUrl, window.location.origin);
url.searchParams.set('auth_code', code);
window.open(url.toString(), '_blank', 'noopener,noreferrer');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[WARNING]: Popup blocker silently wastes the one-time access code

If the browser's popup blocker prevents window.open from opening a new tab, it returns null without throwing. The access code has already been generated and redeemed server-side, but the user never reaches the gateway URL. The code is consumed with no feedback to the user.

Consider checking the return value:

const win = window.open(url.toString(), '_blank', 'noopener,noreferrer');
if (!win) {
  toast.error('Popup blocked — please allow popups and try again');
}

<Button
variant="primary"
className={OPEN_BUTTON_ACCENT_CLASS}
disabled={isOpening}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[WARNING]: Race condition — button not disabled during concurrent code generation

The "Open" button is only disabled by isOpening, not by isGenerating. If the user clicks "Access Code" first (which sets isGenerating = true), then quickly clicks "Open" before generation completes, two concurrent generateAccessCode() calls will fire. The first code gets overwritten in state and is never used — wasting a one-time access code.

Suggested change
disabled={isOpening}
disabled={isOpening || isGenerating}

- Check window.open return value and toast an error if the popup was
  blocked, so the user knows the code was wasted.
- Disable the Open button while isGenerating to prevent racing with
  an in-flight Access Code generation.
}
}
} catch {
toast.error('Failed to generate access code for auto-login');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[WARNING]: Misleading error message in catch block

generateAccessCode() catches all its own errors internally and returns null, so this catch block only fires if new URL(gatewayUrl, ...) throws (malformed URL) or something else unexpected happens. The message "Failed to generate access code for auto-login" is misleading in those cases — it should be a generic fallback like "Failed to open — please try again".

Suggested change
toast.error('Failed to generate access code for auto-login');
toast.error('Failed to open — please try again');

setIsOpening(true);
const win = window.open('about:blank', '_blank');
try {
const code = await generateAccessCode();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[WARNING]: One-time access code wasted when popup is blocked

If window.open returns null (popup blocked), generateAccessCode() is still called and the one-time code is consumed server-side. The code && win guard on line 23 prevents navigation but the code is already redeemed.

Consider checking win before calling generateAccessCode():

const win = window.open('about:blank', '_blank');
if (!win) {
  toast.error('Popup blocked — please allow popups for this site');
  setIsOpening(false);
  return;
}
try {
  const code = await generateAccessCode();
  ...

Copy link
Contributor

@St0rmz1 St0rmz1 left a comment

Choose a reason for hiding this comment

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

Findings from the first bot round have been addressed. The two remaining bot comments are cosmetic/edge-case. and all looks good to me.

Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com>
@pandemicsyn pandemicsyn merged commit b1497a4 into main Mar 3, 2026
12 checks passed
@pandemicsyn pandemicsyn deleted the feat/claw-auto-auth-code branch March 3, 2026 16:55
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