fix(design): bound requests and prevent mutation replay
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { createHash } from 'node:crypto';
|
||||
import { NIANCODE_AUTH_CONFIG } from '../api/auth-config';
|
||||
import { proxyAwareFetch } from '../utils/proxy-fetch';
|
||||
import { proxyAwareFetch, runWithDeadline } from '../utils/proxy-fetch';
|
||||
import { logger } from '../utils/logger';
|
||||
import { WORKS_SQUARE_SESSION_IDLE_TIMEOUT_MS } from '../../shared/auth-session';
|
||||
|
||||
const TOKEN_REFRESH_SKEW_MS = 30_000;
|
||||
const WORKS_SQUARE_AUTH_REQUEST_TIMEOUT_MS = 30_000;
|
||||
const SESSION_STORE_SCHEMA_VERSION = 1;
|
||||
export { WORKS_SQUARE_SESSION_IDLE_TIMEOUT_MS } from '../../shared/auth-session';
|
||||
|
||||
@@ -716,7 +717,7 @@ async function waitForCredentialPersistence(): Promise<boolean> {
|
||||
async function refreshWorksSquareSession(
|
||||
session: StoredWorksSquareSession,
|
||||
generation: number,
|
||||
options: { fetchImpl?: typeof fetch; nowMs?: number } = {},
|
||||
options: { fetchImpl?: typeof fetch; nowMs?: number; requestTimeoutMs?: number } = {},
|
||||
): Promise<string | null> {
|
||||
if (!session.refreshToken) return null;
|
||||
|
||||
@@ -726,17 +727,25 @@ async function refreshWorksSquareSession(
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: session.refreshToken,
|
||||
});
|
||||
const response = await fetchImpl(`${NIANCODE_AUTH_CONFIG.gatewayAuthUrl.replace(/\/+$/, '')}/oauth2/token`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: createBasicAuthHeader(
|
||||
NIANCODE_AUTH_CONFIG.clientId,
|
||||
NIANCODE_AUTH_CONFIG.clientSecret,
|
||||
),
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body,
|
||||
});
|
||||
const { response, payload } = await runWithDeadline(async (signal) => {
|
||||
const response = await fetchImpl(
|
||||
`${NIANCODE_AUTH_CONFIG.gatewayAuthUrl.replace(/\/+$/, '')}/oauth2/token`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: createBasicAuthHeader(
|
||||
NIANCODE_AUTH_CONFIG.clientId,
|
||||
NIANCODE_AUTH_CONFIG.clientSecret,
|
||||
),
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body,
|
||||
signal,
|
||||
},
|
||||
);
|
||||
const payload = response.ok ? await readResponsePayload(response) : null;
|
||||
return { response, payload };
|
||||
}, options.requestTimeoutMs ?? WORKS_SQUARE_AUTH_REQUEST_TIMEOUT_MS);
|
||||
|
||||
if (!response.ok) {
|
||||
logger.warn('[works-square-session] Refresh failed', { status: response.status });
|
||||
@@ -746,7 +755,6 @@ async function refreshWorksSquareSession(
|
||||
return null;
|
||||
}
|
||||
|
||||
const payload = await readResponsePayload(response);
|
||||
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
||||
logger.warn('[works-square-session] Refresh returned an invalid payload');
|
||||
return null;
|
||||
@@ -780,6 +788,7 @@ export async function getValidWorksSquareAccessToken(
|
||||
fetchImpl?: typeof fetch;
|
||||
nowMs?: number;
|
||||
forceRefresh?: boolean;
|
||||
requestTimeoutMs?: number;
|
||||
} = {},
|
||||
): Promise<string | null> {
|
||||
if (restoreStatus === 'unavailable') {
|
||||
|
||||
Reference in New Issue
Block a user