From 1f942a30df9fa481257112ec9afdf9e5a2d20a46 Mon Sep 17 00:00:00 2001 From: Zrzzzz <1160026659@qq.com> Date: Sun, 1 Nov 2026 02:18:21 -0500 Subject: [PATCH] fix(oauth): accept weekly-only official usage responses --- src/lib/oauth/crs-usage-probe.mjs | 4 +++- test/unit/crs-usage-probe.test.mjs | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lib/oauth/crs-usage-probe.mjs b/src/lib/oauth/crs-usage-probe.mjs index 90961052f..f62c078d8 100644 --- a/src/lib/oauth/crs-usage-probe.mjs +++ b/src/lib/oauth/crs-usage-probe.mjs @@ -135,7 +135,9 @@ export function parseOAuthUsage(data = {}) { export function isCompleteOAuthUsage(data = {}, parsed = null) { const p = parsed || parseOAuthUsage(data) - if (!p.five_hour || !p.seven_day) return false + // Official usage can omit the session window while retaining weekly limits. + // Keep an absent window unknown; a supplied but unreadable window is invalid. + if (!p.seven_day || (!p.five_hour && data.five_hour != null)) return false if (p.usage_has_fable !== null) return true // 2.1.293 GET /api/oauth/usage is a Utilization object: named windows, no limits[] catalog. if ( diff --git a/test/unit/crs-usage-probe.test.mjs b/test/unit/crs-usage-probe.test.mjs index 150c2c50b..f72741cdb 100644 --- a/test/unit/crs-usage-probe.test.mjs +++ b/test/unit/crs-usage-probe.test.mjs @@ -2,6 +2,7 @@ import { test } from 'node:test' import assert from 'node:assert/strict' import { parseOAuthUsage, + isCompleteOAuthUsage, parseFableProbe, isFablePlanDenied, isFableUnavailablePro, @@ -16,6 +17,25 @@ import { probeVmUsage, } from '../../src/lib/oauth/crs-usage-probe.mjs' +test('official weekly-only usage is complete without inventing a session window', () => { + const data = { + five_hour: null, + seven_day: { utilization: 4, resets_at: '2026-11-05T12:00:00Z' }, + limits: [{ kind: 'weekly_all', percent: 4, resets_at: '2026-11-05T12:00:00Z' }], + } + const parsed = parseOAuthUsage(data) + assert.equal(isCompleteOAuthUsage(data, parsed), true) + assert.equal(parsed.five_hour, null) + assert.equal(parsed.seven_day.utilization, 0.04) + const { five_hour, ...omitted } = data + assert.equal(isCompleteOAuthUsage(omitted), true) + assert.equal(isCompleteOAuthUsage({ ...data, five_hour: { utilization: 12 } }), true) + assert.equal(isCompleteOAuthUsage({ ...data, five_hour: {} }), false) + assert.equal(isCompleteOAuthUsage({ ...data, seven_day: null }), false) + assert.equal(isCompleteOAuthUsage({ five_hour: null, seven_day: null, limits: [] }), false) + assert.equal(isCompleteOAuthUsage({}), false) +}) + test('oauth usage parse: official percent scale 1 = 1%', () => { const p = parseOAuthUsage({ five_hour: { utilization: 1, resets_at: '2026-08-18T20:00:00Z' },