@cloudflare/workers-oauth-provider 0.10.2 → 0.10.4
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 +2 -0
- package/dist/oauth-provider.d.ts +14 -0
- package/dist/oauth-provider.js +11 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -248,6 +248,8 @@ A typical flow has three steps:
|
|
|
248
248
|
|
|
249
249
|
`completeAuthorization()` stores a new grant and, by default, revokes existing grants for the same user and client after the new grant is safely stored. Set `revokeExistingGrants: false` only when the application intentionally allows concurrent grants for the same user and client.
|
|
250
250
|
|
|
251
|
+
For Client ID Metadata Document clients, whose client_id is the metadata URL shared by every installation, default revocation is additionally scoped to grants created from the same redirect URI, so one installation's re-authorization does not revoke another's. Grants created before the redirect URI was recorded are never auto-revoked by CIMD clients.
|
|
252
|
+
|
|
251
253
|
For users with many grants, `revokeExistingGrantsBatchSize` controls the KV page size used during that scan. It defaults to `50` and is capped at KV's maximum page size of `1000`.
|
|
252
254
|
|
|
253
255
|
### Authorization response issuer
|
package/dist/oauth-provider.d.ts
CHANGED
|
@@ -1103,6 +1103,13 @@ interface Grant {
|
|
|
1103
1103
|
* Indicates the protected resource(s) for which access is requested
|
|
1104
1104
|
*/
|
|
1105
1105
|
resource?: string | string[];
|
|
1106
|
+
/**
|
|
1107
|
+
* The exact redirect URI used in the authorization request that created this grant
|
|
1108
|
+
* Recorded so that default grant revocation can be scoped to a single installation
|
|
1109
|
+
* of a CIMD client (whose client_id is shared across all installations). Absent on
|
|
1110
|
+
* grants created before this field was introduced.
|
|
1111
|
+
*/
|
|
1112
|
+
redirectUri?: string;
|
|
1106
1113
|
}
|
|
1107
1114
|
/**
|
|
1108
1115
|
* OAuth 2.0 Token Response
|
|
@@ -1314,6 +1321,13 @@ interface GrantSummary {
|
|
|
1314
1321
|
* Unix timestamp when the grant expires (if TTL is configured)
|
|
1315
1322
|
*/
|
|
1316
1323
|
expiresAt?: number;
|
|
1324
|
+
/**
|
|
1325
|
+
* The exact redirect URI used in the authorization request that created this grant
|
|
1326
|
+
* Recorded so that default grant revocation can be scoped to a single installation
|
|
1327
|
+
* of a CIMD client (whose client_id is shared across all installations). Absent on
|
|
1328
|
+
* grants created before this field was introduced.
|
|
1329
|
+
*/
|
|
1330
|
+
redirectUri?: string;
|
|
1317
1331
|
}
|
|
1318
1332
|
/**
|
|
1319
1333
|
* OAuth 2.0 Provider implementation for Cloudflare Workers
|
package/dist/oauth-provider.js
CHANGED
|
@@ -581,6 +581,8 @@ const EMA_DEFAULT_MAX_ASSERTION_LIFETIME_SECONDS = 300;
|
|
|
581
581
|
* values to amplify load on the IdP's JWKS endpoint.
|
|
582
582
|
*/
|
|
583
583
|
const EMA_JWKS_FORCE_REFRESH_COOLDOWN_SECONDS = 30;
|
|
584
|
+
/** Floor for the `jti` replay marker's KV TTL; KV rejects a sub-60s expiration. */
|
|
585
|
+
const EMA_JTI_MIN_TTL_SECONDS = 60;
|
|
584
586
|
/** Default JWT signing algorithm assumed for a trusted issuer. */
|
|
585
587
|
const EMA_DEFAULT_JWT_ALGORITHM = "RS256";
|
|
586
588
|
/** JWT signing algorithms supported by the built-in WebCrypto verifier. */
|
|
@@ -698,7 +700,7 @@ const EMA_JTI_KV_PREFIX = "enterprise-jti:";
|
|
|
698
700
|
/** Create the default KV-backed JTI store. KV TTL handles cleanup. */
|
|
699
701
|
function createKvJtiStore() {
|
|
700
702
|
return { async markUsed({ issuer, jti, exp, now, env }) {
|
|
701
|
-
const ttl = Math.max(
|
|
703
|
+
const ttl = Math.max(EMA_JTI_MIN_TTL_SECONDS, exp - now);
|
|
702
704
|
const key = `${EMA_JTI_KV_PREFIX}${await sha256Hex(`${issuer}\n${jti}`)}`;
|
|
703
705
|
if (await env.OAUTH_KV.get(key)) return err({
|
|
704
706
|
reason: "replayed",
|
|
@@ -3572,6 +3574,7 @@ var OAuthHelpersImpl = class {
|
|
|
3572
3574
|
validateAuthorizationPkce(this.provider.serverCapabilities, options.request, clientInfo);
|
|
3573
3575
|
let grantsToRevoke = [];
|
|
3574
3576
|
if (options.revokeExistingGrants !== false) {
|
|
3577
|
+
const isCimdClient = this.provider.isClientMetadataUrl(clientId);
|
|
3575
3578
|
const batchSize = getRevokeExistingGrantsBatchSize(options.revokeExistingGrantsBatchSize);
|
|
3576
3579
|
let cursor;
|
|
3577
3580
|
do {
|
|
@@ -3579,7 +3582,7 @@ var OAuthHelpersImpl = class {
|
|
|
3579
3582
|
cursor,
|
|
3580
3583
|
limit: batchSize
|
|
3581
3584
|
});
|
|
3582
|
-
for (const grant of page.items) if (grant.clientId === clientId) grantsToRevoke.push(grant.id);
|
|
3585
|
+
for (const grant of page.items) if (grant.clientId === clientId && (!isCimdClient || grant.redirectUri === options.request.redirectUri)) grantsToRevoke.push(grant.id);
|
|
3583
3586
|
cursor = page.cursor;
|
|
3584
3587
|
} while (cursor);
|
|
3585
3588
|
}
|
|
@@ -3603,7 +3606,8 @@ var OAuthHelpersImpl = class {
|
|
|
3603
3606
|
metadata: options.metadata,
|
|
3604
3607
|
encryptedProps: encryptedData,
|
|
3605
3608
|
createdAt: now,
|
|
3606
|
-
resource: effectiveResource
|
|
3609
|
+
resource: effectiveResource,
|
|
3610
|
+
redirectUri: options.request.redirectUri
|
|
3607
3611
|
};
|
|
3608
3612
|
const grantKey = `grant:${options.userId}:${grantId}`;
|
|
3609
3613
|
await this.env.OAUTH_KV.put(grantKey, JSON.stringify(grant));
|
|
@@ -3653,7 +3657,8 @@ var OAuthHelpersImpl = class {
|
|
|
3653
3657
|
authCodeWrappedKey,
|
|
3654
3658
|
codeChallenge: options.request.codeChallenge,
|
|
3655
3659
|
codeChallengeMethod: options.request.codeChallengeMethod,
|
|
3656
|
-
resource: effectiveResource
|
|
3660
|
+
resource: effectiveResource,
|
|
3661
|
+
redirectUri: options.request.redirectUri
|
|
3657
3662
|
};
|
|
3658
3663
|
const grantKey = `grant:${options.userId}:${grantId}`;
|
|
3659
3664
|
await this.env.OAUTH_KV.put(grantKey, JSON.stringify(grant), { expirationTtl: 600 });
|
|
@@ -3810,7 +3815,8 @@ var OAuthHelpersImpl = class {
|
|
|
3810
3815
|
scope: grantData.scope,
|
|
3811
3816
|
metadata: grantData.metadata,
|
|
3812
3817
|
createdAt: grantData.createdAt,
|
|
3813
|
-
expiresAt: grantData.expiresAt
|
|
3818
|
+
expiresAt: grantData.expiresAt,
|
|
3819
|
+
redirectUri: grantData.redirectUri
|
|
3814
3820
|
};
|
|
3815
3821
|
grantSummaries.push(summary);
|
|
3816
3822
|
}
|