feat: add Cloudflare Worker check-in console - #7
Conversation
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe project now uses a Cloudflare Worker with D1-backed encrypted account storage, authenticated dashboard APIs, a static management console, and Python Runner integration for fetching configurations and reporting check-in results. ChangesWorker platform and check-in integration
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Dashboard
participant Worker
participant D1
participant Runner
Dashboard->>Worker: Login and request dashboard data
Worker->>D1: Store session hash and query records
Runner->>Worker: Fetch enabled account configuration
Worker->>D1: Read encrypted account records
Worker-->>Runner: Return decrypted configuration
Runner->>Worker: Report check-in results
Worker->>D1: Store run and per-account results
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
checkin.py (1)
637-652: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winPreserve Worker
account_idduring account parsing.
load_config_from_worker()receivesaccount_id, butparse_accounts()drops it while rebuilding each account object. Consequently these fields are alwaysNone; the Worker falls back to matching by name (worker/src/index.js, Lines 78–105), which can associate results with the wrong account when names repeat.Proposed fix
account = { 'url': item['url'], 'session': item['session'], - 'name': item.get('name', '') + 'name': item.get('name', ''), + 'account_id': item.get('account_id'), }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@checkin.py` around lines 637 - 652, Update parse_accounts() to retain and propagate the account_id received from load_config_from_worker() when rebuilding each account object, so downstream success and failure results use the original identifier instead of None or name-based matching.worker/wrangler.toml (1)
1-12: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winAdd the D1 binding for
env.Check.worker/wrangler.tomlstill has no[[d1_databases]]entry, butworker/src/index.jsusesenv.Checkfor login, runner, and dashboard queries. Wire thenewapi-checkindatabase here so those routes can run.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@worker/wrangler.toml` around lines 1 - 12, Add a [[d1_databases]] configuration for the newapi-checkin database in wrangler.toml, binding it as Check to match the env.Check references in the login, runner, and dashboard routes in src/index.js. Use the database’s existing D1 identifier and preserve the current assets and vars configuration.
🧹 Nitpick comments (3)
README.md (1)
145-154: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the dashboard read endpoints.
The table omits
GET /api/dashboard/accountsandGET /api/dashboard/runs/:id, although the Worker exposes both. Add them so the documented API contract is complete.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 145 - 154, Update the README API table to document the missing dashboard read endpoints: GET /api/dashboard/accounts for listing accounts and GET /api/dashboard/runs/:id for retrieving a run by ID. Include their Dashboard Token authentication requirement and concise usage descriptions, while preserving the existing endpoint entries.worker/src/index.js (1)
33-49: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winRedundant key (re)derivation on every encrypt/decrypt call.
Both
encryptanddecryptre-hashenv.DATA_ENCRYPTION_KEYand re-import the AES-GCM key on every call. This is called once per account inside the loop at for (const row of rows.results) accounts.push({ ...JSON.parse(await decrypt(row.secret, env)), name: row.name, account_id: row.id }); — for N accounts that's N redundant digest+import cycles for the same static key. Derive the key once per request (or memoize it) and pass it intoencrypt/decrypt.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@worker/src/index.js` around lines 33 - 49, Refactor encrypt and decrypt to accept a previously derived AES-GCM CryptoKey instead of hashing env.DATA_ENCRYPTION_KEY and importing the key on every call. Derive or memoize the key once per request before processing rows, then pass it into each encrypt/decrypt invocation while preserving the existing encryption and decryption behavior.worker/schema.sql (1)
39-43: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueSessions table has no expiry-cleanup path.
sessionsrows are inserted on every login (worker/src/index.jslogin handler) but nothing ever deletes expired rows — there's no logout endpoint or scheduled cleanup. Given expected low login volume for a personal dashboard, this is likely a slow, low-impact growth; consider periodically deleting rows whereexpires_at <= now()(e.g., opportunistically insiderequireSession, or via a Cron Trigger) if this ever sees heavier use.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@worker/schema.sql` around lines 39 - 43, Implement an expiry-cleanup path for sessions by deleting rows whose expires_at is at or before the current time, preferably opportunistically in requireSession or through an existing scheduled worker mechanism. Ensure cleanup runs periodically without disrupting valid-session checks and preserves the sessions table schema and login behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@checkin.py`:
- Around line 556-558: Update the missing-account error handling near
accounts_str to mention all supported configuration sources:
CHECKIN_WORKER_URL/CHECKIN_RUNNER_TOKEN, CONFIG_URL/CONFIG_AUTH, and
NEWAPI_ACCOUNTS, so users of fallback configurations receive actionable
guidance.
In `@README.md`:
- Line 26: Update the GitHub Actions edge label in the README diagram from
encrypted-account wording to “获取启用账号配置”, and clarify nearby documentation that
encryption applies to storage at rest while the Worker returns decrypted account
JSON to the Runner.
In `@WORKER_DEPLOYMENT.md`:
- Around line 58-61: Make the documented D1 database name configurable in all
initialization commands: update WORKER_DEPLOYMENT.md lines 58-61 and 320-323,
plus README.md lines 53-59, to use a database-name placeholder or clearly
instruct readers to substitute their chosen name for both remote and local
commands.
In `@worker/public/index.html`:
- Line 17: Validate runner-supplied count fields as finite non-negative integers
in the report handler around the dashboard persistence logic, rejecting or
sanitizing invalid values before storage. In dashboard() within
worker/public/index.html, escape or numeric-coerce latest.success_count,
latest.fail_count, latest.total, and each history run’s success_count,
fail_count, and total before interpolating them into innerHTML; preserve the
existing displayed counts and success-rate behavior for valid values.
In `@worker/schema.sql`:
- Around line 1-13: The accounts schema at worker/schema.sql lines 1-13 must
enforce unique account names by adding a UNIQUE constraint to accounts.name. In
the account-creation flow around the insertion handler at worker/src/index.js
lines 128-135, check for an existing account with the same name before inserting
and return a 409 or validation error to the dashboard when found; otherwise
preserve the existing insert behavior.
In `@worker/src/index.js`:
- Around line 20-22: Replace the plain secret comparisons in requireRunner and
the login check with timing-safe comparisons: hash both the supplied and
configured tokens/passwords using the existing sha256 helper, then compare the
resulting digests without direct string comparison. Preserve the current
authentication outcomes, including rejection of missing or invalid credentials.
- Around line 68-76: Implement rate limiting for the `/api/auth/login` branch
before validating the password, tracking failed attempts by client IP (or an
equivalent persistent identifier) in the existing D1/KV storage. Apply
exponential backoff or a lockout window, increment and persist failures for
invalid passwords, and clear the tracking record after successful authentication
while preserving the existing session creation flow.
- Around line 146-159: Update the catch block in the default export’s fetch
method to log the caught error server-side with console.error, then return a
generic internal-error message instead of exposing error.message to clients.
---
Outside diff comments:
In `@checkin.py`:
- Around line 637-652: Update parse_accounts() to retain and propagate the
account_id received from load_config_from_worker() when rebuilding each account
object, so downstream success and failure results use the original identifier
instead of None or name-based matching.
In `@worker/wrangler.toml`:
- Around line 1-12: Add a [[d1_databases]] configuration for the newapi-checkin
database in wrangler.toml, binding it as Check to match the env.Check references
in the login, runner, and dashboard routes in src/index.js. Use the database’s
existing D1 identifier and preserve the current assets and vars configuration.
---
Nitpick comments:
In `@README.md`:
- Around line 145-154: Update the README API table to document the missing
dashboard read endpoints: GET /api/dashboard/accounts for listing accounts and
GET /api/dashboard/runs/:id for retrieving a run by ID. Include their Dashboard
Token authentication requirement and concise usage descriptions, while
preserving the existing endpoint entries.
In `@worker/schema.sql`:
- Around line 39-43: Implement an expiry-cleanup path for sessions by deleting
rows whose expires_at is at or before the current time, preferably
opportunistically in requireSession or through an existing scheduled worker
mechanism. Ensure cleanup runs periodically without disrupting valid-session
checks and preserves the sessions table schema and login behavior.
In `@worker/src/index.js`:
- Around line 33-49: Refactor encrypt and decrypt to accept a previously derived
AES-GCM CryptoKey instead of hashing env.DATA_ENCRYPTION_KEY and importing the
key on every call. Derive or memoize the key once per request before processing
rows, then pass it into each encrypt/decrypt invocation while preserving the
existing encryption and decryption behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ef0fee84-1a7e-4095-8135-647b3050c13b
📒 Files selected for processing (15)
.env.example.github/workflows/checkin.yml.gitignoreLICENSEREADME.mdWORKER_DEPLOYMENT.mdcheckin.pyconfig_generator.htmlindex.htmlworker/.dev.vars.exampleworker/package.jsonworker/public/index.htmlworker/schema.sqlworker/src/index.jsworker/wrangler.toml
| if not accounts_str: | ||
| print('[错误] 未配置账号信息') | ||
| print('请设置 CONFIG_URL(云端配置)或 NEWAPI_ACCOUNTS(本地配置)环境变量') | ||
| print('请设置 CHECKIN_WORKER_URL 和 CHECKIN_RUNNER_TOKEN 环境变量') |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Mention the supported fallback configuration sources.
CONFIG_URL/CONFIG_AUTH and NEWAPI_ACCOUNTS remain valid fallbacks, but this error tells users to configure only Worker variables. List all supported sources so compatibility users receive an actionable error.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@checkin.py` around lines 556 - 558, Update the missing-account error handling
near accounts_str to mention all supported configuration sources:
CHECKIN_WORKER_URL/CHECKIN_RUNNER_TOKEN, CONFIG_URL/CONFIG_AUTH, and
NEWAPI_ACCOUNTS, so users of fallback configurations receive actionable
guidance.
| CREATE TABLE IF NOT EXISTS accounts ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| name TEXT NOT NULL, | ||
| url TEXT NOT NULL, | ||
| secret TEXT NOT NULL, | ||
| enabled INTEGER NOT NULL DEFAULT 1, | ||
| failure_count INTEGER NOT NULL DEFAULT 0, | ||
| last_status TEXT, | ||
| last_message TEXT, | ||
| last_checkin_at TEXT, | ||
| created_at TEXT NOT NULL, | ||
| updated_at TEXT NOT NULL | ||
| ); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Duplicate account names can misattribute check-in results.
Nothing enforces uniqueness on accounts.name, and /api/runner/report's fallback lookup (SELECT id, failure_count FROM accounts WHERE name = ? at worker/src/index.js line 95) will silently pick an arbitrary match via .first() if two accounts share a name, corrupting failure_count/last_status updates and run-result attribution for the wrong account.
worker/schema.sql#L1-L13: addUNIQUEon thenamecolumn ofaccounts.worker/src/index.js#L128-L135: check for an existing account with the same name before inserting and return a409/validation error to the dashboard instead of allowing silent duplicates.
📍 Affects 2 files
worker/schema.sql#L1-L13(this comment)worker/src/index.js#L128-L135
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@worker/schema.sql` around lines 1 - 13, The accounts schema at
worker/schema.sql lines 1-13 must enforce unique account names by adding a
UNIQUE constraint to accounts.name. In the account-creation flow around the
insertion handler at worker/src/index.js lines 128-135, check for an existing
account with the same name before inserting and return a 409 or validation error
to the dashboard when found; otherwise preserve the existing insert behavior.
| async function requireRunner(request, env) { | ||
| return tokenFrom(request) && tokenFrom(request) === env.RUNNER_TOKEN; | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Non-constant-time secret comparisons.
Both async function requireRunner(request, env) {
return tokenFrom(request) && tokenFrom(request) === env.RUNNER_TOKEN;
} and the login check body.password !== env.DASHBOARD_PASSWORD use plain string comparison, which leaks timing information proportional to matched prefix length. sha256 is already available in this file — hash both sides (or use a constant-time byte comparison) before comparing.
🔒 Timing-safe comparison
async function requireRunner(request, env) {
- return tokenFrom(request) && tokenFrom(request) === env.RUNNER_TOKEN;
+ const token = tokenFrom(request);
+ if (!token || !env.RUNNER_TOKEN) return false;
+ return (await sha256(token)) === (await sha256(env.RUNNER_TOKEN));
}Also applies to: 68-76
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@worker/src/index.js` around lines 20 - 22, Replace the plain secret
comparisons in requireRunner and the login check with timing-safe comparisons:
hash both the supplied and configured tokens/passwords using the existing sha256
helper, then compare the resulting digests without direct string comparison.
Preserve the current authentication outcomes, including rejection of missing or
invalid credentials.
| if (method === 'POST' && path === '/api/auth/login') { | ||
| const body = await text(request); | ||
| if (!body?.password || body.password !== env.DASHBOARD_PASSWORD) return json({ error: '访问口令错误' }, 401, env); | ||
| const token = crypto.randomUUID(); | ||
| const expires = new Date(Date.now() + Number(env.SESSION_TTL_SECONDS || 86400) * 1000).toISOString(); | ||
| await env.Check.prepare('INSERT INTO sessions (token_hash, expires_at, created_at) VALUES (?, ?, ?)') | ||
| .bind(await sha256(token), expires, now()).run(); | ||
| return json({ token, expires_at: expires }, 200, env); | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
No rate limiting/lockout on /api/auth/login.
The password check has no throttling, so an attacker can brute-force DASHBOARD_PASSWORD with unlimited attempts against a public endpoint. Consider tracking failed attempts (e.g., per-IP or globally in D1/KV) with exponential backoff or a hard lockout window.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@worker/src/index.js` around lines 68 - 76, Implement rate limiting for the
`/api/auth/login` branch before validating the password, tracking failed
attempts by client IP (or an equivalent persistent identifier) in the existing
D1/KV storage. Apply exponential backoff or a lockout window, increment and
persist failures for invalid passwords, and clear the tracking record after
successful authentication while preserving the existing session creation flow.
| export default { | ||
| async fetch(request, env) { | ||
| try { | ||
| const url = new URL(request.url); | ||
| if (url.pathname.startsWith('/api/')) return await handler(request, env); | ||
| if (env.ASSETS) { | ||
| const assetUrl = new URL(request.url); | ||
| if (assetUrl.pathname === '/' || assetUrl.pathname === '/dashboard.html') assetUrl.pathname = '/index.html'; | ||
| return env.ASSETS.fetch(new Request(assetUrl, request)); | ||
| } | ||
| return json({ error: '静态资源绑定未配置' }, 500, env); | ||
| } catch (error) { | ||
| return json({ error: error.message || 'Internal error' }, 500, env); | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Raw internal error messages returned to clients.
} catch (error) {
return json({ error: error.message || 'Internal error' }, 500, env);
} exposes internal exception text (D1 errors, decrypt failures, etc.) directly in the API response. Log the error server-side (e.g., console.error) and return a generic message to callers.
🛡️ Sanitize error response
} catch (error) {
- return json({ error: error.message || 'Internal error' }, 500, env);
+ console.error('Worker error:', error);
+ return json({ error: 'Internal error' }, 500, env);
}📝 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.
| export default { | |
| async fetch(request, env) { | |
| try { | |
| const url = new URL(request.url); | |
| if (url.pathname.startsWith('/api/')) return await handler(request, env); | |
| if (env.ASSETS) { | |
| const assetUrl = new URL(request.url); | |
| if (assetUrl.pathname === '/' || assetUrl.pathname === '/dashboard.html') assetUrl.pathname = '/index.html'; | |
| return env.ASSETS.fetch(new Request(assetUrl, request)); | |
| } | |
| return json({ error: '静态资源绑定未配置' }, 500, env); | |
| } catch (error) { | |
| return json({ error: error.message || 'Internal error' }, 500, env); | |
| } | |
| export default { | |
| async fetch(request, env) { | |
| try { | |
| const url = new URL(request.url); | |
| if (url.pathname.startsWith('/api/')) return await handler(request, env); | |
| if (env.ASSETS) { | |
| const assetUrl = new URL(request.url); | |
| if (assetUrl.pathname === '/' || assetUrl.pathname === '/dashboard.html') assetUrl.pathname = '/index.html'; | |
| return env.ASSETS.fetch(new Request(assetUrl, request)); | |
| } | |
| return json({ error: '静态资源绑定未配置' }, 500, env); | |
| } catch (error) { | |
| console.error('Worker error:', error); | |
| return json({ error: 'Internal error' }, 500, env); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@worker/src/index.js` around lines 146 - 159, Update the catch block in the
default export’s fetch method to log the caught error server-side with
console.error, then return a generic internal-error message instead of exposing
error.message to clients.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
worker/public/index.html (1)
247-264: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueSession token stored in
localStorageis readable by any injected script.Static analysis flags storing
data.tokenvialocalStorage.setItem(used later byapi()for theAuthorizationheader) as persistent, JS-readable storage (CWE-312). Given the query APIs already withhold session/ciphertext per the form note at line 396, actual exposure is limited to account-management actions, but considersessionStorage(tab-scoped, cleared on close) as a low-cost improvement, or a Worker-sethttpOnlycookie for stronger protection if Worker-side changes are acceptable.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@worker/public/index.html` around lines 247 - 264, Replace the persistent localStorage usage for the session token with tab-scoped sessionStorage, updating the token read/write/remove logic used by api(), login, and clearSession() consistently. Preserve the existing Authorization header behavior and session-expiration handling; do not leave token access dependent on localStorage.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.md`:
- Line 89: Update the repository reference in the README deployment instructions
so it points to the deployer’s fork or their own copied repository rather than
the upstream zhikanyeye/Newapi-checkin repository. Preserve the existing table
formatting and surrounding deployment guidance.
- Around line 159-160: Update the dashboard account API table in README.md to
document the account deletion endpoint alongside the existing POST and PATCH
entries, including its HTTP method, route, authentication requirement, and
delete-account description.
In `@worker/public/index.html`:
- Around line 231-238: Update formatTime so all timezone-less timestamp strings
use one consistent timezone interpretation, regardless of whether they contain a
space or an ISO-style “T” separator. Preserve explicit timezone offsets and
Z-suffixed values, and keep the existing invalid-date fallback and zh-CN
formatting behavior.
---
Nitpick comments:
In `@worker/public/index.html`:
- Around line 247-264: Replace the persistent localStorage usage for the session
token with tab-scoped sessionStorage, updating the token read/write/remove logic
used by api(), login, and clearSession() consistently. Preserve the existing
Authorization header behavior and session-expiration handling; do not leave
token access dependent on localStorage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1b3f0070-33d8-4f25-9a97-38bb98b8daaf
📒 Files selected for processing (8)
.env.exampleREADME.mdWORKER_DEPLOYMENT.mdconfig_generator.htmlindex.htmlworker/.dev.vars.exampleworker/public/index.htmlworker/src/index.js
🚧 Files skipped from review as they are similar to previous changes (3)
- worker/.dev.vars.example
- WORKER_DEPLOYMENT.md
- worker/src/index.js
| - 其他非 JSON 内容 | ||
| | 设置 | 值 | | ||
| |------|----| | ||
| | Repository | `zhikanyeye/Newapi-checkin` | |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Use the deployer’s fork instead of the upstream repository.
Line 89 directs users to connect Workers Builds to zhikanyeye/Newapi-checkin, so fork deployments will build upstream rather than the user’s copy.
Proposed fix
-| Repository | `zhikanyeye/Newapi-checkin` |
+| Repository | 选择你自己的 Fork 仓库(例如 `<your-account>/Newapi-checkin`) |📝 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.
| | Repository | `zhikanyeye/Newapi-checkin` | | |
| | Repository | 选择你自己的 Fork 仓库(例如 `<your-account>/Newapi-checkin`) | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` at line 89, Update the repository reference in the README
deployment instructions so it points to the deployer’s fork or their own copied
repository rather than the upstream zhikanyeye/Newapi-checkin repository.
Preserve the existing table formatting and surrounding deployment guidance.
| | `POST` | `/api/dashboard/accounts` | Dashboard Token | 添加加密账号 | | ||
| | `PATCH` | `/api/dashboard/accounts/:id` | Dashboard Token | 启用或停用账号 | |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Document the delete-account endpoint.
The overview describes account add/delete/enablement support, but lists only POST and PATCH. Add the dashboard deletion route so operators can discover it.
Proposed fix
| `POST` | `/api/dashboard/accounts` | Dashboard Token | 添加加密账号 |
| `PATCH` | `/api/dashboard/accounts/:id` | Dashboard Token | 启用或停用账号 |
+| `DELETE` | `/api/dashboard/accounts/:id` | Dashboard Token | 删除账号 |📝 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.
| | `POST` | `/api/dashboard/accounts` | Dashboard Token | 添加加密账号 | | |
| | `PATCH` | `/api/dashboard/accounts/:id` | Dashboard Token | 启用或停用账号 | | |
| | `POST` | `/api/dashboard/accounts` | Dashboard Token | 添加加密账号 | | |
| | `PATCH` | `/api/dashboard/accounts/:id` | Dashboard Token | 启用或停用账号 | | |
| | `DELETE` | `/api/dashboard/accounts/:id` | Dashboard Token | 删除账号 | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` around lines 159 - 160, Update the dashboard account API table in
README.md to document the account deletion endpoint alongside the existing POST
and PATCH entries, including its HTTP method, route, authentication requirement,
and delete-account description.
| function formatTime(value) { | ||
| if (!value) return '尚未运行'; | ||
| const date = new Date(value.includes('T') ? value : value.replace(' ', 'T') + '+08:00'); | ||
| if (Number.isNaN(date.getTime())) return value; | ||
| return new Intl.DateTimeFormat('zh-CN', { | ||
| month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false, | ||
| }).format(date); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how timestamps are generated/stored in the Worker to confirm timezone assumptions.
rg -n "execution_time|last_checkin_at|CURRENT_TIMESTAMP|toISOString|new Date\(\)" worker/src/index.js worker/schema.sqlRepository: Jasonliu-0/Newapi-checkin
Length of output: 1081
Hardcoded +08:00 makes timestamp parsing inconsistent. formatTime treats strings without T as UTC+8 but leaves ISO strings without a zone to the browser’s local timezone. Since Worker timestamps are stored as toISOString() values and some fields can also come from body.execution_time, this can shift displayed times and render the same moment differently depending on string shape.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@worker/public/index.html` around lines 231 - 238, Update formatTime so all
timezone-less timestamp strings use one consistent timezone interpretation,
regardless of whether they contain a space or an ISO-style “T” separator.
Preserve explicit timezone offsets and Z-suffixed values, and keep the existing
invalid-date fallback and zh-CN formatting behavior.
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@worker/src/index.js`:
- Around line 155-177: Make the account update flow around the enabled update
and session handling atomic: validate the URL, decrypt/encrypt the session, and
prepare all requested field values before executing any database write. Replace
the separate UPDATE statements with one UPDATE or atomic D1 batch so invalid
session requests cannot persist the enabled change, while preserving updates for
enabled-only and session-only requests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2d8b8afd-2f1d-4e55-a62c-9745c3aa6eac
📒 Files selected for processing (9)
FIRST_RUN.mdREADME.mdWORKER_DEPLOYMENT.mdcheckin.pyconfig_generator.htmlindex.htmlpackage.jsonworker/public/index.htmlworker/src/index.js
💤 Files with no reviewable changes (1)
- index.html
🚧 Files skipped from review as they are similar to previous changes (2)
- README.md
- worker/public/index.html
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Unify API payload normalization so null/nested data and "already checked in" responses are not treated as failures; pass new-api-user in CF Playwright requests. Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
There was a problem hiding this comment.
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 (2)
worker/src/index.js (1)
159-160: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winPreserve zero-valued check-in metrics.
|| nullconverts valid0values forquota_awardedandcheckin_countintoNULL, losing reported results. Use nullish coalescing instead.Proposed fix
- .bind(run.meta.last_row_id, account?.id || null, result.name || '未知账号', result.success ? 1 : 0, result.message || '', result.quota_awarded || null, result.checkin_count || null, result.session_expired ? 1 : 0, createdAt).run(); + .bind(run.meta.last_row_id, account?.id || null, result.name || '未知账号', result.success ? 1 : 0, result.message || '', result.quota_awarded ?? null, result.checkin_count ?? null, result.session_expired ? 1 : 0, createdAt).run();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@worker/src/index.js` around lines 159 - 160, Update the parameter bindings in the run-results INSERT within the current worker flow to use nullish fallback for quota_awarded and checkin_count, preserving valid zero values while still converting null or undefined values to NULL. Leave the other field mappings unchanged.checkin.py (1)
563-572: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winRetain Worker
account_idthrough account parsing.The Worker returns
account_id, but the JSON is subsequently passed throughparse_accounts, which drops that field. Reports therefore use the Worker’s name fallback; duplicate account names can update another account’s failure/status history. Preserveaccount_idin parsed JSON accounts.Proposed fix
if 'cf_clearance' in item: account['cf_clearance'] = item['cf_clearance'] + if 'account_id' in item: + account['account_id'] = item['account_id'] accounts.append(account)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@checkin.py` around lines 563 - 572, Preserve each Worker-provided account_id through the account parsing flow after the response handling in the account configuration fetch. Update parse_accounts and its parsed-account serialization so account_id remains available alongside the existing account fields, allowing report updates to target the correct account instead of falling back to names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@checkin.py`:
- Around line 147-185: Update the response normalization in NewAPICheckin to
derive success_flag and message from the nested candidates built from data,
matching the existing date/quota extraction order. Ensure nested payload fields
such as data.success and data.message are honored before falling back to the
outer response, while preserving already_checked_in handling and the existing
success/message defaults.
---
Outside diff comments:
In `@checkin.py`:
- Around line 563-572: Preserve each Worker-provided account_id through the
account parsing flow after the response handling in the account configuration
fetch. Update parse_accounts and its parsed-account serialization so account_id
remains available alongside the existing account fields, allowing report updates
to target the correct account instead of falling back to names.
In `@worker/src/index.js`:
- Around line 159-160: Update the parameter bindings in the run-results INSERT
within the current worker flow to use nullish fallback for quota_awarded and
checkin_count, preserving valid zero values while still converting null or
undefined values to NULL. Leave the other field mappings unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 89260676-41b1-491d-b558-412d56da1d1e
📒 Files selected for processing (3)
cf_bypass.pycheckin.pyworker/src/index.js
Guard env.Check access, return clear D1_BINDING_MISSING errors, and document wrangler.toml [[d1_databases]] so auto-deploy does not drop the Check binding. Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
worker/src/index.js (1)
159-164: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winA single undecryptable account secret aborts the entire runner config fetch.
decrypt(row.secret, env)runs unguarded inside the loop. If any one enabled account's secret fails to decrypt (corrupted data, key rotation, etc.), the exception propagates out of the handler, and the Runner gets a 500 for all accounts instead of just the broken one — turning one bad row into a full outage of the scheduled check-in run.🛠️ Proposed fix
const accounts = []; - for (const row of rows.results) accounts.push({ ...JSON.parse(await decrypt(row.secret, env)), name: row.name, account_id: row.id }); + for (const row of rows.results) { + try { + accounts.push({ ...JSON.parse(await decrypt(row.secret, env)), name: row.name, account_id: row.id }); + } catch (err) { + console.error(`Failed to decrypt account ${row.id}:`, err); + } + } return json({ accounts }, 200, env);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@worker/src/index.js` around lines 159 - 164, Update the account-building loop in the GET /api/runner/config handler to handle decryption failures per row: catch errors from decrypt and skip only the affected account, while continuing to include successfully decrypted accounts and return the normal JSON response.
🧹 Nitpick comments (1)
checkin.py (1)
86-118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the unused session ID extractor.
_extract_user_id_from_sessionis only defined; no caller uses it, while the constructor keeps any passed-inuser_iddirectly. Drop the method if session-derived IDs are no longer needed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@checkin.py` around lines 86 - 118, Remove the unused _extract_user_id_from_session method and its implementation, leaving the constructor’s existing handling of the provided user_id unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@worker/src/index.js`:
- Around line 9-18: Update worker/src/index.js at lines 9-18 so missingDbError
accepts env and passes it to json with status 503, then update its three call
sites at lines 146, 158, and 187 to pass env. Also update the result-format
error response at lines 165-184 to call json with the existing env argument and
status 400.
- Line 150: Update the SESSION_TTL_SECONDS expiration calculation so invalid or
non-finite numeric values, including truthy strings such as “abc”, fall back to
86400 seconds before constructing the Date. Preserve valid configured TTL values
and ensure the resulting expires calculation cannot produce an invalid date.
---
Outside diff comments:
In `@worker/src/index.js`:
- Around line 159-164: Update the account-building loop in the GET
/api/runner/config handler to handle decryption failures per row: catch errors
from decrypt and skip only the affected account, while continuing to include
successfully decrypted accounts and return the normal JSON response.
---
Nitpick comments:
In `@checkin.py`:
- Around line 86-118: Remove the unused _extract_user_id_from_session method and
its implementation, leaving the constructor’s existing handling of the provided
user_id unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0457ec00-5478-44b4-b0aa-7e1913bd13d0
📒 Files selected for processing (8)
.github/workflows/checkin.ymlFIRST_RUN.mdREADME.mdWORKER_DEPLOYMENT.mdcheckin.pyworker/public/index.htmlworker/src/index.jsworker/wrangler.toml
🚧 Files skipped from review as they are similar to previous changes (6)
- FIRST_RUN.md
- worker/wrangler.toml
- .github/workflows/checkin.yml
- worker/public/index.html
- README.md
- WORKER_DEPLOYMENT.md
| function getDb(env) { | ||
| return env?.Check || env?.DB || env?.D1 || env?.CHECK || null; | ||
| } | ||
|
|
||
| function missingDbError() { | ||
| return json({ | ||
| error: 'D1 未绑定:自动部署后绑定可能被清空。请在 Worker Settings → Bindings 添加 D1,变量名必须为 Check;或在 worker/wrangler.toml 的 [[d1_databases]] 填入 database_id 后重新部署。', | ||
| code: 'D1_BINDING_MISSING', | ||
| }, 503); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Inconsistent env argument to json() across error responses. Both sites omit the third env argument that every other response in the file passes, which is inconsistent and, if json() ever keys any header (e.g. CORS) off env, would silently degrade those specific error paths — notably the D1_BINDING_MISSING path this PR is meant to make reliable.
worker/src/index.js#L9-L18: changemissingDbError()tomissingDbError(env)and passenvthrough tojson(..., 503, env); update the three call sites (Lines 146, 158, 187) tomissingDbError(env).worker/src/index.js#L165-L184: change Line 167 toreturn json({ error: '结果格式错误' }, 400, env);.
📍 Affects 1 file
worker/src/index.js#L9-L18(this comment)worker/src/index.js#L165-L184
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@worker/src/index.js` around lines 9 - 18, Update worker/src/index.js at lines
9-18 so missingDbError accepts env and passes it to json with status 503, then
update its three call sites at lines 146, 158, and 187 to pass env. Also update
the result-format error response at lines 165-184 to call json with the existing
env argument and status 400.
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Enable Cloudflare auto-provisioned D1 bindings without repository database IDs, polish the README and guides, and keep local .monkeycode content out of Git. Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com> Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Add a short shareable Markdown post for community promotion and link it from the docs index. Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com> Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Remove unused community share draft and clean related documentation links. Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com> Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Scope cookies to target hosts, make D1 reports atomic, enforce secure account origins, revoke dashboard sessions on logout, and add regression coverage. Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com> Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
Co-authored-by: monkeycode-ai monkeycode-ai@chaitin.com
Summary by CodeRabbit
WORKER_DEPLOYMENT.mdandFIRST_RUN.md..gitignoreand refreshed license header.