Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/shared-fetch-utils/common/middleware/authBlockedMiddleware.ts
13401 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { FetchBlockedError, type FetchMiddleware } from '../fetchTypes';
7
8
export class AuthBlockedError extends FetchBlockedError {
9
constructor(retryAfterMs: number) {
10
super(`Auth token blocked for ${Math.round(retryAfterMs / 1000)}s after 401/403`, retryAfterMs);
11
}
12
}
13
14
/**
15
* After a `401` or `403` response, blocks the current auth token for
16
* {@link blockDurationMs} (default 1 hour). Subsequent requests with
17
* the same `Authorization` header are rejected immediately with an
18
* {@link AuthBlockedError}. If the token changes (e.g. the user
19
* re-authenticates) the block is cleared automatically.
20
*/
21
export function authBlockedMiddleware(
22
blockDurationMs: number = 60 * 60 * 1000,
23
): FetchMiddleware {
24
let blockedToken: string | undefined;
25
let blockedUntil = 0;
26
27
return (next) => async (request) => {
28
const currentToken = request.headers['Authorization'] ?? request.headers['authorization'];
29
30
// Token changed → clear block
31
if (currentToken !== blockedToken) {
32
blockedToken = undefined;
33
blockedUntil = 0;
34
}
35
36
// Still blocked?
37
if (currentToken && currentToken === blockedToken && Date.now() < blockedUntil) {
38
throw new AuthBlockedError(blockedUntil - Date.now());
39
}
40
41
const response = await next(request);
42
43
if ((response.status === 401 || response.status === 403) && currentToken) {
44
blockedToken = currentToken;
45
blockedUntil = Date.now() + blockDurationMs;
46
throw new AuthBlockedError(blockDurationMs);
47
}
48
49
return response;
50
};
51
}
52
53