@cloudflare/workers-auth 0.2.0 → 0.3.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/index.d.mts +100 -240
- package/dist/index.mjs +301 -48
- package/dist/metafile-esm.json +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
import { ApiCredentials,
|
|
1
|
+
import { ApiCredentials, ComplianceConfig } from '@cloudflare/workers-utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pluggable persistence for a typed config blob
|
|
5
|
+
*/
|
|
6
|
+
interface ConfigStorage<T> {
|
|
7
|
+
/**
|
|
8
|
+
* Read and parse the stored config.
|
|
9
|
+
* @throws if the backing store is missing or cannot be parsed.
|
|
10
|
+
*/
|
|
11
|
+
read(): T;
|
|
12
|
+
/** Serialize and persist the config. */
|
|
13
|
+
write(config: T): void;
|
|
14
|
+
/** Remove the backing store; returns whether anything existed beforehand. */
|
|
15
|
+
clear(): boolean;
|
|
16
|
+
/** Human-readable location of the backing store, for display and warnings. */
|
|
17
|
+
path(): string;
|
|
18
|
+
}
|
|
2
19
|
|
|
3
20
|
/**
|
|
4
21
|
* The data that may be read from the on-disk user auth config file.
|
|
@@ -11,30 +28,24 @@ interface UserAuthConfig {
|
|
|
11
28
|
/** @deprecated - this field was only provided by the deprecated v1 `wrangler config` command. */
|
|
12
29
|
api_token?: string;
|
|
13
30
|
}
|
|
31
|
+
type AuthConfigStorage = ConfigStorage<UserAuthConfig>;
|
|
32
|
+
|
|
14
33
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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).
|
|
34
|
+
* A short-lived "temporary preview account"
|
|
23
35
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
36
|
+
type TemporaryPreviewAccount = {
|
|
37
|
+
account: {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
apiToken: string;
|
|
41
|
+
expiresAt: string;
|
|
42
|
+
};
|
|
43
|
+
claim: {
|
|
44
|
+
url: string;
|
|
45
|
+
expiresAt: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
type TemporaryAccountStorage = ConfigStorage<TemporaryPreviewAccount>;
|
|
38
49
|
|
|
39
50
|
interface GenerateAuthUrlProps {
|
|
40
51
|
authUrl: string;
|
|
@@ -62,6 +73,22 @@ declare const generateAuthUrl: ({ authUrl, clientId, scopes, stateQueryParam, co
|
|
|
62
73
|
*/
|
|
63
74
|
declare function generateRandomState(lengthOfState: number): string;
|
|
64
75
|
|
|
76
|
+
/**
|
|
77
|
+
* The dependencies the OAuth flow needs to mint/reuse a short-lived "temporary
|
|
78
|
+
* preview account"
|
|
79
|
+
*/
|
|
80
|
+
interface OAuthFlowTemporaryContext {
|
|
81
|
+
/** Persistence backend for the cached temporary preview account. */
|
|
82
|
+
storage: TemporaryAccountStorage;
|
|
83
|
+
/**
|
|
84
|
+
* Hook to customise the terms-acceptance interactive prompt
|
|
85
|
+
* - question: the question to ask a user in interactive mode.
|
|
86
|
+
* return answer === "yes" (must be the literal string)
|
|
87
|
+
* - notice: the notice to print on stderr if in non-interactive mode
|
|
88
|
+
* always return true
|
|
89
|
+
*/
|
|
90
|
+
prompt: (question: string, notice: string) => Promise<boolean>;
|
|
91
|
+
}
|
|
65
92
|
/**
|
|
66
93
|
* The branded OAuth consent pages the provider redirects the browser to after
|
|
67
94
|
* the user grants or denies consent.
|
|
@@ -144,6 +171,16 @@ interface OAuthFlowContext {
|
|
|
144
171
|
* Persistence backend for the stored auth config.
|
|
145
172
|
*/
|
|
146
173
|
storage: AuthConfigStorage;
|
|
174
|
+
/**
|
|
175
|
+
* Whether the flow's credential resolvers (`getAPIToken` / `requireApiToken`)
|
|
176
|
+
* should honour the global API key + email pair in addition to scoped API
|
|
177
|
+
* tokens.
|
|
178
|
+
*/
|
|
179
|
+
allowGlobalAuthKey: boolean;
|
|
180
|
+
/**
|
|
181
|
+
* Dependencies for minting/reusing a temporary preview account.
|
|
182
|
+
*/
|
|
183
|
+
temporary: OAuthFlowTemporaryContext | undefined;
|
|
147
184
|
/**
|
|
148
185
|
* Override the OAuth authorize URL generator. Used by tests to produce a
|
|
149
186
|
* deterministic URL for snapshot testing. Defaults to the standard
|
|
@@ -186,31 +223,6 @@ interface GetAuthFromEnvOptions {
|
|
|
186
223
|
* are present.
|
|
187
224
|
*/
|
|
188
225
|
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
226
|
|
|
215
227
|
/**
|
|
216
228
|
* Clear internal caches. Exported for use in tests only.
|
|
@@ -243,28 +255,7 @@ declare function getAccessHeaders(domain: string, options: {
|
|
|
243
255
|
logger: OAuthFlowLogger;
|
|
244
256
|
isNonInteractiveOrCI: () => boolean;
|
|
245
257
|
}): Promise<Record<string, string>>;
|
|
246
|
-
/**
|
|
247
|
-
* Get headers needed to authenticate with the Cloudflare OAuth auth domain
|
|
248
|
-
* (the OAuth `WRANGLER_AUTH_DOMAIN`, which is `dash.cloudflare.com` by default
|
|
249
|
-
* and `dash.staging.cloudflare.com` in staging).
|
|
250
|
-
*
|
|
251
|
-
* Checks `WRANGLER_CF_AUTHORIZATION_TOKEN` first, then falls back to
|
|
252
|
-
* {@link getAccessHeaders} against the configured auth domain.
|
|
253
|
-
*/
|
|
254
|
-
declare function getCloudflareAccessHeaders(options: {
|
|
255
|
-
logger: OAuthFlowLogger;
|
|
256
|
-
isNonInteractiveOrCI: () => boolean;
|
|
257
|
-
}): Promise<Record<string, string>>;
|
|
258
258
|
|
|
259
|
-
/**
|
|
260
|
-
* `WRANGLER_AUTH_DOMAIN` is the URL base domain that is used
|
|
261
|
-
* to access OAuth URLs for the Cloudflare APIs.
|
|
262
|
-
*
|
|
263
|
-
* Normally you should not need to set this explicitly.
|
|
264
|
-
* If you want to switch to the staging environment set the
|
|
265
|
-
* `WRANGLER_API_ENVIRONMENT=staging` environment variable instead.
|
|
266
|
-
*/
|
|
267
|
-
declare const getAuthDomainFromEnv: () => string;
|
|
268
259
|
/**
|
|
269
260
|
* `WRANGLER_AUTH_URL` is the path that is used to access OAuth
|
|
270
261
|
* for the Cloudflare APIs.
|
|
@@ -274,131 +265,6 @@ declare const getAuthDomainFromEnv: () => string;
|
|
|
274
265
|
* `WRANGLER_API_ENVIRONMENT=staging` environment variable instead.
|
|
275
266
|
*/
|
|
276
267
|
declare const getAuthUrlFromEnv: () => string;
|
|
277
|
-
/**
|
|
278
|
-
* `WRANGLER_TOKEN_URL` is the path that is used to exchange an OAuth
|
|
279
|
-
* token for an API token.
|
|
280
|
-
*
|
|
281
|
-
* Normally you should not need to set this explicitly.
|
|
282
|
-
* If you want to switch to the staging environment set the
|
|
283
|
-
* `WRANGLER_API_ENVIRONMENT=staging` environment variable instead.
|
|
284
|
-
*/
|
|
285
|
-
declare const getTokenUrlFromEnv: () => string;
|
|
286
|
-
/**
|
|
287
|
-
* `WRANGLER_REVOKE_URL` is the path that is used to exchange an OAuth
|
|
288
|
-
* refresh token for a new OAuth token.
|
|
289
|
-
*
|
|
290
|
-
* Normally you should not need to set this explicitly.
|
|
291
|
-
* If you want to switch to the staging environment set the
|
|
292
|
-
* `WRANGLER_API_ENVIRONMENT=staging` environment variable instead.
|
|
293
|
-
*/
|
|
294
|
-
declare const getRevokeUrlFromEnv: () => string;
|
|
295
|
-
/**
|
|
296
|
-
* `CLOUDFLARE_ACCESS_CLIENT_ID` is the Client ID of a Cloudflare Access Service Token.
|
|
297
|
-
* Used together with `CLOUDFLARE_ACCESS_CLIENT_SECRET` to authenticate with
|
|
298
|
-
* Access-protected domains in non-interactive environments (e.g. CI).
|
|
299
|
-
*
|
|
300
|
-
* @see https://developers.cloudflare.com/cloudflare-one/access-controls/service-credentials/service-tokens/
|
|
301
|
-
*/
|
|
302
|
-
declare const getAccessClientIdFromEnv: () => string | undefined;
|
|
303
|
-
/**
|
|
304
|
-
* `CLOUDFLARE_ACCESS_CLIENT_SECRET` is the Client Secret of a Cloudflare Access Service Token.
|
|
305
|
-
* Used together with `CLOUDFLARE_ACCESS_CLIENT_ID` to authenticate with
|
|
306
|
-
* Access-protected domains in non-interactive environments (e.g. CI).
|
|
307
|
-
*
|
|
308
|
-
* @see https://developers.cloudflare.com/cloudflare-one/access-controls/service-credentials/service-tokens/
|
|
309
|
-
*/
|
|
310
|
-
declare const getAccessClientSecretFromEnv: () => string | undefined;
|
|
311
|
-
/**
|
|
312
|
-
* `WRANGLER_CF_AUTHORIZATION_TOKEN` is an explicit `CF_Authorization` cookie value
|
|
313
|
-
* used to authenticate against the OAuth auth domain when it is Access-protected
|
|
314
|
-
* (typically staging). When set, the OAuth flow skips Access detection and uses
|
|
315
|
-
* this token directly.
|
|
316
|
-
*/
|
|
317
|
-
declare const getCfAuthorizationTokenFromEnv: () => string | undefined;
|
|
318
|
-
|
|
319
|
-
/**
|
|
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}.
|
|
325
|
-
*/
|
|
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;
|
|
333
|
-
toString(): string;
|
|
334
|
-
}
|
|
335
|
-
declare class ErrorUnknown extends ErrorOAuth2 {
|
|
336
|
-
toString(): string;
|
|
337
|
-
}
|
|
338
|
-
declare class ErrorNoAuthCode extends ErrorOAuth2 {
|
|
339
|
-
toString(): string;
|
|
340
|
-
}
|
|
341
|
-
declare class ErrorInvalidReturnedStateParam extends ErrorOAuth2 {
|
|
342
|
-
toString(): string;
|
|
343
|
-
}
|
|
344
|
-
declare class ErrorInvalidJson extends ErrorOAuth2 {
|
|
345
|
-
toString(): string;
|
|
346
|
-
}
|
|
347
|
-
declare class ErrorInvalidScope extends ErrorOAuth2 {
|
|
348
|
-
toString(): string;
|
|
349
|
-
}
|
|
350
|
-
declare class ErrorInvalidRequest extends ErrorOAuth2 {
|
|
351
|
-
toString(): string;
|
|
352
|
-
}
|
|
353
|
-
declare class ErrorInvalidToken extends ErrorOAuth2 {
|
|
354
|
-
toString(): string;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Possible authorization grant errors given by the redirection from the
|
|
358
|
-
* authorization server.
|
|
359
|
-
*/
|
|
360
|
-
declare class ErrorAuthenticationGrant extends ErrorOAuth2 {
|
|
361
|
-
toString(): string;
|
|
362
|
-
}
|
|
363
|
-
declare class ErrorUnauthorizedClient extends ErrorAuthenticationGrant {
|
|
364
|
-
toString(): string;
|
|
365
|
-
}
|
|
366
|
-
declare class ErrorAccessDenied extends ErrorAuthenticationGrant {
|
|
367
|
-
toString(): string;
|
|
368
|
-
}
|
|
369
|
-
declare class ErrorUnsupportedResponseType extends ErrorAuthenticationGrant {
|
|
370
|
-
toString(): string;
|
|
371
|
-
}
|
|
372
|
-
declare class ErrorServerError extends ErrorAuthenticationGrant {
|
|
373
|
-
toString(): string;
|
|
374
|
-
}
|
|
375
|
-
declare class ErrorTemporarilyUnavailable extends ErrorAuthenticationGrant {
|
|
376
|
-
toString(): string;
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* A list of possible access token response errors.
|
|
380
|
-
*/
|
|
381
|
-
declare class ErrorAccessTokenResponse extends ErrorOAuth2 {
|
|
382
|
-
toString(): string;
|
|
383
|
-
}
|
|
384
|
-
declare class ErrorInvalidClient extends ErrorAccessTokenResponse {
|
|
385
|
-
toString(): string;
|
|
386
|
-
}
|
|
387
|
-
declare class ErrorInvalidGrant extends ErrorAccessTokenResponse {
|
|
388
|
-
toString(): string;
|
|
389
|
-
}
|
|
390
|
-
declare class ErrorUnsupportedGrantType extends ErrorAccessTokenResponse {
|
|
391
|
-
toString(): string;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
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.
|
|
400
|
-
*/
|
|
401
|
-
declare function toErrorClass(rawError: string, description?: string, uri?: string): ErrorOAuth2 | ErrorUnknown;
|
|
402
268
|
|
|
403
269
|
/**
|
|
404
270
|
* Reason why {@link OAuthFlowAPI.loginOrRefreshIfRequired} could not
|
|
@@ -493,17 +359,45 @@ interface OAuthFlowAPI {
|
|
|
493
359
|
*/
|
|
494
360
|
getOAuthTokenFromLocalState(): Promise<string | undefined>;
|
|
495
361
|
/**
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
362
|
+
* Resolve API credentials, preferring an active temporary preview account
|
|
363
|
+
* (when one has been latched via {@link activateTemporaryAccount}) over the
|
|
364
|
+
* env / stored-OAuth resolution performed by the shared credential resolver.
|
|
365
|
+
*
|
|
366
|
+
* Returns `undefined` when no credentials are available.
|
|
367
|
+
*/
|
|
368
|
+
getAPIToken(): ApiCredentials | undefined;
|
|
369
|
+
/**
|
|
370
|
+
* Like {@link getAPIToken}, but throws a `UserError` when no credentials are
|
|
371
|
+
* available.
|
|
372
|
+
*/
|
|
373
|
+
requireApiToken(): ApiCredentials;
|
|
374
|
+
/**
|
|
375
|
+
* Establish whether `--temporary` is permitted for this invocation. Called
|
|
376
|
+
* once at command dispatch by the consumer. Also drops any temporary account
|
|
377
|
+
* latched by a previous dispatch, so that — when multiple commands share a
|
|
378
|
+
* process (e.g. in tests) — each invocation starts a fresh temporary session.
|
|
379
|
+
* No-op when the flow was created without a `temporary` context.
|
|
380
|
+
*/
|
|
381
|
+
setTemporaryAllowed(allowed: boolean): void;
|
|
382
|
+
/**
|
|
383
|
+
* Whether `--temporary` is permitted for this invocation (see
|
|
384
|
+
* {@link setTemporaryAllowed}). Always `false` without a `temporary` context.
|
|
385
|
+
*/
|
|
386
|
+
isTemporaryAllowed(): boolean;
|
|
387
|
+
/**
|
|
388
|
+
* The temporary preview account latched for this invocation, or `undefined`.
|
|
389
|
+
* Only set after {@link activateTemporaryAccount} has run.
|
|
500
390
|
*/
|
|
501
|
-
|
|
391
|
+
getActiveTemporaryAccount(): TemporaryPreviewAccount | undefined;
|
|
502
392
|
/**
|
|
503
|
-
*
|
|
504
|
-
*
|
|
393
|
+
* The sole creator of the temporary-account latch: mint a fresh temporary
|
|
394
|
+
* preview account (or reuse a cached one), latch it for this invocation, and
|
|
395
|
+
* return it. Requires a `temporary` context.
|
|
505
396
|
*/
|
|
506
|
-
|
|
397
|
+
activateTemporaryAccount(): Promise<{
|
|
398
|
+
account: TemporaryPreviewAccount;
|
|
399
|
+
cached: boolean;
|
|
400
|
+
}>;
|
|
507
401
|
}
|
|
508
402
|
/**
|
|
509
403
|
* Build an instance of the OAuth flow bound to the given context.
|
|
@@ -514,35 +408,13 @@ interface OAuthFlowAPI {
|
|
|
514
408
|
*/
|
|
515
409
|
declare function createOAuthFlow(ctx: OAuthFlowContext): OAuthFlowAPI;
|
|
516
410
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
* but <= 128, **after** base64 url encoding. This means 32 code verifier bytes
|
|
521
|
-
* encoded will be 43 bytes, or 96 bytes encoded will be 128 bytes. So 96 bytes
|
|
522
|
-
* is the highest valid value that can be used.
|
|
523
|
-
*/
|
|
524
|
-
declare const RECOMMENDED_CODE_VERIFIER_LENGTH = 96;
|
|
525
|
-
/**
|
|
526
|
-
* A sensible length for the state's length, for anti-csrf.
|
|
527
|
-
*/
|
|
528
|
-
declare const RECOMMENDED_STATE_LENGTH = 32;
|
|
411
|
+
declare const TEMPORARY_TERMS_PROMPT: string;
|
|
412
|
+
declare const TEMPORARY_TERMS_NOTICE: string;
|
|
413
|
+
|
|
529
414
|
/**
|
|
530
415
|
* Character set to generate code verifier defined in rfc7636.
|
|
531
416
|
*/
|
|
532
417
|
declare const PKCE_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
|
533
|
-
interface PKCECodes {
|
|
534
|
-
codeChallenge: string;
|
|
535
|
-
codeVerifier: string;
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Implements *base64url-encode* (RFC 4648 § 5) without padding, which is NOT
|
|
539
|
-
* the same as regular base64 encoding.
|
|
540
|
-
*/
|
|
541
|
-
declare function base64urlEncode(value: string): string;
|
|
542
|
-
/**
|
|
543
|
-
* Generates a code_verifier and code_challenge, as specified in rfc7636.
|
|
544
|
-
*/
|
|
545
|
-
declare function generatePKCECodes(): Promise<PKCECodes>;
|
|
546
418
|
|
|
547
419
|
interface RefreshToken {
|
|
548
420
|
value: string;
|
|
@@ -551,18 +423,6 @@ interface AccessToken {
|
|
|
551
423
|
value: string;
|
|
552
424
|
expiry: string;
|
|
553
425
|
}
|
|
554
|
-
/**
|
|
555
|
-
* Transient state that is shared across the steps of a single OAuth login flow
|
|
556
|
-
* within one Wrangler command. This state is not file-backed; it lives only for
|
|
557
|
-
* the duration of an interactive login.
|
|
558
|
-
*/
|
|
559
|
-
interface OAuthFlowState {
|
|
560
|
-
authorizationCode?: string;
|
|
561
|
-
codeChallenge?: string;
|
|
562
|
-
codeVerifier?: string;
|
|
563
|
-
hasAuthCodeBeenExchangedForAccessToken?: boolean;
|
|
564
|
-
stateQueryParam?: string;
|
|
565
|
-
}
|
|
566
426
|
/**
|
|
567
427
|
* The auth state that is stored on disk in the user auth config file (TOML).
|
|
568
428
|
* Read on demand by {@link readStoredAuthState} — never cached at module scope
|
|
@@ -600,4 +460,4 @@ declare function readStoredAuthState(options: {
|
|
|
600
460
|
storage: AuthConfigStorage;
|
|
601
461
|
}): StoredAuthState;
|
|
602
462
|
|
|
603
|
-
export { type
|
|
463
|
+
export { type AuthConfigStorage, type ConfigStorage, type LoginOrRefreshFailureReason, type LoginOrRefreshResult, type LoginProps, PKCE_CHARSET, TEMPORARY_TERMS_NOTICE, TEMPORARY_TERMS_PROMPT, type TemporaryPreviewAccount, type UserAuthConfig, clearAccessCaches, createOAuthFlow, domainUsesAccess, generateAuthUrl, generateRandomState, getAccessHeaders, getAuthFromEnv, getAuthUrlFromEnv, getCloudflareAPITokenFromEnv, getCloudflareGlobalAuthEmailFromEnv, getCloudflareGlobalAuthKeyFromEnv, readStoredAuthState };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __name } from './chunk-O6YSETKJ.mjs';
|
|
2
|
-
import { getEnvironmentVariableFactory, getCloudflareApiEnvironmentFromEnv, UserError, getCloudflareComplianceRegion } from '@cloudflare/workers-utils';
|
|
2
|
+
import { getEnvironmentVariableFactory, getCloudflareApiEnvironmentFromEnv, UserError, getCloudflareApiBaseUrl, COMPLIANCE_REGION_CONFIG_PUBLIC, FatalError, getCloudflareComplianceRegion } from '@cloudflare/workers-utils';
|
|
3
3
|
import { spawnSync } from 'node:child_process';
|
|
4
4
|
import { fetch } from 'undici';
|
|
5
5
|
import assert2 from 'node:assert';
|
|
6
6
|
import http from 'node:http';
|
|
7
7
|
import url from 'node:url';
|
|
8
|
-
import { webcrypto } from 'node:crypto';
|
|
8
|
+
import { webcrypto, createHash } from 'node:crypto';
|
|
9
9
|
import { TextEncoder } from 'node:util';
|
|
10
10
|
|
|
11
11
|
// src/state.ts
|
|
@@ -238,6 +238,48 @@ async function getCloudflareAccessHeaders(options) {
|
|
|
238
238
|
return getAccessHeaders(getAuthDomainFromEnv(), options);
|
|
239
239
|
}
|
|
240
240
|
__name(getCloudflareAccessHeaders, "getCloudflareAccessHeaders");
|
|
241
|
+
|
|
242
|
+
// ../../node_modules/.pnpm/ts-dedent@2.2.0/node_modules/ts-dedent/esm/index.js
|
|
243
|
+
function dedent(templ) {
|
|
244
|
+
var values = [];
|
|
245
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
246
|
+
values[_i - 1] = arguments[_i];
|
|
247
|
+
}
|
|
248
|
+
var strings = Array.from(typeof templ === "string" ? [templ] : templ);
|
|
249
|
+
strings[strings.length - 1] = strings[strings.length - 1].replace(/\r?\n([\t ]*)$/, "");
|
|
250
|
+
var indentLengths = strings.reduce(function(arr, str) {
|
|
251
|
+
var matches = str.match(/\n([\t ]+|(?!\s).)/g);
|
|
252
|
+
if (matches) {
|
|
253
|
+
return arr.concat(matches.map(function(match) {
|
|
254
|
+
var _a, _b;
|
|
255
|
+
return (_b = (_a = match.match(/[\t ]/g)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
256
|
+
}));
|
|
257
|
+
}
|
|
258
|
+
return arr;
|
|
259
|
+
}, []);
|
|
260
|
+
if (indentLengths.length) {
|
|
261
|
+
var pattern_1 = new RegExp("\n[ ]{" + Math.min.apply(Math, indentLengths) + "}", "g");
|
|
262
|
+
strings = strings.map(function(str) {
|
|
263
|
+
return str.replace(pattern_1, "\n");
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
strings[0] = strings[0].replace(/^\r?\n/, "");
|
|
267
|
+
var string = strings[0];
|
|
268
|
+
values.forEach(function(value, i) {
|
|
269
|
+
var endentations = string.match(/(?:^|\n)( *)$/);
|
|
270
|
+
var endentation = endentations ? endentations[1] : "";
|
|
271
|
+
var indentedValue = value;
|
|
272
|
+
if (typeof value === "string" && value.includes("\n")) {
|
|
273
|
+
indentedValue = String(value).split("\n").map(function(str, i2) {
|
|
274
|
+
return i2 === 0 ? str : "" + endentation + str;
|
|
275
|
+
}).join("\n");
|
|
276
|
+
}
|
|
277
|
+
string += indentedValue + strings[i + 1];
|
|
278
|
+
});
|
|
279
|
+
return string;
|
|
280
|
+
}
|
|
281
|
+
__name(dedent, "dedent");
|
|
282
|
+
var esm_default = dedent;
|
|
241
283
|
var ErrorOAuth2 = class extends UserError {
|
|
242
284
|
static {
|
|
243
285
|
__name(this, "ErrorOAuth2");
|
|
@@ -477,48 +519,6 @@ function toErrorClass(rawError, description, uri) {
|
|
|
477
519
|
return error;
|
|
478
520
|
}
|
|
479
521
|
__name(toErrorClass, "toErrorClass");
|
|
480
|
-
|
|
481
|
-
// ../../node_modules/.pnpm/ts-dedent@2.2.0/node_modules/ts-dedent/esm/index.js
|
|
482
|
-
function dedent(templ) {
|
|
483
|
-
var values = [];
|
|
484
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
485
|
-
values[_i - 1] = arguments[_i];
|
|
486
|
-
}
|
|
487
|
-
var strings = Array.from(typeof templ === "string" ? [templ] : templ);
|
|
488
|
-
strings[strings.length - 1] = strings[strings.length - 1].replace(/\r?\n([\t ]*)$/, "");
|
|
489
|
-
var indentLengths = strings.reduce(function(arr, str) {
|
|
490
|
-
var matches = str.match(/\n([\t ]+|(?!\s).)/g);
|
|
491
|
-
if (matches) {
|
|
492
|
-
return arr.concat(matches.map(function(match) {
|
|
493
|
-
var _a, _b;
|
|
494
|
-
return (_b = (_a = match.match(/[\t ]/g)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
495
|
-
}));
|
|
496
|
-
}
|
|
497
|
-
return arr;
|
|
498
|
-
}, []);
|
|
499
|
-
if (indentLengths.length) {
|
|
500
|
-
var pattern_1 = new RegExp("\n[ ]{" + Math.min.apply(Math, indentLengths) + "}", "g");
|
|
501
|
-
strings = strings.map(function(str) {
|
|
502
|
-
return str.replace(pattern_1, "\n");
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
strings[0] = strings[0].replace(/^\r?\n/, "");
|
|
506
|
-
var string = strings[0];
|
|
507
|
-
values.forEach(function(value, i) {
|
|
508
|
-
var endentations = string.match(/(?:^|\n)( *)$/);
|
|
509
|
-
var endentation = endentations ? endentations[1] : "";
|
|
510
|
-
var indentedValue = value;
|
|
511
|
-
if (typeof value === "string" && value.includes("\n")) {
|
|
512
|
-
indentedValue = String(value).split("\n").map(function(str, i2) {
|
|
513
|
-
return i2 === 0 ? str : "" + endentation + str;
|
|
514
|
-
}).join("\n");
|
|
515
|
-
}
|
|
516
|
-
string += indentedValue + strings[i + 1];
|
|
517
|
-
});
|
|
518
|
-
return string;
|
|
519
|
-
}
|
|
520
|
-
__name(dedent, "dedent");
|
|
521
|
-
var esm_default = dedent;
|
|
522
522
|
var RECOMMENDED_CODE_VERIFIER_LENGTH = 96;
|
|
523
523
|
var RECOMMENDED_STATE_LENGTH = 32;
|
|
524
524
|
var PKCE_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
|
@@ -969,6 +969,194 @@ function generateRandomState(lengthOfState) {
|
|
|
969
969
|
return Array.from(output).map((num) => PKCE_CHARSET[num % PKCE_CHARSET.length]).join("");
|
|
970
970
|
}
|
|
971
971
|
__name(generateRandomState, "generateRandomState");
|
|
972
|
+
var POW_MAX_ITERATIONS = 64e6;
|
|
973
|
+
function solvePow(seed, k, g) {
|
|
974
|
+
const checkpoints = new Array(k + 1);
|
|
975
|
+
let h = createHash("sha256").update(seed).digest();
|
|
976
|
+
checkpoints[0] = h;
|
|
977
|
+
for (let j = 0; j < k; j++) {
|
|
978
|
+
for (let i = 0; i < g; i++) {
|
|
979
|
+
h = createHash("sha256").update(h).digest();
|
|
980
|
+
}
|
|
981
|
+
checkpoints[j + 1] = h;
|
|
982
|
+
}
|
|
983
|
+
return checkpoints;
|
|
984
|
+
}
|
|
985
|
+
__name(solvePow, "solvePow");
|
|
986
|
+
function encodeCheckpoints(checkpoints) {
|
|
987
|
+
return Buffer.concat(checkpoints).toString("base64");
|
|
988
|
+
}
|
|
989
|
+
__name(encodeCheckpoints, "encodeCheckpoints");
|
|
990
|
+
function solveChallenge(challenge) {
|
|
991
|
+
const checkpoints = solvePow(
|
|
992
|
+
Buffer.from(challenge.seed, "base64url"),
|
|
993
|
+
challenge.k,
|
|
994
|
+
challenge.g
|
|
995
|
+
);
|
|
996
|
+
return {
|
|
997
|
+
challengeToken: challenge.challengeToken,
|
|
998
|
+
solution: { checkpoints: encodeCheckpoints(checkpoints) }
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
__name(solveChallenge, "solveChallenge");
|
|
1002
|
+
|
|
1003
|
+
// src/temporary.ts
|
|
1004
|
+
var TEMPORARY_TERMS_URLS = {
|
|
1005
|
+
termsOfService: "https://www.cloudflare.com/terms/",
|
|
1006
|
+
privacyPolicy: "https://www.cloudflare.com/privacypolicy/"
|
|
1007
|
+
};
|
|
1008
|
+
var TEMPORARY_TERMS_PROMPT = `You must accept Cloudflare's Terms of Service (${TEMPORARY_TERMS_URLS.termsOfService}) and Privacy Policy (${TEMPORARY_TERMS_URLS.privacyPolicy}) in order to continue. By typing "yes", you agree to these terms. Type "yes" to continue.`;
|
|
1009
|
+
var TEMPORARY_TERMS_NOTICE = `Continuing means you accept Cloudflare's Terms of Service (${TEMPORARY_TERMS_URLS.termsOfService}) and Privacy Policy (${TEMPORARY_TERMS_URLS.privacyPolicy}).`;
|
|
1010
|
+
var TEMPORARY_TERMS_ERROR = `You must accept Cloudflare's Terms of Service (${TEMPORARY_TERMS_URLS.termsOfService}) and Privacy Policy (${TEMPORARY_TERMS_URLS.privacyPolicy}) to use --temporary.`;
|
|
1011
|
+
function getTemporaryPreviewUrl() {
|
|
1012
|
+
return `${getCloudflareApiBaseUrl(COMPLIANCE_REGION_CONFIG_PUBLIC)}/provisioning/previews`;
|
|
1013
|
+
}
|
|
1014
|
+
__name(getTemporaryPreviewUrl, "getTemporaryPreviewUrl");
|
|
1015
|
+
function getTemporaryPreviewChallengeUrl() {
|
|
1016
|
+
return `${getTemporaryPreviewUrl()}/challenge`;
|
|
1017
|
+
}
|
|
1018
|
+
__name(getTemporaryPreviewChallengeUrl, "getTemporaryPreviewChallengeUrl");
|
|
1019
|
+
function isFutureTimestamp(timestamp) {
|
|
1020
|
+
const parsed = Date.parse(timestamp);
|
|
1021
|
+
return !Number.isNaN(parsed) && parsed > Date.now();
|
|
1022
|
+
}
|
|
1023
|
+
__name(isFutureTimestamp, "isFutureTimestamp");
|
|
1024
|
+
function getCachedTemporaryPreviewAccount(storage) {
|
|
1025
|
+
let temporaryPreviewAccount;
|
|
1026
|
+
try {
|
|
1027
|
+
temporaryPreviewAccount = storage.read();
|
|
1028
|
+
} catch {
|
|
1029
|
+
return void 0;
|
|
1030
|
+
}
|
|
1031
|
+
if (!temporaryPreviewAccount) {
|
|
1032
|
+
return void 0;
|
|
1033
|
+
}
|
|
1034
|
+
if (!temporaryPreviewAccount.account?.id || !temporaryPreviewAccount.account?.apiToken || !temporaryPreviewAccount.account?.name || !temporaryPreviewAccount.claim?.url || !isFutureTimestamp(temporaryPreviewAccount.account?.expiresAt ?? "") || !isFutureTimestamp(temporaryPreviewAccount.claim?.expiresAt ?? "")) {
|
|
1035
|
+
return void 0;
|
|
1036
|
+
}
|
|
1037
|
+
return temporaryPreviewAccount;
|
|
1038
|
+
}
|
|
1039
|
+
__name(getCachedTemporaryPreviewAccount, "getCachedTemporaryPreviewAccount");
|
|
1040
|
+
async function requestPowSolution(logger) {
|
|
1041
|
+
const response = await fetch(getTemporaryPreviewChallengeUrl(), {
|
|
1042
|
+
method: "POST",
|
|
1043
|
+
headers: { "Content-Type": "application/json" },
|
|
1044
|
+
body: "{}"
|
|
1045
|
+
});
|
|
1046
|
+
if (!response.ok) {
|
|
1047
|
+
throw new FatalError(
|
|
1048
|
+
`Failed to request a proof-of-work challenge (${response.status} ${response.statusText}).`,
|
|
1049
|
+
{ telemetryMessage: "deploy temporary account challenge failed" }
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
let body;
|
|
1053
|
+
try {
|
|
1054
|
+
body = await response.json();
|
|
1055
|
+
} catch {
|
|
1056
|
+
throw new FatalError(
|
|
1057
|
+
`Failed to request a proof-of-work challenge. Received an invalid response (${response.status} ${response.statusText}).`,
|
|
1058
|
+
{
|
|
1059
|
+
telemetryMessage: "deploy temporary account challenge invalid response"
|
|
1060
|
+
}
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
const { challengeToken, seed, k, g } = body.result ?? {};
|
|
1064
|
+
if (challengeToken === void 0 || seed === void 0 || k === void 0 || g === void 0) {
|
|
1065
|
+
throw new FatalError(
|
|
1066
|
+
"Failed to request a proof-of-work challenge because the response was missing required fields.",
|
|
1067
|
+
{ telemetryMessage: "deploy temporary account challenge incomplete" }
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
if (!Number.isInteger(k) || !Number.isInteger(g) || k <= 0 || g <= 0 || k * g > POW_MAX_ITERATIONS || Buffer.from(seed, "base64url").length !== 32) {
|
|
1071
|
+
throw new FatalError(
|
|
1072
|
+
"The proof-of-work challenge is not supported by this version of Wrangler.",
|
|
1073
|
+
{
|
|
1074
|
+
telemetryMessage: "deploy temporary account challenge difficulty unsupported"
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
logger.log("Solving proof-of-work challenge\u2026");
|
|
1079
|
+
return solveChallenge({ challengeToken, seed, k, g });
|
|
1080
|
+
}
|
|
1081
|
+
__name(requestPowSolution, "requestPowSolution");
|
|
1082
|
+
async function createTemporaryPreviewAccount(logger) {
|
|
1083
|
+
const pow = await requestPowSolution(logger);
|
|
1084
|
+
const response = await fetch(getTemporaryPreviewUrl(), {
|
|
1085
|
+
method: "POST",
|
|
1086
|
+
headers: { "Content-Type": "application/json" },
|
|
1087
|
+
body: JSON.stringify({
|
|
1088
|
+
termsOfService: TEMPORARY_TERMS_URLS.termsOfService,
|
|
1089
|
+
privacyPolicy: TEMPORARY_TERMS_URLS.privacyPolicy,
|
|
1090
|
+
acceptTermsOfService: "yes",
|
|
1091
|
+
challengeToken: pow.challengeToken,
|
|
1092
|
+
solution: pow.solution
|
|
1093
|
+
})
|
|
1094
|
+
});
|
|
1095
|
+
if (!response.ok) {
|
|
1096
|
+
throw new FatalError(
|
|
1097
|
+
`Failed to create a temporary preview account (${response.status} ${response.statusText}).`,
|
|
1098
|
+
{ telemetryMessage: "deploy temporary account create failed" }
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
let responseBody;
|
|
1102
|
+
try {
|
|
1103
|
+
responseBody = await response.json();
|
|
1104
|
+
} catch {
|
|
1105
|
+
throw new FatalError(
|
|
1106
|
+
`Failed to create a temporary preview account. Received an invalid response (${response.status} ${response.statusText}).`,
|
|
1107
|
+
{ telemetryMessage: "deploy temporary account invalid response" }
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
const previewAccount = responseBody.result;
|
|
1111
|
+
const accountId = previewAccount?.account?.id;
|
|
1112
|
+
const accountName = previewAccount?.account?.name;
|
|
1113
|
+
const apiToken = previewAccount?.account?.apiToken;
|
|
1114
|
+
const accountExpiresAt = previewAccount?.account?.expiresAt;
|
|
1115
|
+
const claimUrl = previewAccount?.claim?.url;
|
|
1116
|
+
const claimExpiresAt = previewAccount?.claim?.expiresAt;
|
|
1117
|
+
if (accountId === void 0 || accountName === void 0 || apiToken === void 0 || accountExpiresAt === void 0 || claimUrl === void 0 || claimExpiresAt === void 0) {
|
|
1118
|
+
throw new FatalError(
|
|
1119
|
+
"Failed to create a temporary preview account because the response was missing required fields.",
|
|
1120
|
+
{ telemetryMessage: "deploy temporary account response incomplete" }
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
return {
|
|
1124
|
+
account: {
|
|
1125
|
+
id: accountId,
|
|
1126
|
+
name: accountName,
|
|
1127
|
+
apiToken,
|
|
1128
|
+
expiresAt: accountExpiresAt
|
|
1129
|
+
},
|
|
1130
|
+
claim: {
|
|
1131
|
+
url: claimUrl,
|
|
1132
|
+
expiresAt: claimExpiresAt
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
__name(createTemporaryPreviewAccount, "createTemporaryPreviewAccount");
|
|
1137
|
+
async function getOrCreateTemporaryPreviewAccount(options) {
|
|
1138
|
+
const cachedPreviewAccount = getCachedTemporaryPreviewAccount(
|
|
1139
|
+
options.storage
|
|
1140
|
+
);
|
|
1141
|
+
if (cachedPreviewAccount) {
|
|
1142
|
+
return { account: cachedPreviewAccount, cached: true };
|
|
1143
|
+
}
|
|
1144
|
+
const termsAccepted = await options.prompt(
|
|
1145
|
+
TEMPORARY_TERMS_PROMPT,
|
|
1146
|
+
TEMPORARY_TERMS_NOTICE
|
|
1147
|
+
);
|
|
1148
|
+
if (!termsAccepted) {
|
|
1149
|
+
throw new UserError(TEMPORARY_TERMS_ERROR, {
|
|
1150
|
+
telemetryMessage: "user temporary terms not accepted"
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
const temporaryPreviewAccount = await createTemporaryPreviewAccount(
|
|
1154
|
+
options.logger
|
|
1155
|
+
);
|
|
1156
|
+
options.storage.write(temporaryPreviewAccount);
|
|
1157
|
+
return { account: temporaryPreviewAccount, cached: false };
|
|
1158
|
+
}
|
|
1159
|
+
__name(getOrCreateTemporaryPreviewAccount, "getOrCreateTemporaryPreviewAccount");
|
|
972
1160
|
|
|
973
1161
|
// src/flow.ts
|
|
974
1162
|
function createOAuthFlow(ctx) {
|
|
@@ -980,6 +1168,8 @@ function createOAuthFlow(ctx) {
|
|
|
980
1168
|
const storage = ctx.storage;
|
|
981
1169
|
const getClientId = /* @__PURE__ */ __name(() => typeof ctx.clientId === "function" ? ctx.clientId() : ctx.clientId, "getClientId");
|
|
982
1170
|
const consent = ctx.consent;
|
|
1171
|
+
let temporaryAllowed = false;
|
|
1172
|
+
let activeTemporaryAccount;
|
|
983
1173
|
const redirectUrl = new URL(ctx.redirectUri);
|
|
984
1174
|
const defaultCallbackHost = redirectUrl.hostname;
|
|
985
1175
|
const defaultCallbackPort = Number(redirectUrl.port);
|
|
@@ -1028,6 +1218,7 @@ function createOAuthFlow(ctx) {
|
|
|
1028
1218
|
scopes: oauth.scopes
|
|
1029
1219
|
});
|
|
1030
1220
|
ctx.logger.log(`Successfully logged in.`);
|
|
1221
|
+
clearTemporaryAccount();
|
|
1031
1222
|
ctx.purgeOnLoginOrLogout?.();
|
|
1032
1223
|
return true;
|
|
1033
1224
|
}
|
|
@@ -1113,6 +1304,7 @@ function createOAuthFlow(ctx) {
|
|
|
1113
1304
|
}
|
|
1114
1305
|
__name(loginOrRefreshIfRequired, "loginOrRefreshIfRequired");
|
|
1115
1306
|
async function logout() {
|
|
1307
|
+
const clearedTemporary = clearTemporaryAccount();
|
|
1116
1308
|
if (ctx.hasEnvCredentials()) {
|
|
1117
1309
|
ctx.logger.log(
|
|
1118
1310
|
"You are logged in with an API Token. Unset the CLOUDFLARE_API_TOKEN in the environment to log out."
|
|
@@ -1124,7 +1316,9 @@ function createOAuthFlow(ctx) {
|
|
|
1124
1316
|
storage
|
|
1125
1317
|
}).refreshToken;
|
|
1126
1318
|
if (!storedRefreshToken) {
|
|
1127
|
-
ctx.logger.log(
|
|
1319
|
+
ctx.logger.log(
|
|
1320
|
+
clearedTemporary ? "Cleared temporary preview account." : "Not logged in, exiting..."
|
|
1321
|
+
);
|
|
1128
1322
|
return;
|
|
1129
1323
|
}
|
|
1130
1324
|
const body = `client_id=${encodeURIComponent(getClientId())}&token_type_hint=refresh_token&token=${encodeURIComponent(storedRefreshToken.value || "")}`;
|
|
@@ -1157,15 +1351,74 @@ function createOAuthFlow(ctx) {
|
|
|
1157
1351
|
return stored.accessToken?.value;
|
|
1158
1352
|
}
|
|
1159
1353
|
__name(getOAuthTokenFromLocalState, "getOAuthTokenFromLocalState");
|
|
1354
|
+
function getAPITokenInternal() {
|
|
1355
|
+
if (activeTemporaryAccount) {
|
|
1356
|
+
return { apiToken: activeTemporaryAccount.account.apiToken };
|
|
1357
|
+
}
|
|
1358
|
+
return getAPIToken({
|
|
1359
|
+
storage,
|
|
1360
|
+
warningLogger: ctx.logger,
|
|
1361
|
+
allowGlobalAuthKey: ctx.allowGlobalAuthKey
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
__name(getAPITokenInternal, "getAPITokenInternal");
|
|
1365
|
+
function requireApiTokenInternal() {
|
|
1366
|
+
if (activeTemporaryAccount) {
|
|
1367
|
+
return { apiToken: activeTemporaryAccount.account.apiToken };
|
|
1368
|
+
}
|
|
1369
|
+
return requireApiToken({
|
|
1370
|
+
storage,
|
|
1371
|
+
warningLogger: ctx.logger,
|
|
1372
|
+
allowGlobalAuthKey: ctx.allowGlobalAuthKey
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
__name(requireApiTokenInternal, "requireApiTokenInternal");
|
|
1376
|
+
function setTemporaryAllowed(allowed) {
|
|
1377
|
+
temporaryAllowed = allowed && ctx.temporary !== void 0;
|
|
1378
|
+
activeTemporaryAccount = void 0;
|
|
1379
|
+
}
|
|
1380
|
+
__name(setTemporaryAllowed, "setTemporaryAllowed");
|
|
1381
|
+
function isTemporaryAllowed() {
|
|
1382
|
+
return temporaryAllowed;
|
|
1383
|
+
}
|
|
1384
|
+
__name(isTemporaryAllowed, "isTemporaryAllowed");
|
|
1385
|
+
function getActiveTemporaryAccount() {
|
|
1386
|
+
return activeTemporaryAccount;
|
|
1387
|
+
}
|
|
1388
|
+
__name(getActiveTemporaryAccount, "getActiveTemporaryAccount");
|
|
1389
|
+
async function activateTemporaryAccount() {
|
|
1390
|
+
if (!ctx.temporary) {
|
|
1391
|
+
throw new UserError(
|
|
1392
|
+
"Temporary preview accounts are not supported by this CLI.",
|
|
1393
|
+
{ telemetryMessage: "user temporary account unsupported" }
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
const result = await getOrCreateTemporaryPreviewAccount({
|
|
1397
|
+
...ctx.temporary,
|
|
1398
|
+
logger: ctx.logger
|
|
1399
|
+
});
|
|
1400
|
+
activeTemporaryAccount = result.account;
|
|
1401
|
+
return result;
|
|
1402
|
+
}
|
|
1403
|
+
__name(activateTemporaryAccount, "activateTemporaryAccount");
|
|
1404
|
+
function clearTemporaryAccount() {
|
|
1405
|
+
activeTemporaryAccount = void 0;
|
|
1406
|
+
return ctx.temporary?.storage.clear() ?? false;
|
|
1407
|
+
}
|
|
1408
|
+
__name(clearTemporaryAccount, "clearTemporaryAccount");
|
|
1160
1409
|
return {
|
|
1161
1410
|
login,
|
|
1162
1411
|
logout,
|
|
1163
1412
|
loginOrRefreshIfRequired,
|
|
1164
1413
|
getOAuthTokenFromLocalState,
|
|
1165
|
-
|
|
1166
|
-
|
|
1414
|
+
getAPIToken: getAPITokenInternal,
|
|
1415
|
+
requireApiToken: requireApiTokenInternal,
|
|
1416
|
+
setTemporaryAllowed,
|
|
1417
|
+
isTemporaryAllowed,
|
|
1418
|
+
getActiveTemporaryAccount,
|
|
1419
|
+
activateTemporaryAccount
|
|
1167
1420
|
};
|
|
1168
1421
|
}
|
|
1169
1422
|
__name(createOAuthFlow, "createOAuthFlow");
|
|
1170
1423
|
|
|
1171
|
-
export {
|
|
1424
|
+
export { PKCE_CHARSET, TEMPORARY_TERMS_NOTICE, TEMPORARY_TERMS_PROMPT, clearAccessCaches, createOAuthFlow, domainUsesAccess, generateAuthUrl, generateRandomState, getAccessHeaders, getAuthFromEnv, getAuthUrlFromEnv, getCloudflareAPITokenFromEnv, getCloudflareGlobalAuthEmailFromEnv, getCloudflareGlobalAuthKeyFromEnv, readStoredAuthState };
|
package/dist/metafile-esm.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/state.ts":{"bytes":3882,"imports":[{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/credentials.ts":{"bytes":4510,"imports":[{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"
|
|
1
|
+
{"inputs":{"src/state.ts":{"bytes":3882,"imports":[{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/credentials.ts":{"bytes":4510,"imports":[{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"src/state.ts","kind":"import-statement","original":"./state"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/env-vars.ts":{"bytes":3473,"imports":[{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/access.ts":{"bytes":7367,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"src/env-vars.ts","kind":"import-statement","original":"./env-vars"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"../../node_modules/.pnpm/ts-dedent@2.2.0/node_modules/ts-dedent/esm/index.js":{"bytes":1634,"imports":[{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/errors.ts":{"bytes":6757,"imports":[{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/pkce.ts":{"bytes":2624,"imports":[{"path":"node:crypto","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/token-exchange.ts":{"bytes":11753,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"src/access.ts","kind":"import-statement","original":"./access"},{"path":"src/env-vars.ts","kind":"import-statement","original":"./env-vars"},{"path":"src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"src/pkce.ts","kind":"import-statement","original":"./pkce"},{"path":"src/state.ts","kind":"import-statement","original":"./state"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/callback-server.ts":{"bytes":10234,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"src/token-exchange.ts","kind":"import-statement","original":"./token-exchange"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/generate-auth-url.ts":{"bytes":978,"imports":[{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/generate-random-state.ts":{"bytes":599,"imports":[{"path":"node:crypto","kind":"import-statement","external":true},{"path":"src/pkce.ts","kind":"import-statement","original":"./pkce"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/pow.ts":{"bytes":1766,"imports":[{"path":"node:crypto","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/temporary.ts":{"bytes":8099,"imports":[{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"src/pow.ts","kind":"import-statement","original":"./pow"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/flow.ts":{"bytes":16319,"imports":[{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"../../node_modules/.pnpm/ts-dedent@2.2.0/node_modules/ts-dedent/esm/index.js","kind":"import-statement","original":"ts-dedent"},{"path":"undici","kind":"import-statement","external":true},{"path":"src/callback-server.ts","kind":"import-statement","original":"./callback-server"},{"path":"src/credentials.ts","kind":"import-statement","original":"./credentials"},{"path":"src/env-vars.ts","kind":"import-statement","original":"./env-vars"},{"path":"src/generate-auth-url.ts","kind":"import-statement","original":"./generate-auth-url"},{"path":"src/generate-random-state.ts","kind":"import-statement","original":"./generate-random-state"},{"path":"src/state.ts","kind":"import-statement","original":"./state"},{"path":"src/temporary.ts","kind":"import-statement","original":"./temporary"},{"path":"src/token-exchange.ts","kind":"import-statement","original":"./token-exchange"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":1282,"imports":[{"path":"src/credentials.ts","kind":"import-statement","original":"./credentials"},{"path":"src/access.ts","kind":"import-statement","original":"./access"},{"path":"src/env-vars.ts","kind":"import-statement","original":"./env-vars"},{"path":"src/flow.ts","kind":"import-statement","original":"./flow"},{"path":"src/generate-auth-url.ts","kind":"import-statement","original":"./generate-auth-url"},{"path":"src/generate-random-state.ts","kind":"import-statement","original":"./generate-random-state"},{"path":"src/temporary.ts","kind":"import-statement","original":"./temporary"},{"path":"src/pkce.ts","kind":"import-statement","original":"./pkce"},{"path":"src/state.ts","kind":"import-statement","original":"./state"}],"format":"esm"},"src/test-helpers/msw-handlers/access.ts":{"bytes":744,"imports":[{"path":"msw","kind":"import-statement","external":true}],"format":"esm"},"src/test-helpers/msw-handlers/oauth.ts":{"bytes":760,"imports":[{"path":"msw","kind":"import-statement","external":true}],"format":"esm"},"src/test-helpers/index.ts":{"bytes":123,"imports":[{"path":"src/test-helpers/msw-handlers/access.ts","kind":"import-statement","original":"./msw-handlers/access"},{"path":"src/test-helpers/msw-handlers/oauth.ts","kind":"import-statement","original":"./msw-handlers/oauth"}],"format":"esm"}},"outputs":{"dist/index.mjs":{"imports":[{"path":"dist/chunk-O6YSETKJ.mjs","kind":"import-statement"},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"node:child_process","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:http","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"node:assert","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"node:crypto","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"node:crypto","kind":"import-statement","external":true},{"path":"@cloudflare/workers-utils","kind":"import-statement","external":true},{"path":"undici","kind":"import-statement","external":true},{"path":"node:crypto","kind":"import-statement","external":true}],"exports":["PKCE_CHARSET","TEMPORARY_TERMS_NOTICE","TEMPORARY_TERMS_PROMPT","clearAccessCaches","createOAuthFlow","domainUsesAccess","generateAuthUrl","generateRandomState","getAccessHeaders","getAuthFromEnv","getAuthUrlFromEnv","getCloudflareAPITokenFromEnv","getCloudflareGlobalAuthEmailFromEnv","getCloudflareGlobalAuthKeyFromEnv","readStoredAuthState"],"entryPoint":"src/index.ts","inputs":{"src/credentials.ts":{"bytesInOutput":1810},"src/state.ts":{"bytesInOutput":1316},"src/index.ts":{"bytesInOutput":0},"src/access.ts":{"bytesInOutput":4517},"src/env-vars.ts":{"bytesInOutput":1415},"src/flow.ts":{"bytesInOutput":8660},"../../node_modules/.pnpm/ts-dedent@2.2.0/node_modules/ts-dedent/esm/index.js":{"bytesInOutput":1494},"src/callback-server.ts":{"bytesInOutput":6776},"src/errors.ts":{"bytesInOutput":6069},"src/token-exchange.ts":{"bytesInOutput":7156},"src/pkce.ts":{"bytesInOutput":1203},"src/generate-auth-url.ts":{"bytesInOutput":467},"src/generate-random-state.ts":{"bytesInOutput":328},"src/temporary.ts":{"bytesInOutput":6747},"src/pow.ts":{"bytesInOutput":899}},"bytes":49784},"dist/test-helpers/index.mjs":{"imports":[{"path":"dist/chunk-O6YSETKJ.mjs","kind":"import-statement"},{"path":"msw","kind":"import-statement","external":true},{"path":"msw","kind":"import-statement","external":true}],"exports":["mswAccessHandlers","mswSuccessOauthHandlers"],"entryPoint":"src/test-helpers/index.ts","inputs":{"src/test-helpers/msw-handlers/access.ts":{"bytesInOutput":756},"src/test-helpers/index.ts":{"bytesInOutput":0},"src/test-helpers/msw-handlers/oauth.ts":{"bytesInOutput":877}},"bytes":1811},"dist/chunk-O6YSETKJ.mjs":{"imports":[],"exports":["__name"],"inputs":{},"bytes":151}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudflare/workers-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Internal OAuth 2.0 + PKCE flow for Cloudflare CLIs. Not intended for external use — APIs may change without notice.",
|
|
5
5
|
"homepage": "https://github.com/cloudflare/workers-sdk/tree/main/packages/workers-auth#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"undici": "7.24.8",
|
|
32
|
-
"@cloudflare/workers-utils": "0.23.
|
|
32
|
+
"@cloudflare/workers-utils": "0.23.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "22.15.17",
|