@cloudflare/workers-auth 0.1.0 → 0.2.0
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/dist/{chunk-PAWJFY3S.mjs → chunk-O6YSETKJ.mjs} +0 -2
- package/dist/index.d.mts +170 -42
- package/dist/index.mjs +305 -1288
- package/dist/metafile-esm.json +1 -1
- package/dist/test-helpers/index.mjs +1 -3
- package/package.json +2 -2
- package/dist/chunk-PAWJFY3S.mjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/test-helpers/index.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UserError, ComplianceConfig } from '@cloudflare/workers-utils';
|
|
1
|
+
import { ApiCredentials, UserError, ComplianceConfig } from '@cloudflare/workers-utils';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The data that may be read from the on-disk user auth config file.
|
|
@@ -12,28 +12,29 @@ interface UserAuthConfig {
|
|
|
12
12
|
api_token?: string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Pluggable persistence for the user auth config.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*/
|
|
36
|
-
|
|
17
|
+
* This package does not ship a default implementation — the consumer injects
|
|
18
|
+
* one via {@link OAuthFlowContext.storage} (and into {@link getAPIToken} /
|
|
19
|
+
* {@link readStoredAuthState}). Wrangler's default reads/writes a TOML file
|
|
20
|
+
* under the global Wrangler config directory; other CLIs can use a different
|
|
21
|
+
* location and/or serialization format (e.g. a JSONC file under a different
|
|
22
|
+
* CLI's XDG config directory).
|
|
23
|
+
*/
|
|
24
|
+
interface AuthConfigStorage {
|
|
25
|
+
/**
|
|
26
|
+
* Read and parse the stored auth config.
|
|
27
|
+
* @throws if the backing store is missing or cannot be parsed. Callers treat
|
|
28
|
+
* a throw as "not logged in via local OAuth".
|
|
29
|
+
*/
|
|
30
|
+
read(): UserAuthConfig;
|
|
31
|
+
/** Serialize and persist the auth config. */
|
|
32
|
+
write(config: UserAuthConfig): void;
|
|
33
|
+
/** Remove the backing store (used on logout). */
|
|
34
|
+
clear(): void;
|
|
35
|
+
/** Human-readable location of the backing store, for display and warnings. */
|
|
36
|
+
path(): string;
|
|
37
|
+
}
|
|
37
38
|
|
|
38
39
|
interface GenerateAuthUrlProps {
|
|
39
40
|
authUrl: string;
|
|
@@ -41,8 +42,8 @@ interface GenerateAuthUrlProps {
|
|
|
41
42
|
scopes: string[];
|
|
42
43
|
stateQueryParam: string;
|
|
43
44
|
codeChallenge: string;
|
|
45
|
+
redirectUri: string;
|
|
44
46
|
}
|
|
45
|
-
declare const OAUTH_CALLBACK_URL = "http://localhost:8976/oauth/callback";
|
|
46
47
|
/**
|
|
47
48
|
* Build the OAuth 2.0 authorize URL for the Cloudflare auth endpoint.
|
|
48
49
|
*
|
|
@@ -50,7 +51,7 @@ declare const OAUTH_CALLBACK_URL = "http://localhost:8976/oauth/callback";
|
|
|
50
51
|
* substitute a deterministic implementation when a stable URL is needed
|
|
51
52
|
* (e.g. for snapshot testing).
|
|
52
53
|
*/
|
|
53
|
-
declare const generateAuthUrl: ({ authUrl, clientId, scopes, stateQueryParam, codeChallenge, }: GenerateAuthUrlProps) => string;
|
|
54
|
+
declare const generateAuthUrl: ({ authUrl, clientId, scopes, stateQueryParam, codeChallenge, redirectUri, }: GenerateAuthUrlProps) => string;
|
|
54
55
|
|
|
55
56
|
/**
|
|
56
57
|
* Generates random state to be passed for anti-csrf.
|
|
@@ -61,6 +62,22 @@ declare const generateAuthUrl: ({ authUrl, clientId, scopes, stateQueryParam, co
|
|
|
61
62
|
*/
|
|
62
63
|
declare function generateRandomState(lengthOfState: number): string;
|
|
63
64
|
|
|
65
|
+
/**
|
|
66
|
+
* The branded OAuth consent pages the provider redirects the browser to after
|
|
67
|
+
* the user grants or denies consent.
|
|
68
|
+
*/
|
|
69
|
+
interface OAuthConsentPages {
|
|
70
|
+
/** Redirect target shown after the user grants consent. */
|
|
71
|
+
granted: {
|
|
72
|
+
url: string;
|
|
73
|
+
};
|
|
74
|
+
/** Redirect target shown after the user denies consent, plus the error
|
|
75
|
+
* surfaced to the terminal. */
|
|
76
|
+
denied: {
|
|
77
|
+
url: string;
|
|
78
|
+
error: string;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
64
81
|
/**
|
|
65
82
|
* Subset of the wrangler `logger` singleton used by the OAuth flow.
|
|
66
83
|
* Consumers pass in an implementation that maps to their own logging surface.
|
|
@@ -107,6 +124,26 @@ interface OAuthFlowContext {
|
|
|
107
124
|
* cache).
|
|
108
125
|
*/
|
|
109
126
|
purgeOnLoginOrLogout?: () => void;
|
|
127
|
+
/**
|
|
128
|
+
* The OAuth client ID identifying the consuming CLI to the Cloudflare OAuth
|
|
129
|
+
* server. Consumer-specific (each CLI registers its own OAuth app), so it is
|
|
130
|
+
* required. Pass a function to resolve it lazily — e.g. so an env-var read at
|
|
131
|
+
* call time can switch between production and staging apps.
|
|
132
|
+
*/
|
|
133
|
+
clientId: string | (() => string);
|
|
134
|
+
/**
|
|
135
|
+
* The branded consent pages the provider redirects to after the user grants
|
|
136
|
+
* or denies consent.
|
|
137
|
+
*/
|
|
138
|
+
consent: OAuthConsentPages;
|
|
139
|
+
/**
|
|
140
|
+
* The `redirect_uri` registered on the consumer's OAuth app
|
|
141
|
+
*/
|
|
142
|
+
redirectUri: string;
|
|
143
|
+
/**
|
|
144
|
+
* Persistence backend for the stored auth config.
|
|
145
|
+
*/
|
|
146
|
+
storage: AuthConfigStorage;
|
|
110
147
|
/**
|
|
111
148
|
* Override the OAuth authorize URL generator. Used by tests to produce a
|
|
112
149
|
* deterministic URL for snapshot testing. Defaults to the standard
|
|
@@ -121,6 +158,60 @@ interface OAuthFlowContext {
|
|
|
121
158
|
generateRandomState?: typeof generateRandomState;
|
|
122
159
|
}
|
|
123
160
|
|
|
161
|
+
/** `CLOUDFLARE_API_TOKEN` (legacy alias `CF_API_TOKEN`): a scoped API token. */
|
|
162
|
+
declare const getCloudflareAPITokenFromEnv: () => string | undefined;
|
|
163
|
+
/** `CLOUDFLARE_API_KEY` (legacy alias `CF_API_KEY`): the global API key. */
|
|
164
|
+
declare const getCloudflareGlobalAuthKeyFromEnv: () => string | undefined;
|
|
165
|
+
/** `CLOUDFLARE_EMAIL` (legacy alias `CF_EMAIL`): the account email, paired with
|
|
166
|
+
* the global API key. */
|
|
167
|
+
declare const getCloudflareGlobalAuthEmailFromEnv: () => string | undefined;
|
|
168
|
+
interface GetAuthFromEnvOptions {
|
|
169
|
+
/**
|
|
170
|
+
* Whether to honour the global API key + email pair
|
|
171
|
+
* (`CLOUDFLARE_API_KEY` + `CLOUDFLARE_EMAIL`, surfaced as
|
|
172
|
+
* `X-Auth-Key`/`X-Auth-Email`). Defaults to `true` (Wrangler's behaviour).
|
|
173
|
+
* CLIs that only support scoped API tokens / OAuth should pass `false`.
|
|
174
|
+
*/
|
|
175
|
+
allowGlobalAuthKey?: boolean;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Resolve Cloudflare API credentials from environment variables.
|
|
179
|
+
*
|
|
180
|
+
* Priority (highest to lowest), matching Wrangler's historical order:
|
|
181
|
+
* 1. Global API key + email (`CLOUDFLARE_API_KEY` + `CLOUDFLARE_EMAIL`) —
|
|
182
|
+
* only when `allowGlobalAuthKey` is `true`.
|
|
183
|
+
* 2. API token (`CLOUDFLARE_API_TOKEN`).
|
|
184
|
+
*
|
|
185
|
+
* @returns the resolved credentials, or `undefined` when no env credentials
|
|
186
|
+
* are present.
|
|
187
|
+
*/
|
|
188
|
+
declare function getAuthFromEnv(options?: GetAuthFromEnvOptions): ApiCredentials | undefined;
|
|
189
|
+
interface GetAPITokenOptions extends GetAuthFromEnvOptions {
|
|
190
|
+
/** Persistence backend for the stored OAuth token. */
|
|
191
|
+
storage: AuthConfigStorage;
|
|
192
|
+
/** Logger used to surface the one-time deprecated-v1-`api_token` warning. */
|
|
193
|
+
warningLogger?: Pick<OAuthFlowLogger, "warn">;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Resolve Cloudflare API credentials from the environment, falling back to the
|
|
197
|
+
* locally-stored OAuth token.
|
|
198
|
+
*
|
|
199
|
+
* Resolution order (highest to lowest):
|
|
200
|
+
* 1. {@link getAuthFromEnv} (env credentials).
|
|
201
|
+
* 2. The deprecated v1 `api_token` on disk (with a one-time warning).
|
|
202
|
+
* 3. The stored OAuth access token (from a previous interactive login).
|
|
203
|
+
*
|
|
204
|
+
* Note: this does NOT refresh an expired OAuth token. Callers that need a
|
|
205
|
+
* guaranteed-valid OAuth token should use the flow's
|
|
206
|
+
* `getOAuthTokenFromLocalState()` instead.
|
|
207
|
+
*/
|
|
208
|
+
declare function getAPIToken(options: GetAPITokenOptions): ApiCredentials | undefined;
|
|
209
|
+
/**
|
|
210
|
+
* Like {@link getAPIToken}, but throws a {@link UserError} when no credentials
|
|
211
|
+
* are available.
|
|
212
|
+
*/
|
|
213
|
+
declare function requireApiToken(options: GetAPITokenOptions): ApiCredentials;
|
|
214
|
+
|
|
124
215
|
/**
|
|
125
216
|
* Clear internal caches. Exported for use in tests only.
|
|
126
217
|
*/
|
|
@@ -165,15 +256,6 @@ declare function getCloudflareAccessHeaders(options: {
|
|
|
165
256
|
isNonInteractiveOrCI: () => boolean;
|
|
166
257
|
}): Promise<Record<string, string>>;
|
|
167
258
|
|
|
168
|
-
/**
|
|
169
|
-
* `WRANGLER_CLIENT_ID` is a UUID that is used to identify Wrangler
|
|
170
|
-
* to the Cloudflare APIs.
|
|
171
|
-
*
|
|
172
|
-
* Normally you should not need to set this explicitly.
|
|
173
|
-
* If you want to switch to the staging environment set the
|
|
174
|
-
* `WRANGLER_API_ENVIRONMENT=staging` environment variable instead.
|
|
175
|
-
*/
|
|
176
|
-
declare const getClientIdFromEnv: () => string;
|
|
177
259
|
/**
|
|
178
260
|
* `WRANGLER_AUTH_DOMAIN` is the URL base domain that is used
|
|
179
261
|
* to access OAuth URLs for the Cloudflare APIs.
|
|
@@ -236,11 +318,21 @@ declare const getCfAuthorizationTokenFromEnv: () => string | undefined;
|
|
|
236
318
|
|
|
237
319
|
/**
|
|
238
320
|
* A list of OAuth2AuthCodePKCE errors.
|
|
321
|
+
*
|
|
322
|
+
* Instances may carry the structured details from the OAuth provider's
|
|
323
|
+
* `error`, `error_description` and `error_uri` query parameters (RFC 6749
|
|
324
|
+
* §4.1.2.1) so callers can render them — see {@link toErrorClass}.
|
|
239
325
|
*/
|
|
240
326
|
declare class ErrorOAuth2 extends UserError {
|
|
327
|
+
/** The OAuth `error` code returned by the provider (e.g. `invalid_scope`). */
|
|
328
|
+
code?: string;
|
|
329
|
+
/** The OAuth `error_description` returned by the provider, if any. */
|
|
330
|
+
description?: string;
|
|
331
|
+
/** The OAuth `error_uri` returned by the provider, if any. */
|
|
332
|
+
uri?: string;
|
|
241
333
|
toString(): string;
|
|
242
334
|
}
|
|
243
|
-
declare class ErrorUnknown extends
|
|
335
|
+
declare class ErrorUnknown extends ErrorOAuth2 {
|
|
244
336
|
toString(): string;
|
|
245
337
|
}
|
|
246
338
|
declare class ErrorNoAuthCode extends ErrorOAuth2 {
|
|
@@ -299,10 +391,41 @@ declare class ErrorUnsupportedGrantType extends ErrorAccessTokenResponse {
|
|
|
299
391
|
toString(): string;
|
|
300
392
|
}
|
|
301
393
|
/**
|
|
302
|
-
* Translate
|
|
394
|
+
* Translate an OAuth error response from the provider into one of our error
|
|
395
|
+
* classes. The `error_description` and `error_uri` parameters (RFC 6749
|
|
396
|
+
* §4.1.2.1) are included in the message when present so the user sees the
|
|
397
|
+
* specific reason for the failure rather than just the bare error code, and
|
|
398
|
+
* are also attached as structured fields so the HTTP callback handler can
|
|
399
|
+
* render them on the browser-facing error page.
|
|
303
400
|
*/
|
|
304
|
-
declare function toErrorClass(rawError: string): ErrorOAuth2 | ErrorUnknown;
|
|
401
|
+
declare function toErrorClass(rawError: string, description?: string, uri?: string): ErrorOAuth2 | ErrorUnknown;
|
|
305
402
|
|
|
403
|
+
/**
|
|
404
|
+
* Reason why {@link OAuthFlowAPI.loginOrRefreshIfRequired} could not
|
|
405
|
+
* authenticate the user.
|
|
406
|
+
*/
|
|
407
|
+
type LoginOrRefreshFailureReason =
|
|
408
|
+
/** no stored credentials and the environment is non-interactive (CI, piped stdin, etc.) so a browser login cannot be started. */
|
|
409
|
+
"no-credentials-non-interactive"
|
|
410
|
+
/** stored credentials and the interactive login attempt was unsuccessful (user cancelled, etc.). */
|
|
411
|
+
| "no-credentials-login-failed"
|
|
412
|
+
/** the stored token has expired, refresh failed, and the environment is non-interactive so a browser login cannot be started. */
|
|
413
|
+
| "token-expired-non-interactive"
|
|
414
|
+
/** the stored token has expired, refresh failed, and the interactive login attempt was unsuccessful. */
|
|
415
|
+
| "token-expired-login-failed";
|
|
416
|
+
/**
|
|
417
|
+
* Discriminated union returned by {@link OAuthFlowAPI.loginOrRefreshIfRequired}.
|
|
418
|
+
*
|
|
419
|
+
* When `loggedIn` is `true` the caller can proceed. When `false`, `reason`
|
|
420
|
+
* describes why authentication failed so the caller can surface a
|
|
421
|
+
* targeted error message.
|
|
422
|
+
*/
|
|
423
|
+
type LoginOrRefreshResult = {
|
|
424
|
+
loggedIn: true;
|
|
425
|
+
} | {
|
|
426
|
+
loggedIn: false;
|
|
427
|
+
reason: LoginOrRefreshFailureReason;
|
|
428
|
+
};
|
|
306
429
|
/**
|
|
307
430
|
* Options for an interactive OAuth login.
|
|
308
431
|
*/
|
|
@@ -354,11 +477,12 @@ interface OAuthFlowAPI {
|
|
|
354
477
|
* Scopes are required in case an interactive login is triggered — the
|
|
355
478
|
* consumer's scope catalog lives outside this package.
|
|
356
479
|
*
|
|
357
|
-
* @returns `true` when the user is
|
|
358
|
-
* present)
|
|
359
|
-
*
|
|
480
|
+
* @returns `{ loggedIn: true }` when the user is authenticated (or env
|
|
481
|
+
* credentials are present). When authentication fails, returns
|
|
482
|
+
* `{ loggedIn: false, reason }` describing why — see
|
|
483
|
+
* {@link LoginOrRefreshFailureReason}.
|
|
360
484
|
*/
|
|
361
|
-
loginOrRefreshIfRequired(props: LoginProps): Promise<
|
|
485
|
+
loginOrRefreshIfRequired(props: LoginProps): Promise<LoginOrRefreshResult>;
|
|
362
486
|
/**
|
|
363
487
|
* Read the OAuth access token from local state, refreshing it first if
|
|
364
488
|
* needed. Returns `undefined` when there is no stored OAuth token or the
|
|
@@ -466,10 +590,14 @@ interface StoredAuthState {
|
|
|
466
590
|
* @param options.warningLogger if provided, a one-time warning is emitted when a
|
|
467
591
|
* deprecated v1 `api_token` is found on disk. Pass the consumer's logger (e.g.
|
|
468
592
|
* wrangler's logger singleton) to surface this to the user.
|
|
593
|
+
* @param options.storage the persistence backend to read from, injected by the
|
|
594
|
+
* consumer (e.g. wrangler's TOML-file-on-disk storage under the global Wrangler
|
|
595
|
+
* config directory).
|
|
469
596
|
*/
|
|
470
|
-
declare function readStoredAuthState(options
|
|
597
|
+
declare function readStoredAuthState(options: {
|
|
471
598
|
configOverride?: UserAuthConfig;
|
|
472
599
|
warningLogger?: Pick<OAuthFlowLogger, "warn">;
|
|
600
|
+
storage: AuthConfigStorage;
|
|
473
601
|
}): StoredAuthState;
|
|
474
602
|
|
|
475
|
-
export { type AccessToken, ErrorAccessDenied, ErrorAccessTokenResponse, ErrorAuthenticationGrant, ErrorInvalidClient, ErrorInvalidGrant, ErrorInvalidJson, ErrorInvalidRequest, ErrorInvalidReturnedStateParam, ErrorInvalidScope, ErrorInvalidToken, ErrorNoAuthCode, ErrorOAuth2, ErrorServerError, ErrorTemporarilyUnavailable, ErrorUnauthorizedClient, ErrorUnknown, ErrorUnsupportedGrantType, ErrorUnsupportedResponseType, type LoginProps,
|
|
603
|
+
export { type AccessToken, type AuthConfigStorage, ErrorAccessDenied, ErrorAccessTokenResponse, ErrorAuthenticationGrant, ErrorInvalidClient, ErrorInvalidGrant, ErrorInvalidJson, ErrorInvalidRequest, ErrorInvalidReturnedStateParam, ErrorInvalidScope, ErrorInvalidToken, ErrorNoAuthCode, ErrorOAuth2, ErrorServerError, ErrorTemporarilyUnavailable, ErrorUnauthorizedClient, ErrorUnknown, ErrorUnsupportedGrantType, ErrorUnsupportedResponseType, type GetAPITokenOptions, type GetAuthFromEnvOptions, type LoginOrRefreshFailureReason, type LoginOrRefreshResult, type LoginProps, type OAuthConsentPages, type OAuthFlowAPI, type OAuthFlowContext, type OAuthFlowLogger, type OAuthFlowState, type PKCECodes, PKCE_CHARSET, RECOMMENDED_CODE_VERIFIER_LENGTH, RECOMMENDED_STATE_LENGTH, type RefreshToken, type StoredAuthState, type UserAuthConfig, base64urlEncode, clearAccessCaches, createOAuthFlow, domainUsesAccess, generateAuthUrl, generatePKCECodes, generateRandomState, getAPIToken, getAccessClientIdFromEnv, getAccessClientSecretFromEnv, getAccessHeaders, getAuthDomainFromEnv, getAuthFromEnv, getAuthUrlFromEnv, getCfAuthorizationTokenFromEnv, getCloudflareAPITokenFromEnv, getCloudflareAccessHeaders, getCloudflareGlobalAuthEmailFromEnv, getCloudflareGlobalAuthKeyFromEnv, getRevokeUrlFromEnv, getTokenUrlFromEnv, readStoredAuthState, requireApiToken, toErrorClass };
|