From d5e9360ed7df8ba40aef6ecbfd81eaef4f6caa7b Mon Sep 17 00:00:00 2001 From: Zyy Date: Fri, 11 Sep 2026 20:41:32 +0800 Subject: [PATCH] fix(admin): support quota resets over plain HTTP Generate canonical UUIDv4 redeem IDs with crypto.getRandomValues so reset confirmation works on non-secure HTTP origins. Preserve the pending operation ID when retrying uncertain consumption. Validation: frontend lint/type checks/build, browser composable checks with mocked APIs on HTTP/localhost/HTTPS, and 10 related backend tests passed. No real reset credits were consumed. Refs #62 Co-authored-by: Codex --- .../accounts/composables/useAccountResetCredits.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/accounts/composables/useAccountResetCredits.ts b/frontend/src/views/accounts/composables/useAccountResetCredits.ts index 5ac104c21..7620296c5 100644 --- a/frontend/src/views/accounts/composables/useAccountResetCredits.ts +++ b/frontend/src/views/accounts/composables/useAccountResetCredits.ts @@ -147,7 +147,7 @@ export function useAccountResetCredits(options: { accountId, creditId: credit.id, credit, - redeemRequestId: globalThis.crypto.randomUUID(), + redeemRequestId: generateRedeemRequestId(), hasTransportFailure: false, } } @@ -257,6 +257,15 @@ export function useAccountResetCredits(options: { } } +function generateRedeemRequestId() { + // 普通 HTTP 管理端没有 randomUUID;getRandomValues 仍可生成密码学安全的 UUIDv4。 + const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16)) + bytes[6] = (bytes[6] & 0x0F) | 0x40 + bytes[8] = (bytes[8] & 0x3F) | 0x80 + const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('') + return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}` +} + function isAmbiguousConsumeError(error: unknown) { if (!(error instanceof ApiError)) return false