@superfunctions/oauth-http 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +71 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/retry-policy.d.ts +20 -0
- package/dist/retry-policy.d.ts.map +1 -0
- package/dist/retry-policy.js +50 -0
- package/dist/retry-policy.js.map +1 -0
- package/dist/token-client.d.ts +47 -0
- package/dist/token-client.d.ts.map +1 -0
- package/dist/token-client.js +408 -0
- package/dist/token-client.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# @superfunctions/oauth-http
|
|
2
|
+
|
|
3
|
+
Reusable OAuth token transport for code exchange, refresh, revocation, retries, and normalized upstream errors.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @superfunctions/oauth-http @superfunctions/oauth-core @superfunctions/oauth-providers
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { DefaultOAuthTokenHttpClient } from "@superfunctions/oauth-http";
|
|
15
|
+
import { getOAuthProviderDescriptor } from "@superfunctions/oauth-providers";
|
|
16
|
+
|
|
17
|
+
const client = new DefaultOAuthTokenHttpClient();
|
|
18
|
+
const github = getOAuthProviderDescriptor("github");
|
|
19
|
+
|
|
20
|
+
const tokenSet = await client.exchangeToken({
|
|
21
|
+
provider: github,
|
|
22
|
+
grantType: "authorization_code",
|
|
23
|
+
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
24
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
25
|
+
code: "oauth-code",
|
|
26
|
+
redirectUri: "https://app.example/oauth/github/callback",
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Package Boundary
|
|
31
|
+
|
|
32
|
+
`@superfunctions/oauth-http` owns OAuth HTTP transport only:
|
|
33
|
+
|
|
34
|
+
- token endpoint exchange
|
|
35
|
+
- refresh exchange
|
|
36
|
+
- revocation requests
|
|
37
|
+
- retry policy and normalized transport errors
|
|
38
|
+
|
|
39
|
+
It does not own state validation, token persistence, or route generation. Pair it with:
|
|
40
|
+
|
|
41
|
+
- `@superfunctions/oauth-core` for callback invariants
|
|
42
|
+
- `@superfunctions/oauth-flow` for full lifecycle orchestration
|
|
43
|
+
- `@superfunctions/oauth-router` for route exposure
|
|
44
|
+
|
|
45
|
+
## Production Notes
|
|
46
|
+
|
|
47
|
+
- Provide secrets through `clientSecretResolver` when your platform resolves secrets dynamically.
|
|
48
|
+
- Tune retries for provider-specific 429/5xx behavior instead of wrapping token calls with ad hoc fetch logic.
|
|
49
|
+
- Treat provider revocation as best effort unless your product contract requires remote confirmation before local cleanup.
|
|
50
|
+
|
|
51
|
+
## Related Packages
|
|
52
|
+
|
|
53
|
+
- OAuth core primitives: [../oauth-core/README.md](../oauth-core/README.md)
|
|
54
|
+
- Provider descriptors: [../oauth-providers/README.md](../oauth-providers/README.md)
|
|
55
|
+
- Route factories: [../oauth-router/README.md](../oauth-router/README.md)
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OAuthSecretResolverContext } from "./index.js";
|
|
2
|
+
export type OAuthHttpErrorCode = "OAUTH_TOKEN_EXCHANGE_FAILED" | "OAUTH_TOKEN_REFRESH_FAILED" | "PROVIDER_RATE_LIMITED" | "VALIDATION_ERROR" | "INTERNAL_ERROR" | "OAUTH_RUNTIME_CONFIG_INVALID" | "OAUTH_SECRET_RESOLUTION_FAILED";
|
|
3
|
+
export interface OAuthHttpErrorOptions {
|
|
4
|
+
code: OAuthHttpErrorCode;
|
|
5
|
+
status?: number;
|
|
6
|
+
retryable?: boolean;
|
|
7
|
+
details?: Record<string, unknown>;
|
|
8
|
+
cause?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export declare class OAuthHttpError extends Error {
|
|
11
|
+
readonly code: OAuthHttpErrorCode;
|
|
12
|
+
readonly status?: number;
|
|
13
|
+
readonly retryable: boolean;
|
|
14
|
+
readonly details?: Record<string, unknown>;
|
|
15
|
+
readonly cause?: unknown;
|
|
16
|
+
constructor(message: string, options: OAuthHttpErrorOptions);
|
|
17
|
+
}
|
|
18
|
+
export declare function unsupportedTokenAuthMethodError(tokenAuthMethod: string): OAuthHttpError;
|
|
19
|
+
export declare function invalidRuntimeConfigError(message: string, details?: Record<string, unknown>): OAuthHttpError;
|
|
20
|
+
export declare function secretResolutionFailedError(context: OAuthSecretResolverContext, cause?: unknown, message?: string): OAuthHttpError;
|
|
21
|
+
export declare function normalizeOAuthErrorBody(rawBody: unknown): {
|
|
22
|
+
message: string;
|
|
23
|
+
details?: Record<string, unknown>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAC1B,6BAA6B,GAC7B,4BAA4B,GAC5B,uBAAuB,GACvB,kBAAkB,GAClB,gBAAgB,GAChB,8BAA8B,GAC9B,gCAAgC,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB;CAS5D;AAED,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,GAAG,cAAc,CAOvF;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAO5G;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,0BAA0B,EACnC,KAAK,CAAC,EAAE,OAAO,EACf,OAAO,GAAE,MAAgD,GACxD,cAAc,CAahB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAyBhH"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export class OAuthHttpError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
status;
|
|
4
|
+
retryable;
|
|
5
|
+
details;
|
|
6
|
+
cause;
|
|
7
|
+
constructor(message, options) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "OAuthHttpError";
|
|
10
|
+
this.code = options.code;
|
|
11
|
+
this.status = options.status;
|
|
12
|
+
this.retryable = options.retryable ?? false;
|
|
13
|
+
this.details = options.details;
|
|
14
|
+
this.cause = options.cause;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function unsupportedTokenAuthMethodError(tokenAuthMethod) {
|
|
18
|
+
return new OAuthHttpError("unsupported token auth method", {
|
|
19
|
+
code: "VALIDATION_ERROR",
|
|
20
|
+
status: 400,
|
|
21
|
+
retryable: false,
|
|
22
|
+
details: { tokenAuthMethod }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function invalidRuntimeConfigError(message, details) {
|
|
26
|
+
return new OAuthHttpError(message, {
|
|
27
|
+
code: "OAUTH_RUNTIME_CONFIG_INVALID",
|
|
28
|
+
status: 500,
|
|
29
|
+
retryable: false,
|
|
30
|
+
details
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export function secretResolutionFailedError(context, cause, message = "failed to resolve OAuth client secret") {
|
|
34
|
+
return new OAuthHttpError(message, {
|
|
35
|
+
code: "OAUTH_SECRET_RESOLUTION_FAILED",
|
|
36
|
+
status: 500,
|
|
37
|
+
retryable: false,
|
|
38
|
+
cause,
|
|
39
|
+
details: {
|
|
40
|
+
providerId: context.provider.id,
|
|
41
|
+
operation: context.operation,
|
|
42
|
+
grantType: context.grantType,
|
|
43
|
+
hasResolver: true
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function normalizeOAuthErrorBody(rawBody) {
|
|
48
|
+
if (!rawBody || typeof rawBody !== "object") {
|
|
49
|
+
return { message: "OAuth provider request failed" };
|
|
50
|
+
}
|
|
51
|
+
const payload = rawBody;
|
|
52
|
+
const description = asString(payload.error_description) ??
|
|
53
|
+
asString(payload.message) ??
|
|
54
|
+
asString(payload.error) ??
|
|
55
|
+
asString(payload.detail) ??
|
|
56
|
+
"OAuth provider request failed";
|
|
57
|
+
const details = Object.fromEntries(Object.entries({
|
|
58
|
+
error: asString(payload.error),
|
|
59
|
+
error_description: asString(payload.error_description),
|
|
60
|
+
error_uri: asString(payload.error_uri),
|
|
61
|
+
detail: asString(payload.detail)
|
|
62
|
+
}).filter(([, value]) => value !== undefined));
|
|
63
|
+
return {
|
|
64
|
+
message: description,
|
|
65
|
+
details: Object.keys(details).length > 0 ? details : undefined
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function asString(value) {
|
|
69
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { OAuthProviderDescriptor } from "@superfunctions/oauth-core";
|
|
2
|
+
export type OAuthTokenGrantType = "authorization_code" | "refresh_token" | "client_credentials";
|
|
3
|
+
export type OAuthTokenAuthMethod = "client_secret_post" | "client_secret_basic";
|
|
4
|
+
export interface OAuthResolvedClientSecret {
|
|
5
|
+
clientSecret: string;
|
|
6
|
+
tokenAuthMethod?: OAuthTokenAuthMethod;
|
|
7
|
+
}
|
|
8
|
+
export interface OAuthSecretResolverContext {
|
|
9
|
+
provider: OAuthProviderDescriptor;
|
|
10
|
+
operation: "exchange" | "revoke";
|
|
11
|
+
clientId: string;
|
|
12
|
+
grantType?: OAuthTokenGrantType;
|
|
13
|
+
redirectUri?: string;
|
|
14
|
+
scopes?: string[];
|
|
15
|
+
tokenTypeHint?: "access_token" | "refresh_token";
|
|
16
|
+
}
|
|
17
|
+
export type OAuthClientSecretResolver = (input: OAuthSecretResolverContext) => Promise<OAuthResolvedClientSecret> | OAuthResolvedClientSecret;
|
|
18
|
+
export interface OAuthTokenEndpointRequest {
|
|
19
|
+
provider: OAuthProviderDescriptor;
|
|
20
|
+
grantType: OAuthTokenGrantType;
|
|
21
|
+
clientId: string;
|
|
22
|
+
clientSecret?: string;
|
|
23
|
+
clientSecretResolver?: OAuthClientSecretResolver;
|
|
24
|
+
redirectUri?: string;
|
|
25
|
+
code?: string;
|
|
26
|
+
codeVerifier?: string;
|
|
27
|
+
refreshToken?: string;
|
|
28
|
+
scopes?: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface OAuthTokenEndpointResponse {
|
|
31
|
+
accessToken: string;
|
|
32
|
+
refreshToken?: string;
|
|
33
|
+
expiresIn?: number;
|
|
34
|
+
tokenType?: string;
|
|
35
|
+
scope?: string;
|
|
36
|
+
idToken?: string;
|
|
37
|
+
raw?: unknown;
|
|
38
|
+
}
|
|
39
|
+
export interface OAuthRevocationRequest {
|
|
40
|
+
provider: OAuthProviderDescriptor;
|
|
41
|
+
clientId: string;
|
|
42
|
+
clientSecret?: string;
|
|
43
|
+
clientSecretResolver?: OAuthClientSecretResolver;
|
|
44
|
+
token: string;
|
|
45
|
+
tokenTypeHint?: "access_token" | "refresh_token";
|
|
46
|
+
}
|
|
47
|
+
export interface OAuthTokenHttpClient {
|
|
48
|
+
exchangeToken(input: OAuthTokenEndpointRequest): Promise<OAuthTokenEndpointResponse>;
|
|
49
|
+
revokeToken(input: OAuthRevocationRequest): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
export * from "./errors.js";
|
|
52
|
+
export * from "./retry-policy.js";
|
|
53
|
+
export * from "./token-client.js";
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE1E,MAAM,MAAM,mBAAmB,GAC3B,oBAAoB,GACpB,eAAe,GACf,oBAAoB,CAAC;AAEzB,MAAM,MAAM,oBAAoB,GAAG,oBAAoB,GAAG,qBAAqB,CAAC;AAEhF,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,oBAAoB,CAAC;CACxC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,cAAc,GAAG,eAAe,CAAC;CAClD;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,0BAA0B,KAC9B,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,cAAc,GAAG,eAAe,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACrF,WAAW,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiEA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface OAuthRetryPolicy {
|
|
2
|
+
maxAttempts: number;
|
|
3
|
+
baseDelayMs: number;
|
|
4
|
+
maxDelayMs: number;
|
|
5
|
+
jitterRatio: number;
|
|
6
|
+
random: () => number;
|
|
7
|
+
}
|
|
8
|
+
export interface RetryDecisionInput {
|
|
9
|
+
attempt: number;
|
|
10
|
+
status?: number;
|
|
11
|
+
retryAfterHeader?: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface RetryDecision {
|
|
14
|
+
retry: boolean;
|
|
15
|
+
delayMs: number;
|
|
16
|
+
}
|
|
17
|
+
export declare const DEFAULT_OAUTH_RETRY_POLICY: OAuthRetryPolicy;
|
|
18
|
+
export declare function decideRetry(input: RetryDecisionInput, policy?: OAuthRetryPolicy): RetryDecision;
|
|
19
|
+
export declare function parseRetryAfter(value: string | null | undefined): number | null;
|
|
20
|
+
//# sourceMappingURL=retry-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAMxC,CAAC;AAEF,wBAAgB,WAAW,CACzB,KAAK,EAAE,kBAAkB,EACzB,MAAM,GAAE,gBAA6C,GACpD,aAAa,CAiBf;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqB/E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const DEFAULT_OAUTH_RETRY_POLICY = {
|
|
2
|
+
maxAttempts: 5,
|
|
3
|
+
baseDelayMs: 250,
|
|
4
|
+
maxDelayMs: 10_000,
|
|
5
|
+
jitterRatio: 0.2,
|
|
6
|
+
random: Math.random
|
|
7
|
+
};
|
|
8
|
+
export function decideRetry(input, policy = DEFAULT_OAUTH_RETRY_POLICY) {
|
|
9
|
+
if (!shouldRetryStatus(input.status)) {
|
|
10
|
+
return { retry: false, delayMs: 0 };
|
|
11
|
+
}
|
|
12
|
+
if (input.attempt >= policy.maxAttempts) {
|
|
13
|
+
return { retry: false, delayMs: 0 };
|
|
14
|
+
}
|
|
15
|
+
const retryAfterMs = parseRetryAfter(input.retryAfterHeader);
|
|
16
|
+
if (retryAfterMs !== null) {
|
|
17
|
+
return { retry: true, delayMs: retryAfterMs };
|
|
18
|
+
}
|
|
19
|
+
const exponentialDelay = Math.min(policy.maxDelayMs, policy.baseDelayMs * 2 ** (input.attempt - 1));
|
|
20
|
+
const jitter = Math.floor(exponentialDelay * policy.jitterRatio * policy.random());
|
|
21
|
+
return { retry: true, delayMs: exponentialDelay + jitter };
|
|
22
|
+
}
|
|
23
|
+
export function parseRetryAfter(value) {
|
|
24
|
+
if (!value) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const seconds = Number(value);
|
|
28
|
+
if (!Number.isNaN(seconds) && Number.isFinite(seconds) && seconds >= 0) {
|
|
29
|
+
return Math.round(seconds * 1000);
|
|
30
|
+
}
|
|
31
|
+
const dateValue = Date.parse(value);
|
|
32
|
+
if (Number.isNaN(dateValue)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
if (dateValue <= now) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
return dateValue - now;
|
|
40
|
+
}
|
|
41
|
+
function shouldRetryStatus(status) {
|
|
42
|
+
if (status === undefined) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
if (status === 429) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return status >= 500 && status <= 599;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=retry-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.js","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAmBA,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,GAAG;IAChB,MAAM,EAAE,IAAI,CAAC,MAAM;CACpB,CAAC;AAEF,MAAM,UAAU,WAAW,CACzB,KAAyB,EACzB,SAA2B,0BAA0B;IAErD,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IACpG,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAgC;IAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,SAAS,GAAG,GAAG,CAAC;AACzB,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAe;IACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { OAuthRevocationRequest, OAuthTokenEndpointRequest, OAuthTokenEndpointResponse, OAuthTokenHttpClient } from "./index.js";
|
|
2
|
+
import { OAuthHttpError } from "./errors.js";
|
|
3
|
+
import { type OAuthRetryPolicy } from "./retry-policy.js";
|
|
4
|
+
interface HeadersLike {
|
|
5
|
+
get(name: string): string | null;
|
|
6
|
+
}
|
|
7
|
+
interface ResponseLike {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
status: number;
|
|
10
|
+
headers: HeadersLike;
|
|
11
|
+
text(): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
export interface RequestInitLike {
|
|
14
|
+
method: string;
|
|
15
|
+
headers: Record<string, string>;
|
|
16
|
+
body?: string;
|
|
17
|
+
}
|
|
18
|
+
export type OAuthFetchLike = (url: string, init: RequestInitLike) => Promise<ResponseLike>;
|
|
19
|
+
export interface OAuthTokenClientOptions {
|
|
20
|
+
fetcher?: OAuthFetchLike;
|
|
21
|
+
retryPolicy?: OAuthRetryPolicy;
|
|
22
|
+
sleep?: (delayMs: number) => Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export interface DisconnectWithRevokeInput {
|
|
25
|
+
revokeSupported: boolean;
|
|
26
|
+
revokeRequest: OAuthRevocationRequest;
|
|
27
|
+
deleteLocalTokenRecord: () => Promise<void>;
|
|
28
|
+
deleteConnectionRecord: () => Promise<void>;
|
|
29
|
+
onRevocationFailure?: (error: OAuthHttpError) => Promise<void> | void;
|
|
30
|
+
}
|
|
31
|
+
export interface DisconnectWithRevokeResult {
|
|
32
|
+
remoteRevokeAttempted: boolean;
|
|
33
|
+
localTokenDeleted: boolean;
|
|
34
|
+
connectionDeleted: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare class DefaultOAuthTokenHttpClient implements OAuthTokenHttpClient {
|
|
37
|
+
private readonly fetcher;
|
|
38
|
+
private readonly retryPolicy;
|
|
39
|
+
private readonly sleep;
|
|
40
|
+
constructor(options?: OAuthTokenClientOptions);
|
|
41
|
+
exchangeToken(input: OAuthTokenEndpointRequest): Promise<OAuthTokenEndpointResponse>;
|
|
42
|
+
revokeToken(input: OAuthRevocationRequest): Promise<void>;
|
|
43
|
+
private executeWithRetry;
|
|
44
|
+
}
|
|
45
|
+
export declare function disconnectWithRevoke(client: OAuthTokenHttpClient, input: DisconnectWithRevokeInput): Promise<DisconnectWithRevokeResult>;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=token-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-client.d.ts","sourceRoot":"","sources":["../src/token-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,sBAAsB,EAGtB,yBAAyB,EACzB,0BAA0B,EAE1B,oBAAoB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EAKf,MAAM,aAAa,CAAC;AACrB,OAAO,EAA2C,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,UAAU,WAAW;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3F,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,yBAAyB;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,sBAAsB,CAAC;IACtC,sBAAsB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,sBAAsB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACvE;AAED,MAAM,WAAW,0BAA0B;IACzC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAQD,qBAAa,2BAA4B,YAAW,oBAAoB;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;gBAE/C,OAAO,GAAE,uBAA4B;IAM3C,aAAa,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IA2BpF,WAAW,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;YAkCjD,gBAAgB;CAiD/B;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,0BAA0B,CAAC,CAyCrC"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { OAuthHttpError, invalidRuntimeConfigError, normalizeOAuthErrorBody, secretResolutionFailedError, unsupportedTokenAuthMethodError } from "./errors.js";
|
|
2
|
+
import { DEFAULT_OAUTH_RETRY_POLICY, decideRetry } from "./retry-policy.js";
|
|
3
|
+
export class DefaultOAuthTokenHttpClient {
|
|
4
|
+
fetcher;
|
|
5
|
+
retryPolicy;
|
|
6
|
+
sleep;
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.fetcher = options.fetcher ?? getGlobalFetch();
|
|
9
|
+
this.retryPolicy = options.retryPolicy ?? DEFAULT_OAUTH_RETRY_POLICY;
|
|
10
|
+
this.sleep = options.sleep ?? ((delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)));
|
|
11
|
+
}
|
|
12
|
+
async exchangeToken(input) {
|
|
13
|
+
const credentials = await resolveRequestCredentials(input, {
|
|
14
|
+
provider: input.provider,
|
|
15
|
+
operation: "exchange",
|
|
16
|
+
clientId: input.clientId,
|
|
17
|
+
grantType: input.grantType,
|
|
18
|
+
redirectUri: input.redirectUri,
|
|
19
|
+
scopes: input.scopes
|
|
20
|
+
});
|
|
21
|
+
const endpointRequest = createTokenRequest(input, credentials);
|
|
22
|
+
const response = await this.executeWithRetry(input.provider.tokenUrl, endpointRequest);
|
|
23
|
+
const contentType = response.headers.get("content-type");
|
|
24
|
+
const rawBodyText = await response.text();
|
|
25
|
+
const parsedBody = parseResponseBody(rawBodyText, contentType);
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
throw createTokenEndpointError({
|
|
28
|
+
status: response.status,
|
|
29
|
+
grantType: input.grantType,
|
|
30
|
+
providerId: input.provider.id,
|
|
31
|
+
parsedBody
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return normalizeTokenResponse(parsedBody);
|
|
35
|
+
}
|
|
36
|
+
async revokeToken(input) {
|
|
37
|
+
if (!input.provider.revocationUrl) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const credentials = await resolveRequestCredentials(input, {
|
|
41
|
+
provider: input.provider,
|
|
42
|
+
operation: "revoke",
|
|
43
|
+
clientId: input.clientId,
|
|
44
|
+
tokenTypeHint: input.tokenTypeHint
|
|
45
|
+
});
|
|
46
|
+
const endpointRequest = createRevokeRequest(input, credentials);
|
|
47
|
+
const response = await this.executeWithRetry(input.provider.revocationUrl, endpointRequest);
|
|
48
|
+
if (response.ok) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const contentType = response.headers.get("content-type");
|
|
52
|
+
const rawBodyText = await response.text();
|
|
53
|
+
const parsedBody = parseResponseBody(rawBodyText, contentType);
|
|
54
|
+
const normalized = normalizeOAuthErrorBody(parsedBody);
|
|
55
|
+
const retryable = response.status === 429 || (response.status >= 500 && response.status <= 599);
|
|
56
|
+
throw new OAuthHttpError(normalized.message, {
|
|
57
|
+
code: response.status === 429 ? "PROVIDER_RATE_LIMITED" : "INTERNAL_ERROR",
|
|
58
|
+
status: response.status,
|
|
59
|
+
retryable,
|
|
60
|
+
details: {
|
|
61
|
+
providerId: input.provider.id,
|
|
62
|
+
operation: "revoke",
|
|
63
|
+
...normalized.details
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async executeWithRetry(url, init) {
|
|
68
|
+
let attempt = 1;
|
|
69
|
+
while (true) {
|
|
70
|
+
let response;
|
|
71
|
+
try {
|
|
72
|
+
response = await this.fetcher(url, init);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
const decision = decideRetry({
|
|
76
|
+
attempt,
|
|
77
|
+
status: 503
|
|
78
|
+
}, this.retryPolicy);
|
|
79
|
+
if (!decision.retry) {
|
|
80
|
+
throw new OAuthHttpError("OAuth provider request failed", {
|
|
81
|
+
code: "OAUTH_TOKEN_EXCHANGE_FAILED",
|
|
82
|
+
status: 502,
|
|
83
|
+
retryable: false,
|
|
84
|
+
cause: error,
|
|
85
|
+
details: {
|
|
86
|
+
transportFailure: true
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
await this.sleep(decision.delayMs);
|
|
91
|
+
attempt += 1;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const decision = decideRetry({
|
|
95
|
+
attempt,
|
|
96
|
+
status: response.status,
|
|
97
|
+
retryAfterHeader: response.headers.get("retry-after")
|
|
98
|
+
}, this.retryPolicy);
|
|
99
|
+
if (!decision.retry) {
|
|
100
|
+
return response;
|
|
101
|
+
}
|
|
102
|
+
await this.sleep(decision.delayMs);
|
|
103
|
+
attempt += 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export async function disconnectWithRevoke(client, input) {
|
|
108
|
+
let revokeError = null;
|
|
109
|
+
let localTokenDeleted = false;
|
|
110
|
+
let connectionDeleted = false;
|
|
111
|
+
if (input.revokeSupported) {
|
|
112
|
+
try {
|
|
113
|
+
await client.revokeToken(input.revokeRequest);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
revokeError = ensureOAuthHttpError(error);
|
|
117
|
+
if (input.onRevocationFailure) {
|
|
118
|
+
await input.onRevocationFailure(revokeError);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
await input.deleteLocalTokenRecord();
|
|
123
|
+
localTokenDeleted = true;
|
|
124
|
+
await input.deleteConnectionRecord();
|
|
125
|
+
connectionDeleted = true;
|
|
126
|
+
if (revokeError) {
|
|
127
|
+
throw new OAuthHttpError("provider revoke failed after local cleanup", {
|
|
128
|
+
code: "INTERNAL_ERROR",
|
|
129
|
+
status: 502,
|
|
130
|
+
retryable: false,
|
|
131
|
+
cause: revokeError,
|
|
132
|
+
details: {
|
|
133
|
+
remoteRevokeAttempted: true,
|
|
134
|
+
localTokenDeleted,
|
|
135
|
+
connectionDeleted,
|
|
136
|
+
revokeErrorCode: revokeError.code
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
remoteRevokeAttempted: input.revokeSupported,
|
|
142
|
+
localTokenDeleted,
|
|
143
|
+
connectionDeleted
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async function resolveRequestCredentials(input, context) {
|
|
147
|
+
if (!input.clientId) {
|
|
148
|
+
throw invalidRuntimeConfigError("OAuth runtime config missing clientId", {
|
|
149
|
+
providerId: input.provider.id,
|
|
150
|
+
operation: context.operation
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const tokenAuthMethod = getTokenAuthMethod(input.provider.tokenAuthMethod);
|
|
154
|
+
if (input.clientSecret) {
|
|
155
|
+
return {
|
|
156
|
+
clientId: input.clientId,
|
|
157
|
+
clientSecret: input.clientSecret,
|
|
158
|
+
tokenAuthMethod
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const resolvedSecret = await resolveClientSecret(input.clientSecretResolver, context);
|
|
162
|
+
return {
|
|
163
|
+
clientId: input.clientId,
|
|
164
|
+
clientSecret: resolvedSecret.clientSecret,
|
|
165
|
+
tokenAuthMethod: resolvedSecret.tokenAuthMethod ?? tokenAuthMethod
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
async function resolveClientSecret(resolver, context) {
|
|
169
|
+
if (!resolver) {
|
|
170
|
+
throw invalidRuntimeConfigError("OAuth runtime config missing clientSecret or clientSecretResolver", {
|
|
171
|
+
providerId: context.provider.id,
|
|
172
|
+
operation: context.operation
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
let resolved;
|
|
176
|
+
try {
|
|
177
|
+
resolved = await resolver(context);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
throw secretResolutionFailedError(context, error);
|
|
181
|
+
}
|
|
182
|
+
if (!resolved?.clientSecret) {
|
|
183
|
+
throw secretResolutionFailedError(context, undefined, "resolved OAuth client secret is empty");
|
|
184
|
+
}
|
|
185
|
+
return resolved;
|
|
186
|
+
}
|
|
187
|
+
function createTokenRequest(input, credentials) {
|
|
188
|
+
const params = new URLSearchParams();
|
|
189
|
+
params.set("grant_type", input.grantType);
|
|
190
|
+
if (input.grantType === "authorization_code") {
|
|
191
|
+
if (!input.code) {
|
|
192
|
+
throw new OAuthHttpError("authorization code is required", {
|
|
193
|
+
code: "VALIDATION_ERROR",
|
|
194
|
+
status: 400
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
params.set("code", input.code);
|
|
198
|
+
if (input.redirectUri) {
|
|
199
|
+
params.set("redirect_uri", input.redirectUri);
|
|
200
|
+
}
|
|
201
|
+
if (input.codeVerifier) {
|
|
202
|
+
params.set("code_verifier", input.codeVerifier);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else if (input.grantType === "refresh_token") {
|
|
206
|
+
if (!input.refreshToken) {
|
|
207
|
+
throw new OAuthHttpError("refresh token is required", {
|
|
208
|
+
code: "VALIDATION_ERROR",
|
|
209
|
+
status: 400
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
params.set("refresh_token", input.refreshToken);
|
|
213
|
+
if (input.redirectUri) {
|
|
214
|
+
params.set("redirect_uri", input.redirectUri);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (input.scopes && input.scopes.length > 0) {
|
|
218
|
+
params.set("scope", input.scopes.join(input.provider.scopeSeparator ?? " "));
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
method: "POST",
|
|
222
|
+
headers: createAuthHeaders(credentials, params),
|
|
223
|
+
body: params.toString()
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function createRevokeRequest(input, credentials) {
|
|
227
|
+
const params = new URLSearchParams();
|
|
228
|
+
params.set("token", input.token);
|
|
229
|
+
if (input.tokenTypeHint) {
|
|
230
|
+
params.set("token_type_hint", input.tokenTypeHint);
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
method: "POST",
|
|
234
|
+
headers: createAuthHeaders(credentials, params),
|
|
235
|
+
body: params.toString()
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function createAuthHeaders(credentials, params) {
|
|
239
|
+
const headers = {
|
|
240
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
241
|
+
accept: "application/json, application/x-www-form-urlencoded, text/plain"
|
|
242
|
+
};
|
|
243
|
+
if (credentials.tokenAuthMethod === "client_secret_post") {
|
|
244
|
+
params.set("client_id", credentials.clientId);
|
|
245
|
+
params.set("client_secret", credentials.clientSecret);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const authUser = encodeURIComponent(credentials.clientId);
|
|
249
|
+
const authPassword = encodeURIComponent(credentials.clientSecret);
|
|
250
|
+
const auth = Buffer.from(`${authUser}:${authPassword}`, "utf8").toString("base64");
|
|
251
|
+
headers.authorization = `Basic ${auth}`;
|
|
252
|
+
}
|
|
253
|
+
return headers;
|
|
254
|
+
}
|
|
255
|
+
function parseResponseBody(rawBodyText, contentType) {
|
|
256
|
+
if (rawBodyText.length === 0) {
|
|
257
|
+
return {};
|
|
258
|
+
}
|
|
259
|
+
const normalizedContentType = contentType?.toLowerCase() ?? "";
|
|
260
|
+
if (normalizedContentType.includes("application/json")) {
|
|
261
|
+
return safeParseJson(rawBodyText);
|
|
262
|
+
}
|
|
263
|
+
if (normalizedContentType.includes("application/x-www-form-urlencoded") ||
|
|
264
|
+
normalizedContentType.includes("text/plain")) {
|
|
265
|
+
return parseFormBody(rawBodyText);
|
|
266
|
+
}
|
|
267
|
+
const maybeJson = safeParseJson(rawBodyText);
|
|
268
|
+
if (maybeJson !== null) {
|
|
269
|
+
return maybeJson;
|
|
270
|
+
}
|
|
271
|
+
return parseFormBody(rawBodyText);
|
|
272
|
+
}
|
|
273
|
+
function normalizeTokenResponse(parsedBody) {
|
|
274
|
+
if (!parsedBody || typeof parsedBody !== "object" || Array.isArray(parsedBody)) {
|
|
275
|
+
throw new OAuthHttpError("OAuth token response body must be a JSON object", {
|
|
276
|
+
code: "OAUTH_TOKEN_EXCHANGE_FAILED",
|
|
277
|
+
status: 502,
|
|
278
|
+
retryable: false,
|
|
279
|
+
details: { parsedBodyKeys: [] }
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const payload = parsedBody;
|
|
283
|
+
const accessToken = asString(payload.access_token);
|
|
284
|
+
if (!accessToken) {
|
|
285
|
+
throw new OAuthHttpError("OAuth token response missing access_token", {
|
|
286
|
+
code: "OAUTH_TOKEN_EXCHANGE_FAILED",
|
|
287
|
+
status: 502,
|
|
288
|
+
retryable: false,
|
|
289
|
+
details: { parsedBodyKeys: Object.keys(payload).slice(0, 10) }
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
const result = {
|
|
293
|
+
accessToken,
|
|
294
|
+
refreshToken: asString(payload.refresh_token),
|
|
295
|
+
tokenType: asString(payload.token_type),
|
|
296
|
+
scope: asString(payload.scope),
|
|
297
|
+
idToken: asString(payload.id_token),
|
|
298
|
+
raw: payload
|
|
299
|
+
};
|
|
300
|
+
const expiresIn = asNumber(payload.expires_in);
|
|
301
|
+
if (expiresIn !== undefined) {
|
|
302
|
+
result.expiresIn = expiresIn;
|
|
303
|
+
}
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
function createTokenEndpointError(input) {
|
|
307
|
+
const normalized = normalizeOAuthErrorBody(input.parsedBody);
|
|
308
|
+
const retryable = input.status === 429 || (input.status >= 500 && input.status <= 599);
|
|
309
|
+
if (input.status === 429) {
|
|
310
|
+
return new OAuthHttpError(normalized.message, {
|
|
311
|
+
code: "PROVIDER_RATE_LIMITED",
|
|
312
|
+
status: input.status,
|
|
313
|
+
retryable: true,
|
|
314
|
+
details: {
|
|
315
|
+
providerId: input.providerId,
|
|
316
|
+
grantType: input.grantType,
|
|
317
|
+
...normalized.details
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return new OAuthHttpError(normalized.message, {
|
|
322
|
+
code: input.grantType === "refresh_token" ? "OAUTH_TOKEN_REFRESH_FAILED" : "OAUTH_TOKEN_EXCHANGE_FAILED",
|
|
323
|
+
status: input.status,
|
|
324
|
+
retryable,
|
|
325
|
+
details: {
|
|
326
|
+
providerId: input.providerId,
|
|
327
|
+
grantType: input.grantType,
|
|
328
|
+
...normalized.details
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function getTokenAuthMethod(tokenAuthMethod) {
|
|
333
|
+
if (!tokenAuthMethod) {
|
|
334
|
+
return "client_secret_post";
|
|
335
|
+
}
|
|
336
|
+
if (tokenAuthMethod === "client_secret_post" || tokenAuthMethod === "client_secret_basic") {
|
|
337
|
+
return tokenAuthMethod;
|
|
338
|
+
}
|
|
339
|
+
throw unsupportedTokenAuthMethodError(tokenAuthMethod);
|
|
340
|
+
}
|
|
341
|
+
function parseFormBody(rawBodyText) {
|
|
342
|
+
const params = new URLSearchParams(rawBodyText);
|
|
343
|
+
const result = {};
|
|
344
|
+
for (const [key, value] of params.entries()) {
|
|
345
|
+
result[key] = value;
|
|
346
|
+
}
|
|
347
|
+
return result;
|
|
348
|
+
}
|
|
349
|
+
function safeParseJson(rawBodyText) {
|
|
350
|
+
try {
|
|
351
|
+
return JSON.parse(rawBodyText);
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function asString(value) {
|
|
358
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
359
|
+
}
|
|
360
|
+
function asNumber(value) {
|
|
361
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
362
|
+
return value;
|
|
363
|
+
}
|
|
364
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
365
|
+
const parsed = Number(value);
|
|
366
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
367
|
+
}
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
function ensureOAuthHttpError(error) {
|
|
371
|
+
if (error instanceof OAuthHttpError) {
|
|
372
|
+
return error;
|
|
373
|
+
}
|
|
374
|
+
return new OAuthHttpError(error instanceof Error ? error.message : "OAuth HTTP request failed", {
|
|
375
|
+
code: "INTERNAL_ERROR",
|
|
376
|
+
status: 500,
|
|
377
|
+
retryable: false,
|
|
378
|
+
cause: error
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function getGlobalFetch() {
|
|
382
|
+
const fetcher = globalThis.fetch;
|
|
383
|
+
if (!fetcher) {
|
|
384
|
+
throw new OAuthHttpError("global fetch is not available", {
|
|
385
|
+
code: "INTERNAL_ERROR",
|
|
386
|
+
status: 500,
|
|
387
|
+
retryable: false
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
return async (url, init) => {
|
|
391
|
+
const response = await fetcher(url, {
|
|
392
|
+
method: init.method,
|
|
393
|
+
headers: init.headers,
|
|
394
|
+
body: init.body
|
|
395
|
+
});
|
|
396
|
+
return {
|
|
397
|
+
ok: response.ok,
|
|
398
|
+
status: response.status,
|
|
399
|
+
headers: {
|
|
400
|
+
get(name) {
|
|
401
|
+
return response.headers.get(name);
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
text: () => response.text()
|
|
405
|
+
};
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=token-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-client.js","sourceRoot":"","sources":["../src/token-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@superfunctions/oauth-http",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "OAuth HTTP transport contracts for Superfunctions",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"test": "vitest --config ./vitest.config.ts --run",
|
|
20
|
+
"test:watch": "vitest --config ./vitest.config.ts --watch",
|
|
21
|
+
"lint": "echo 'lint not configured'",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"clean": "rm -rf dist"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"oauth",
|
|
27
|
+
"http",
|
|
28
|
+
"superfunctions"
|
|
29
|
+
],
|
|
30
|
+
"author": "21n",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/21nCo/super-functions.git",
|
|
35
|
+
"directory": "packages/oauth-http"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@superfunctions/oauth-core": "0.0.1"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^22.0.0",
|
|
45
|
+
"typescript": "^5.6.0",
|
|
46
|
+
"vitest": "^3.2.4"
|
|
47
|
+
}
|
|
48
|
+
}
|