-
Notifications
You must be signed in to change notification settings - Fork 5
fix: data-guard coverage, interrupted-flow cleanup, log-field bounds #372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f2c06db
dd834e0
f60fa92
1d27938
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,8 @@ import { NextResponse } from "next/server"; | |
| import { spawn } from "child_process"; | ||
| import fs from "fs/promises"; | ||
| import path from "path"; | ||
| import { DATA_DIR, getAll, setMany } from "@/lib/config-store"; | ||
| import { getAll, setMany } from "@/lib/config-store"; | ||
| import { HANDOFF_TOKENS_PATH, HANDOFF_TTL_MS } from "@/lib/oauth-handoff"; | ||
| import { | ||
| restartGateway, | ||
| findOpenclawBin, | ||
|
|
@@ -483,7 +484,6 @@ export async function POST(request: Request) { | |
| // 15-minute TTL rather than forcing a full re-auth. | ||
| let pendingHandoffTokensPath: string | null = null; | ||
| if (body.authMode === "subscription" && body.oauthHandoff) { | ||
| const tokensPath = path.join(DATA_DIR, "oauth-device-tokens.json"); | ||
| let handoff: { | ||
| provider?: string; | ||
| access_token?: string; | ||
|
|
@@ -493,19 +493,22 @@ export async function POST(request: Request) { | |
| createdAt?: number; | ||
| }; | ||
| try { | ||
| handoff = JSON.parse(await fs.readFile(tokensPath, "utf-8")); | ||
| handoff = JSON.parse(await fs.readFile(HANDOFF_TOKENS_PATH, "utf-8")); | ||
| } catch { | ||
| return NextResponse.json( | ||
| { error: "No pending OAuth tokens. Restart the sign-in flow." }, | ||
| { status: 400 }, | ||
| ); | ||
| } | ||
| // A file with no `createdAt` has no age we can check, so it cannot be | ||
| // shown to be inside the TTL — treat it the same as one that is past it. | ||
| if ( | ||
| !handoff.access_token || | ||
| (handoff.createdAt && Date.now() - handoff.createdAt > 15 * 60 * 1000) | ||
| !handoff.createdAt || | ||
| Date.now() - handoff.createdAt > HANDOFF_TTL_MS | ||
| ) { | ||
| // Stale/invalid credential material — consume it so it can't linger. | ||
| await fs.unlink(tokensPath).catch(() => {}); | ||
| await fs.unlink(HANDOFF_TOKENS_PATH).catch(() => {}); | ||
|
Comment on lines
505
to
+511
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Validate the timestamp value at runtime. A truthy non-number value produces Require a finite numeric 🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Taken — this was a real hole in the line the branch had just changed. Both cases you name slip through for the same reason: The age is now computed only from a Fixed in 6162632. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
git show --stat --oneline 6162632
git show --format=fuller --find-renames --find-copies -- \
src/app/setup-api/ai-models/configure/route.ts \
src/tests/routes/ai-models/configure.test.ts \
6162632
printf '\n--- Current validation hunk ---\n'
rg -n -A22 -B8 'createdAt|HANDOFF_TTL_MS|handoffAge' \
src/app/setup-api/ai-models/configure/route.ts
printf '\n--- Relevant tests ---\n'
rg -n -A15 -B8 'createdAt|future|NaN|non-numeric|handoff' \
src/tests/routes/ai-models/configure.test.tsLength of output: 2147 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- Current OAuth handoff validation ---'
rg -n -A30 -B10 'createdAt|HANDOFF_TTL_MS|handoffAge' \
src/app/setup-api/ai-models/configure/route.ts || true
printf '%s\n' '--- Configure route test structure ---'
ast-grep outline src/tests/routes/ai-models/configure.test.ts --items all --type function
printf '%s\n' '--- Timestamp-related regression tests ---'
rg -n -A20 -B10 'createdAt|future|NaN|non-numeric|handoff|expired' \
src/tests/routes/ai-models/configure.test.ts || trueLength of output: 12933
The current !handoff.createdAt ||
Date.now() - handoff.createdAt > HANDOFF_TTL_MSThis code still accepts truthy non-numeric timestamps and future timestamps. The current tests cover missing and expired timestamps only. They do not include the stated string, Please retry after the PR branch contains 🧬 Code Graph Analysis Results
|
||
| return NextResponse.json( | ||
| { error: "OAuth tokens missing or expired. Restart the sign-in flow." }, | ||
| { status: 400 }, | ||
|
|
@@ -519,7 +522,7 @@ export async function POST(request: Request) { | |
| body.idToken = handoff.id_token; | ||
| body.refreshToken = handoff.refresh_token; | ||
| body.expiresIn = handoff.expires_in; | ||
| pendingHandoffTokensPath = tokensPath; | ||
| pendingHandoffTokensPath = HANDOFF_TOKENS_PATH; | ||
| } | ||
|
|
||
| const { provider, apiKey, authMode = "token", idToken, refreshToken, expiresIn, projectId, scope = "primary", model: bodyModel } = body; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.