@atproto/oauth-provider 0.1.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/.postcssrc.yml +3 -0
- package/CHANGELOG.md +19 -0
- package/LICENSE.txt +7 -0
- package/dist/access-token/access-token-type.d.ts +6 -0
- package/dist/access-token/access-token-type.d.ts.map +1 -0
- package/dist/access-token/access-token-type.js +10 -0
- package/dist/access-token/access-token-type.js.map +1 -0
- package/dist/account/account-manager.d.ts +14 -0
- package/dist/account/account-manager.d.ts.map +1 -0
- package/dist/account/account-manager.js +39 -0
- package/dist/account/account-manager.js.map +1 -0
- package/dist/account/account-store.d.ts +39 -0
- package/dist/account/account-store.d.ts.map +1 -0
- package/dist/account/account-store.js +19 -0
- package/dist/account/account-store.js.map +1 -0
- package/dist/account/account.d.ts +8 -0
- package/dist/account/account.d.ts.map +1 -0
- package/dist/account/account.js +3 -0
- package/dist/account/account.js.map +1 -0
- package/dist/assets/app/bundle-manifest.json +22 -0
- package/dist/assets/app/main.css +3 -0
- package/dist/assets/app/main.js +20 -0
- package/dist/assets/app/main.js.map +1 -0
- package/dist/assets/asset.d.ts +9 -0
- package/dist/assets/asset.d.ts.map +1 -0
- package/dist/assets/asset.js +3 -0
- package/dist/assets/asset.js.map +1 -0
- package/dist/assets/assets-middleware.d.ts +2 -0
- package/dist/assets/assets-middleware.d.ts.map +1 -0
- package/dist/assets/assets-middleware.js +30 -0
- package/dist/assets/assets-middleware.js.map +1 -0
- package/dist/assets/index.d.ts +4 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/assets/index.js +65 -0
- package/dist/assets/index.js.map +1 -0
- package/dist/client/client-auth.d.ts +13 -0
- package/dist/client/client-auth.d.ts.map +1 -0
- package/dist/client/client-auth.js +35 -0
- package/dist/client/client-auth.js.map +1 -0
- package/dist/client/client-data.d.ts +8 -0
- package/dist/client/client-data.d.ts.map +1 -0
- package/dist/client/client-data.js +3 -0
- package/dist/client/client-data.js.map +1 -0
- package/dist/client/client-id.d.ts +4 -0
- package/dist/client/client-id.d.ts.map +1 -0
- package/dist/client/client-id.js +6 -0
- package/dist/client/client-id.js.map +1 -0
- package/dist/client/client-info.d.ts +13 -0
- package/dist/client/client-info.d.ts.map +1 -0
- package/dist/client/client-info.js +3 -0
- package/dist/client/client-info.js.map +1 -0
- package/dist/client/client-manager.d.ts +38 -0
- package/dist/client/client-manager.d.ts.map +1 -0
- package/dist/client/client-manager.js +534 -0
- package/dist/client/client-manager.js.map +1 -0
- package/dist/client/client-store.d.ts +13 -0
- package/dist/client/client-store.d.ts.map +1 -0
- package/dist/client/client-store.js +39 -0
- package/dist/client/client-store.js.map +1 -0
- package/dist/client/client-utils.d.ts +6 -0
- package/dist/client/client-utils.d.ts.map +1 -0
- package/dist/client/client-utils.js +40 -0
- package/dist/client/client-utils.js.map +1 -0
- package/dist/client/client.d.ts +41 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +163 -0
- package/dist/client/client.js.map +1 -0
- package/dist/constants.d.ts +42 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +53 -0
- package/dist/constants.js.map +1 -0
- package/dist/device/device-data.d.ts +20 -0
- package/dist/device/device-data.d.ts.map +1 -0
- package/dist/device/device-data.js +11 -0
- package/dist/device/device-data.js.map +1 -0
- package/dist/device/device-details.d.ts +17 -0
- package/dist/device/device-details.d.ts.map +1 -0
- package/dist/device/device-details.js +34 -0
- package/dist/device/device-details.js.map +1 -0
- package/dist/device/device-id.d.ts +6 -0
- package/dist/device/device-id.d.ts.map +1 -0
- package/dist/device/device-id.js +18 -0
- package/dist/device/device-id.js.map +1 -0
- package/dist/device/device-manager.d.ts +88 -0
- package/dist/device/device-manager.d.ts.map +1 -0
- package/dist/device/device-manager.js +206 -0
- package/dist/device/device-manager.js.map +1 -0
- package/dist/device/device-store.d.ts +15 -0
- package/dist/device/device-store.d.ts.map +1 -0
- package/dist/device/device-store.js +36 -0
- package/dist/device/device-store.js.map +1 -0
- package/dist/device/session-id.d.ts +6 -0
- package/dist/device/session-id.d.ts.map +1 -0
- package/dist/device/session-id.js +18 -0
- package/dist/device/session-id.js.map +1 -0
- package/dist/dpop/dpop-manager.d.ts +33 -0
- package/dist/dpop/dpop-manager.d.ts.map +1 -0
- package/dist/dpop/dpop-manager.js +115 -0
- package/dist/dpop/dpop-manager.js.map +1 -0
- package/dist/dpop/dpop-nonce.d.ts +13 -0
- package/dist/dpop/dpop-nonce.d.ts.map +1 -0
- package/dist/dpop/dpop-nonce.js +94 -0
- package/dist/dpop/dpop-nonce.js.map +1 -0
- package/dist/errors/access-denied-error.d.ts +8 -0
- package/dist/errors/access-denied-error.d.ts.map +1 -0
- package/dist/errors/access-denied-error.js +21 -0
- package/dist/errors/access-denied-error.js.map +1 -0
- package/dist/errors/account-selection-required-error.d.ts +6 -0
- package/dist/errors/account-selection-required-error.d.ts.map +1 -0
- package/dist/errors/account-selection-required-error.js +11 -0
- package/dist/errors/account-selection-required-error.js.map +1 -0
- package/dist/errors/consent-required-error.d.ts +6 -0
- package/dist/errors/consent-required-error.d.ts.map +1 -0
- package/dist/errors/consent-required-error.js +11 -0
- package/dist/errors/consent-required-error.js.map +1 -0
- package/dist/errors/invalid-authorization-details-error.d.ts +20 -0
- package/dist/errors/invalid-authorization-details-error.d.ts.map +1 -0
- package/dist/errors/invalid-authorization-details-error.js +26 -0
- package/dist/errors/invalid-authorization-details-error.js.map +1 -0
- package/dist/errors/invalid-client-error.d.ts +18 -0
- package/dist/errors/invalid-client-error.d.ts.map +1 -0
- package/dist/errors/invalid-client-error.js +24 -0
- package/dist/errors/invalid-client-error.js.map +1 -0
- package/dist/errors/invalid-client-id-error.d.ts +13 -0
- package/dist/errors/invalid-client-id-error.d.ts.map +1 -0
- package/dist/errors/invalid-client-id-error.js +25 -0
- package/dist/errors/invalid-client-id-error.js.map +1 -0
- package/dist/errors/invalid-client-metadata-error.d.ts +13 -0
- package/dist/errors/invalid-client-metadata-error.d.ts.map +1 -0
- package/dist/errors/invalid-client-metadata-error.js +23 -0
- package/dist/errors/invalid-client-metadata-error.js.map +1 -0
- package/dist/errors/invalid-dpop-key-binding-error.d.ts +12 -0
- package/dist/errors/invalid-dpop-key-binding-error.d.ts.map +1 -0
- package/dist/errors/invalid-dpop-key-binding-error.js +20 -0
- package/dist/errors/invalid-dpop-key-binding-error.js.map +1 -0
- package/dist/errors/invalid-dpop-proof-error.d.ts +5 -0
- package/dist/errors/invalid-dpop-proof-error.d.ts.map +1 -0
- package/dist/errors/invalid-dpop-proof-error.js +12 -0
- package/dist/errors/invalid-dpop-proof-error.js.map +1 -0
- package/dist/errors/invalid-grant-error.d.ts +14 -0
- package/dist/errors/invalid-grant-error.d.ts.map +1 -0
- package/dist/errors/invalid-grant-error.js +20 -0
- package/dist/errors/invalid-grant-error.js.map +1 -0
- package/dist/errors/invalid-parameters-error.d.ts +6 -0
- package/dist/errors/invalid-parameters-error.d.ts.map +1 -0
- package/dist/errors/invalid-parameters-error.js +11 -0
- package/dist/errors/invalid-parameters-error.js.map +1 -0
- package/dist/errors/invalid-redirect-uri-error.d.ts +11 -0
- package/dist/errors/invalid-redirect-uri-error.d.ts.map +1 -0
- package/dist/errors/invalid-redirect-uri-error.js +21 -0
- package/dist/errors/invalid-redirect-uri-error.js.map +1 -0
- package/dist/errors/invalid-request-error.d.ts +28 -0
- package/dist/errors/invalid-request-error.d.ts.map +1 -0
- package/dist/errors/invalid-request-error.js +34 -0
- package/dist/errors/invalid-request-error.js.map +1 -0
- package/dist/errors/invalid-token-error.d.ts +16 -0
- package/dist/errors/invalid-token-error.d.ts.map +1 -0
- package/dist/errors/invalid-token-error.js +45 -0
- package/dist/errors/invalid-token-error.js.map +1 -0
- package/dist/errors/login-required-error.d.ts +6 -0
- package/dist/errors/login-required-error.d.ts.map +1 -0
- package/dist/errors/login-required-error.js +11 -0
- package/dist/errors/login-required-error.js.map +1 -0
- package/dist/errors/oauth-error.d.ts +13 -0
- package/dist/errors/oauth-error.d.ts.map +1 -0
- package/dist/errors/oauth-error.js +29 -0
- package/dist/errors/oauth-error.js.map +1 -0
- package/dist/errors/unauthorized-client-error.d.ts +18 -0
- package/dist/errors/unauthorized-client-error.d.ts.map +1 -0
- package/dist/errors/unauthorized-client-error.js +24 -0
- package/dist/errors/unauthorized-client-error.js.map +1 -0
- package/dist/errors/use-dpop-nonce-error.d.ts +18 -0
- package/dist/errors/use-dpop-nonce-error.d.ts.map +1 -0
- package/dist/errors/use-dpop-nonce-error.js +27 -0
- package/dist/errors/use-dpop-nonce-error.js.map +1 -0
- package/dist/errors/www-authenticate-error.d.ts +9 -0
- package/dist/errors/www-authenticate-error.d.ts.map +1 -0
- package/dist/errors/www-authenticate-error.js +46 -0
- package/dist/errors/www-authenticate-error.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/html/build-document.d.ts +32 -0
- package/dist/lib/html/build-document.d.ts.map +1 -0
- package/dist/lib/html/build-document.js +61 -0
- package/dist/lib/html/build-document.js.map +1 -0
- package/dist/lib/html/escapers.d.ts +9 -0
- package/dist/lib/html/escapers.d.ts.map +1 -0
- package/dist/lib/html/escapers.js +66 -0
- package/dist/lib/html/escapers.js.map +1 -0
- package/dist/lib/html/html.d.ts +13 -0
- package/dist/lib/html/html.d.ts.map +1 -0
- package/dist/lib/html/html.js +53 -0
- package/dist/lib/html/html.js.map +1 -0
- package/dist/lib/html/index.d.ts +4 -0
- package/dist/lib/html/index.d.ts.map +1 -0
- package/dist/lib/html/index.js +21 -0
- package/dist/lib/html/index.js.map +1 -0
- package/dist/lib/html/tags.d.ts +34 -0
- package/dist/lib/html/tags.d.ts.map +1 -0
- package/dist/lib/html/tags.js +47 -0
- package/dist/lib/html/tags.js.map +1 -0
- package/dist/lib/html/util.d.ts +4 -0
- package/dist/lib/html/util.d.ts.map +1 -0
- package/dist/lib/html/util.js +20 -0
- package/dist/lib/html/util.js.map +1 -0
- package/dist/lib/http/accept.d.ts +29 -0
- package/dist/lib/http/accept.d.ts.map +1 -0
- package/dist/lib/http/accept.js +67 -0
- package/dist/lib/http/accept.js.map +1 -0
- package/dist/lib/http/context.d.ts +5 -0
- package/dist/lib/http/context.d.ts.map +1 -0
- package/dist/lib/http/context.js +10 -0
- package/dist/lib/http/context.js.map +1 -0
- package/dist/lib/http/index.d.ts +10 -0
- package/dist/lib/http/index.d.ts.map +1 -0
- package/dist/lib/http/index.js +26 -0
- package/dist/lib/http/index.js.map +1 -0
- package/dist/lib/http/method.d.ts +6 -0
- package/dist/lib/http/method.d.ts.map +1 -0
- package/dist/lib/http/method.js +19 -0
- package/dist/lib/http/method.js.map +1 -0
- package/dist/lib/http/middleware.d.ts +18 -0
- package/dist/lib/http/middleware.d.ts.map +1 -0
- package/dist/lib/http/middleware.js +118 -0
- package/dist/lib/http/middleware.js.map +1 -0
- package/dist/lib/http/parser.d.ts +33 -0
- package/dist/lib/http/parser.d.ts.map +1 -0
- package/dist/lib/http/parser.js +48 -0
- package/dist/lib/http/parser.js.map +1 -0
- package/dist/lib/http/path.d.ts +9 -0
- package/dist/lib/http/path.d.ts.map +1 -0
- package/dist/lib/http/path.js +54 -0
- package/dist/lib/http/path.js.map +1 -0
- package/dist/lib/http/request.d.ts +33 -0
- package/dist/lib/http/request.d.ts.map +1 -0
- package/dist/lib/http/request.js +86 -0
- package/dist/lib/http/request.js.map +1 -0
- package/dist/lib/http/response.d.ts +13 -0
- package/dist/lib/http/response.d.ts.map +1 -0
- package/dist/lib/http/response.js +98 -0
- package/dist/lib/http/response.js.map +1 -0
- package/dist/lib/http/route.d.ts +25 -0
- package/dist/lib/http/route.d.ts.map +1 -0
- package/dist/lib/http/route.js +39 -0
- package/dist/lib/http/route.js.map +1 -0
- package/dist/lib/http/router.d.ts +32 -0
- package/dist/lib/http/router.d.ts.map +1 -0
- package/dist/lib/http/router.js +74 -0
- package/dist/lib/http/router.js.map +1 -0
- package/dist/lib/http/stream.d.ts +13 -0
- package/dist/lib/http/stream.d.ts.map +1 -0
- package/dist/lib/http/stream.js +46 -0
- package/dist/lib/http/stream.js.map +1 -0
- package/dist/lib/http/types.d.ts +7 -0
- package/dist/lib/http/types.d.ts.map +1 -0
- package/dist/lib/http/types.js +3 -0
- package/dist/lib/http/types.js.map +1 -0
- package/dist/lib/http/url.d.ts +8 -0
- package/dist/lib/http/url.d.ts.map +1 -0
- package/dist/lib/http/url.js +22 -0
- package/dist/lib/http/url.js.map +1 -0
- package/dist/lib/redis.d.ts +5 -0
- package/dist/lib/redis.d.ts.map +1 -0
- package/dist/lib/redis.js +22 -0
- package/dist/lib/redis.js.map +1 -0
- package/dist/lib/util/authorization-header.d.ts +4 -0
- package/dist/lib/util/authorization-header.d.ts.map +1 -0
- package/dist/lib/util/authorization-header.js +23 -0
- package/dist/lib/util/authorization-header.js.map +1 -0
- package/dist/lib/util/cast.d.ts +2 -0
- package/dist/lib/util/cast.d.ts.map +1 -0
- package/dist/lib/util/cast.js +10 -0
- package/dist/lib/util/cast.js.map +1 -0
- package/dist/lib/util/crypto.d.ts +3 -0
- package/dist/lib/util/crypto.d.ts.map +1 -0
- package/dist/lib/util/crypto.js +29 -0
- package/dist/lib/util/crypto.js.map +1 -0
- package/dist/lib/util/date.d.ts +3 -0
- package/dist/lib/util/date.d.ts.map +1 -0
- package/dist/lib/util/date.js +12 -0
- package/dist/lib/util/date.js.map +1 -0
- package/dist/lib/util/hostname.d.ts +6 -0
- package/dist/lib/util/hostname.d.ts.map +1 -0
- package/dist/lib/util/hostname.js +24 -0
- package/dist/lib/util/hostname.js.map +1 -0
- package/dist/lib/util/redirect-uri.d.ts +7 -0
- package/dist/lib/util/redirect-uri.d.ts.map +1 -0
- package/dist/lib/util/redirect-uri.js +44 -0
- package/dist/lib/util/redirect-uri.js.map +1 -0
- package/dist/lib/util/time.d.ts +6 -0
- package/dist/lib/util/time.d.ts.map +1 -0
- package/dist/lib/util/time.js +28 -0
- package/dist/lib/util/time.js.map +1 -0
- package/dist/lib/util/type.d.ts +6 -0
- package/dist/lib/util/type.d.ts.map +1 -0
- package/dist/lib/util/type.js +3 -0
- package/dist/lib/util/type.js.map +1 -0
- package/dist/lib/util/well-known.d.ts +3 -0
- package/dist/lib/util/well-known.d.ts.map +1 -0
- package/dist/lib/util/well-known.js +11 -0
- package/dist/lib/util/well-known.js.map +1 -0
- package/dist/metadata/build-metadata.d.ts +14 -0
- package/dist/metadata/build-metadata.d.ts.map +1 -0
- package/dist/metadata/build-metadata.js +132 -0
- package/dist/metadata/build-metadata.js.map +1 -0
- package/dist/oauth-client.d.ts +4 -0
- package/dist/oauth-client.d.ts.map +1 -0
- package/dist/oauth-client.js +19 -0
- package/dist/oauth-client.js.map +1 -0
- package/dist/oauth-dpop.d.ts +3 -0
- package/dist/oauth-dpop.d.ts.map +1 -0
- package/dist/oauth-dpop.js +19 -0
- package/dist/oauth-dpop.js.map +1 -0
- package/dist/oauth-errors.d.ts +20 -0
- package/dist/oauth-errors.d.ts.map +1 -0
- package/dist/oauth-errors.js +43 -0
- package/dist/oauth-errors.js.map +1 -0
- package/dist/oauth-hooks.d.ts +42 -0
- package/dist/oauth-hooks.d.ts.map +1 -0
- package/dist/oauth-hooks.js +3 -0
- package/dist/oauth-hooks.js.map +1 -0
- package/dist/oauth-provider.d.ts +179 -0
- package/dist/oauth-provider.d.ts.map +1 -0
- package/dist/oauth-provider.js +748 -0
- package/dist/oauth-provider.js.map +1 -0
- package/dist/oauth-store.d.ts +11 -0
- package/dist/oauth-store.d.ts.map +1 -0
- package/dist/oauth-store.js +27 -0
- package/dist/oauth-store.js.map +1 -0
- package/dist/oauth-verifier.d.ts +66 -0
- package/dist/oauth-verifier.d.ts.map +1 -0
- package/dist/oauth-verifier.js +94 -0
- package/dist/oauth-verifier.js.map +1 -0
- package/dist/oidc/claims.d.ts +16 -0
- package/dist/oidc/claims.d.ts.map +1 -0
- package/dist/oidc/claims.js +29 -0
- package/dist/oidc/claims.js.map +1 -0
- package/dist/oidc/sub.d.ts +4 -0
- package/dist/oidc/sub.d.ts.map +1 -0
- package/dist/oidc/sub.js +6 -0
- package/dist/oidc/sub.js.map +1 -0
- package/dist/oidc/userinfo.d.ts +7 -0
- package/dist/oidc/userinfo.d.ts.map +1 -0
- package/dist/oidc/userinfo.js +3 -0
- package/dist/oidc/userinfo.js.map +1 -0
- package/dist/output/build-error-payload.d.ts +6 -0
- package/dist/output/build-error-payload.d.ts.map +1 -0
- package/dist/output/build-error-payload.js +108 -0
- package/dist/output/build-error-payload.js.map +1 -0
- package/dist/output/customization.d.ts +37 -0
- package/dist/output/customization.d.ts.map +1 -0
- package/dist/output/customization.js +62 -0
- package/dist/output/customization.js.map +1 -0
- package/dist/output/send-authorize-page.d.ts +43 -0
- package/dist/output/send-authorize-page.d.ts.map +1 -0
- package/dist/output/send-authorize-page.js +49 -0
- package/dist/output/send-authorize-page.js.map +1 -0
- package/dist/output/send-authorize-redirect.d.ts +25 -0
- package/dist/output/send-authorize-redirect.d.ts.map +1 -0
- package/dist/output/send-authorize-redirect.js +72 -0
- package/dist/output/send-authorize-redirect.js.map +1 -0
- package/dist/output/send-error-page.d.ts +5 -0
- package/dist/output/send-error-page.d.ts.map +1 -0
- package/dist/output/send-error-page.js +31 -0
- package/dist/output/send-error-page.js.map +1 -0
- package/dist/output/send-web-page.d.ts +8 -0
- package/dist/output/send-web-page.d.ts.map +1 -0
- package/dist/output/send-web-page.js +48 -0
- package/dist/output/send-web-page.js.map +1 -0
- package/dist/parameters/claims-requested.d.ts +3 -0
- package/dist/parameters/claims-requested.d.ts.map +1 -0
- package/dist/parameters/claims-requested.js +77 -0
- package/dist/parameters/claims-requested.js.map +1 -0
- package/dist/parameters/oidc-payload.d.ts +31 -0
- package/dist/parameters/oidc-payload.d.ts.map +1 -0
- package/dist/parameters/oidc-payload.js +25 -0
- package/dist/parameters/oidc-payload.js.map +1 -0
- package/dist/replay/replay-manager.d.ts +10 -0
- package/dist/replay/replay-manager.d.ts.map +1 -0
- package/dist/replay/replay-manager.js +23 -0
- package/dist/replay/replay-manager.js.map +1 -0
- package/dist/replay/replay-store-memory.d.ts +11 -0
- package/dist/replay/replay-store-memory.d.ts.map +1 -0
- package/dist/replay/replay-store-memory.js +30 -0
- package/dist/replay/replay-store-memory.js.map +1 -0
- package/dist/replay/replay-store-redis.d.ts +16 -0
- package/dist/replay/replay-store-redis.d.ts.map +1 -0
- package/dist/replay/replay-store-redis.js +20 -0
- package/dist/replay/replay-store-redis.js.map +1 -0
- package/dist/replay/replay-store.d.ts +16 -0
- package/dist/replay/replay-store.d.ts.map +1 -0
- package/dist/replay/replay-store.js +22 -0
- package/dist/replay/replay-store.js.map +1 -0
- package/dist/request/code.d.ts +7 -0
- package/dist/request/code.d.ts.map +1 -0
- package/dist/request/code.js +20 -0
- package/dist/request/code.js.map +1 -0
- package/dist/request/request-data.d.ts +21 -0
- package/dist/request/request-data.d.ts.map +1 -0
- package/dist/request/request-data.js +6 -0
- package/dist/request/request-data.js.map +1 -0
- package/dist/request/request-id.d.ts +6 -0
- package/dist/request/request-id.d.ts.map +1 -0
- package/dist/request/request-id.js +18 -0
- package/dist/request/request-id.js.map +1 -0
- package/dist/request/request-info.d.ts +12 -0
- package/dist/request/request-info.d.ts.map +1 -0
- package/dist/request/request-info.js +3 -0
- package/dist/request/request-info.js.map +1 -0
- package/dist/request/request-manager.d.ts +40 -0
- package/dist/request/request-manager.d.ts.map +1 -0
- package/dist/request/request-manager.js +310 -0
- package/dist/request/request-manager.js.map +1 -0
- package/dist/request/request-store-memory.d.ts +16 -0
- package/dist/request/request-store-memory.d.ts.map +1 -0
- package/dist/request/request-store-memory.js +31 -0
- package/dist/request/request-store-memory.js.map +1 -0
- package/dist/request/request-store-redis.d.ts +24 -0
- package/dist/request/request-store-redis.d.ts.map +1 -0
- package/dist/request/request-store-redis.js +58 -0
- package/dist/request/request-store-redis.js.map +1 -0
- package/dist/request/request-store.d.ts +27 -0
- package/dist/request/request-store.d.ts.map +1 -0
- package/dist/request/request-store.js +37 -0
- package/dist/request/request-store.js.map +1 -0
- package/dist/request/request-uri.d.ts +8 -0
- package/dist/request/request-uri.d.ts.map +1 -0
- package/dist/request/request-uri.js +24 -0
- package/dist/request/request-uri.js.map +1 -0
- package/dist/request/types.d.ts +328 -0
- package/dist/request/types.d.ts.map +1 -0
- package/dist/request/types.js +27 -0
- package/dist/request/types.js.map +1 -0
- package/dist/signer/signed-token-payload.d.ts +1694 -0
- package/dist/signer/signed-token-payload.d.ts.map +1 -0
- package/dist/signer/signed-token-payload.js +32 -0
- package/dist/signer/signed-token-payload.js.map +1 -0
- package/dist/signer/signer.d.ts +193 -0
- package/dist/signer/signer.d.ts.map +1 -0
- package/dist/signer/signer.js +101 -0
- package/dist/signer/signer.js.map +1 -0
- package/dist/token/refresh-token.d.ts +7 -0
- package/dist/token/refresh-token.d.ts.map +1 -0
- package/dist/token/refresh-token.js +20 -0
- package/dist/token/refresh-token.js.map +1 -0
- package/dist/token/token-claims.d.ts +1687 -0
- package/dist/token/token-claims.d.ts.map +1 -0
- package/dist/token/token-claims.js +30 -0
- package/dist/token/token-claims.js.map +1 -0
- package/dist/token/token-data.d.ts +20 -0
- package/dist/token/token-data.d.ts.map +1 -0
- package/dist/token/token-data.js +3 -0
- package/dist/token/token-data.js.map +1 -0
- package/dist/token/token-id.d.ts +7 -0
- package/dist/token/token-id.d.ts.map +1 -0
- package/dist/token/token-id.js +20 -0
- package/dist/token/token-id.js.map +1 -0
- package/dist/token/token-manager.d.ts +48 -0
- package/dist/token/token-manager.d.ts.map +1 -0
- package/dist/token/token-manager.js +421 -0
- package/dist/token/token-manager.js.map +1 -0
- package/dist/token/token-store.d.ts +35 -0
- package/dist/token/token-store.d.ts.map +1 -0
- package/dist/token/token-store.js +38 -0
- package/dist/token/token-store.js.map +1 -0
- package/dist/token/types.d.ts +250 -0
- package/dist/token/types.d.ts.map +1 -0
- package/dist/token/types.js +36 -0
- package/dist/token/types.js.map +1 -0
- package/dist/token/verify-token-claims.d.ts +17 -0
- package/dist/token/verify-token-claims.d.ts.map +1 -0
- package/dist/token/verify-token-claims.js +39 -0
- package/dist/token/verify-token-claims.js.map +1 -0
- package/package.json +83 -0
- package/rollup.config.js +55 -0
- package/src/access-token/access-token-type.ts +5 -0
- package/src/account/account-manager.ts +55 -0
- package/src/account/account-store.ts +74 -0
- package/src/account/account.ts +10 -0
- package/src/assets/app/app.tsx +28 -0
- package/src/assets/app/backend-data.ts +65 -0
- package/src/assets/app/components/accept-form.tsx +112 -0
- package/src/assets/app/components/account-identifier.tsx +18 -0
- package/src/assets/app/components/account-picker.tsx +108 -0
- package/src/assets/app/components/client-identifier.tsx +32 -0
- package/src/assets/app/components/client-name.tsx +30 -0
- package/src/assets/app/components/error-card.tsx +41 -0
- package/src/assets/app/components/help-card.tsx +42 -0
- package/src/assets/app/components/layout-title-page.tsx +43 -0
- package/src/assets/app/components/layout-welcome.tsx +58 -0
- package/src/assets/app/components/sign-in-form.tsx +290 -0
- package/src/assets/app/components/sign-up-account-form.tsx +210 -0
- package/src/assets/app/components/sign-up-disclaimer.tsx +44 -0
- package/src/assets/app/components/url-viewer.tsx +70 -0
- package/src/assets/app/cookies.ts +11 -0
- package/src/assets/app/hooks/use-api.ts +104 -0
- package/src/assets/app/hooks/use-bound-dispatch.ts +5 -0
- package/src/assets/app/hooks/use-csrf-token.ts +5 -0
- package/src/assets/app/lib/api.ts +64 -0
- package/src/assets/app/lib/clsx.ts +4 -0
- package/src/assets/app/lib/util.ts +10 -0
- package/src/assets/app/main.css +11 -0
- package/src/assets/app/main.tsx +28 -0
- package/src/assets/app/views/accept-view.tsx +51 -0
- package/src/assets/app/views/authorize-view.tsx +101 -0
- package/src/assets/app/views/error-view.tsx +27 -0
- package/src/assets/app/views/sign-in-view.tsx +121 -0
- package/src/assets/app/views/sign-up-view.tsx +93 -0
- package/src/assets/app/views/welcome-view.tsx +61 -0
- package/src/assets/asset.ts +8 -0
- package/src/assets/assets-middleware.ts +32 -0
- package/src/assets/index.ts +74 -0
- package/src/client/client-auth.ts +45 -0
- package/src/client/client-data.ts +9 -0
- package/src/client/client-id.ts +4 -0
- package/src/client/client-info.ts +13 -0
- package/src/client/client-manager.ts +818 -0
- package/src/client/client-store.ts +38 -0
- package/src/client/client-utils.ts +43 -0
- package/src/client/client.ts +231 -0
- package/src/constants.ts +69 -0
- package/src/device/device-data.ts +11 -0
- package/src/device/device-details.ts +43 -0
- package/src/device/device-id.ts +23 -0
- package/src/device/device-manager.ts +287 -0
- package/src/device/device-store.ts +35 -0
- package/src/device/session-id.ts +22 -0
- package/src/dpop/dpop-manager.ts +147 -0
- package/src/dpop/dpop-nonce.ts +104 -0
- package/src/errors/access-denied-error.ts +26 -0
- package/src/errors/account-selection-required-error.ts +12 -0
- package/src/errors/consent-required-error.ts +12 -0
- package/src/errors/invalid-authorization-details-error.ts +22 -0
- package/src/errors/invalid-client-error.ts +20 -0
- package/src/errors/invalid-client-id-error.ts +20 -0
- package/src/errors/invalid-client-metadata-error.ts +19 -0
- package/src/errors/invalid-dpop-key-binding-error.ts +21 -0
- package/src/errors/invalid-dpop-proof-error.ts +13 -0
- package/src/errors/invalid-grant-error.ts +16 -0
- package/src/errors/invalid-parameters-error.ts +12 -0
- package/src/errors/invalid-redirect-uri-error.ts +17 -0
- package/src/errors/invalid-request-error.ts +30 -0
- package/src/errors/invalid-token-error.ts +59 -0
- package/src/errors/login-required-error.ts +12 -0
- package/src/errors/oauth-error.ts +28 -0
- package/src/errors/unauthorized-client-error.ts +20 -0
- package/src/errors/use-dpop-nonce-error.ts +32 -0
- package/src/errors/www-authenticate-error.ts +65 -0
- package/src/index.ts +15 -0
- package/src/lib/html/README.md +9 -0
- package/src/lib/html/build-document.ts +98 -0
- package/src/lib/html/escapers.ts +66 -0
- package/src/lib/html/html.ts +61 -0
- package/src/lib/html/index.ts +5 -0
- package/src/lib/html/tags.ts +58 -0
- package/src/lib/html/util.ts +21 -0
- package/src/lib/http/README.md +11 -0
- package/src/lib/http/accept.ts +91 -0
- package/src/lib/http/context.ts +11 -0
- package/src/lib/http/index.ts +9 -0
- package/src/lib/http/method.ts +18 -0
- package/src/lib/http/middleware.ts +183 -0
- package/src/lib/http/parser.ts +64 -0
- package/src/lib/http/path.ts +82 -0
- package/src/lib/http/request.ts +141 -0
- package/src/lib/http/response.ts +133 -0
- package/src/lib/http/route.ts +56 -0
- package/src/lib/http/router.ts +118 -0
- package/src/lib/http/stream.ts +78 -0
- package/src/lib/http/types.ts +22 -0
- package/src/lib/http/url.ts +23 -0
- package/src/lib/redis.ts +23 -0
- package/src/lib/util/authorization-header.ts +26 -0
- package/src/lib/util/cast.ts +4 -0
- package/src/lib/util/crypto.ts +27 -0
- package/src/lib/util/date.ts +7 -0
- package/src/lib/util/hostname.ts +19 -0
- package/src/lib/util/redirect-uri.ts +46 -0
- package/src/lib/util/time.ts +33 -0
- package/src/lib/util/type.ts +4 -0
- package/src/lib/util/well-known.ts +8 -0
- package/src/metadata/build-metadata.ts +165 -0
- package/src/oauth-client.ts +3 -0
- package/src/oauth-dpop.ts +2 -0
- package/src/oauth-errors.ts +21 -0
- package/src/oauth-hooks.ts +66 -0
- package/src/oauth-provider.ts +1409 -0
- package/src/oauth-store.ts +11 -0
- package/src/oauth-verifier.ts +219 -0
- package/src/oidc/claims.ts +35 -0
- package/src/oidc/sub.ts +4 -0
- package/src/oidc/userinfo.ts +11 -0
- package/src/output/build-error-payload.ts +143 -0
- package/src/output/customization.ts +96 -0
- package/src/output/send-authorize-page.ts +111 -0
- package/src/output/send-authorize-redirect.ts +130 -0
- package/src/output/send-error-page.ts +41 -0
- package/src/output/send-web-page.ts +66 -0
- package/src/parameters/claims-requested.ts +106 -0
- package/src/parameters/oidc-payload.ts +28 -0
- package/src/replay/replay-manager.ts +38 -0
- package/src/replay/replay-store-memory.ts +36 -0
- package/src/replay/replay-store-redis.ts +31 -0
- package/src/replay/replay-store.ts +44 -0
- package/src/request/code.ts +24 -0
- package/src/request/request-data.ts +26 -0
- package/src/request/request-id.ts +23 -0
- package/src/request/request-info.ts +12 -0
- package/src/request/request-manager.ts +479 -0
- package/src/request/request-store-memory.ts +39 -0
- package/src/request/request-store-redis.ts +71 -0
- package/src/request/request-store.ts +54 -0
- package/src/request/request-uri.ts +29 -0
- package/src/request/types.ts +48 -0
- package/src/signer/signed-token-payload.ts +35 -0
- package/src/signer/signer.ts +165 -0
- package/src/token/refresh-token.ts +31 -0
- package/src/token/token-claims.ts +31 -0
- package/src/token/token-data.ts +33 -0
- package/src/token/token-id.ts +26 -0
- package/src/token/token-manager.ts +591 -0
- package/src/token/token-store.ts +78 -0
- package/src/token/types.ts +86 -0
- package/src/token/verify-token-claims.ts +65 -0
- package/tailwind.config.js +13 -0
- package/tsconfig.backend.json +9 -0
- package/tsconfig.frontend.json +11 -0
- package/tsconfig.json +8 -0
- package/tsconfig.tools.json +8 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
import { OAuthClientMetadata } from '@atproto/oauth-types'
|
2
|
+
|
3
|
+
import { Awaitable } from '../lib/util/type.js'
|
4
|
+
import { ClientId } from './client-id.js'
|
5
|
+
|
6
|
+
// Export all types needed to implement the ClientStore interface
|
7
|
+
export * from './client-data.js'
|
8
|
+
export * from './client-id.js'
|
9
|
+
export type { Awaitable }
|
10
|
+
|
11
|
+
export interface ClientStore {
|
12
|
+
findClient(clientId: ClientId): Awaitable<OAuthClientMetadata>
|
13
|
+
}
|
14
|
+
|
15
|
+
export function isClientStore(
|
16
|
+
implementation: Record<string, unknown> & Partial<ClientStore>,
|
17
|
+
): implementation is Record<string, unknown> & ClientStore {
|
18
|
+
return typeof implementation.findClient === 'function'
|
19
|
+
}
|
20
|
+
|
21
|
+
export function ifClientStore(
|
22
|
+
implementation?: Record<string, unknown> & Partial<ClientStore>,
|
23
|
+
): ClientStore | undefined {
|
24
|
+
if (implementation && isClientStore(implementation)) {
|
25
|
+
return implementation
|
26
|
+
}
|
27
|
+
|
28
|
+
return undefined
|
29
|
+
}
|
30
|
+
|
31
|
+
export function asClientStore(
|
32
|
+
implementation?: Record<string, unknown> & Partial<ClientStore>,
|
33
|
+
): ClientStore {
|
34
|
+
const store = ifClientStore(implementation)
|
35
|
+
if (store) return store
|
36
|
+
|
37
|
+
throw new Error('Invalid ClientStore implementation')
|
38
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import {
|
2
|
+
OAuthClientIdDiscoverable,
|
3
|
+
OAuthClientIdLoopback,
|
4
|
+
parseOAuthLoopbackClientId,
|
5
|
+
parseOAuthDiscoverableClientId,
|
6
|
+
} from '@atproto/oauth-types'
|
7
|
+
|
8
|
+
import { InvalidClientIdError } from '../errors/invalid-client-id-error.js'
|
9
|
+
import { InvalidRedirectUriError } from '../errors/invalid-redirect-uri-error.js'
|
10
|
+
import { isInternetHost } from '../lib/util/hostname.js'
|
11
|
+
|
12
|
+
export function parseRedirectUri(redirectUri: string): URL {
|
13
|
+
try {
|
14
|
+
return new URL(redirectUri)
|
15
|
+
} catch (err) {
|
16
|
+
throw InvalidRedirectUriError.from(err)
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
export function parseDiscoverableClientId(
|
21
|
+
clientId: OAuthClientIdDiscoverable,
|
22
|
+
): URL {
|
23
|
+
try {
|
24
|
+
const url = parseOAuthDiscoverableClientId(clientId)
|
25
|
+
|
26
|
+
// Extra validation, prevent usage of invalid internet domain names.
|
27
|
+
if (!isInternetHost(url.hostname)) {
|
28
|
+
throw new InvalidClientIdError('ClientID is not a valid internet address')
|
29
|
+
}
|
30
|
+
|
31
|
+
return url
|
32
|
+
} catch (err) {
|
33
|
+
throw InvalidClientIdError.from(err)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
export function parseLoopbackClientId(clientId: OAuthClientIdLoopback): URL {
|
38
|
+
try {
|
39
|
+
return parseOAuthLoopbackClientId(clientId)
|
40
|
+
} catch (err) {
|
41
|
+
throw InvalidClientIdError.from(err)
|
42
|
+
}
|
43
|
+
}
|
@@ -0,0 +1,231 @@
|
|
1
|
+
import { Jwks } from '@atproto/jwk'
|
2
|
+
import {
|
3
|
+
CLIENT_ASSERTION_TYPE_JWT_BEARER,
|
4
|
+
OAuthClientIdentification,
|
5
|
+
OAuthClientMetadata,
|
6
|
+
OAuthEndpointName,
|
7
|
+
} from '@atproto/oauth-types'
|
8
|
+
import {
|
9
|
+
UnsecuredJWT,
|
10
|
+
createLocalJWKSet,
|
11
|
+
createRemoteJWKSet,
|
12
|
+
jwtVerify,
|
13
|
+
type JWTPayload,
|
14
|
+
type JWTVerifyGetKey,
|
15
|
+
type JWTVerifyOptions,
|
16
|
+
type JWTVerifyResult,
|
17
|
+
type KeyLike,
|
18
|
+
type ResolvedKey,
|
19
|
+
type UnsecuredResult,
|
20
|
+
} from 'jose'
|
21
|
+
import { JOSEError } from 'jose/errors'
|
22
|
+
|
23
|
+
import { CLIENT_ASSERTION_MAX_AGE, JAR_MAX_AGE } from '../constants.js'
|
24
|
+
import { InvalidClientError } from '../errors/invalid-client-error.js'
|
25
|
+
import { InvalidClientMetadataError } from '../errors/invalid-client-metadata-error.js'
|
26
|
+
import { InvalidRequestError } from '../errors/invalid-request-error.js'
|
27
|
+
import { ClientAuth, authJwkThumbprint } from './client-auth.js'
|
28
|
+
import { ClientId } from './client-id.js'
|
29
|
+
import { ClientInfo } from './client-info.js'
|
30
|
+
|
31
|
+
export class Client {
|
32
|
+
/**
|
33
|
+
* @see {@link https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method}
|
34
|
+
*/
|
35
|
+
static readonly AUTH_METHODS_SUPPORTED = ['none', 'private_key_jwt'] as const
|
36
|
+
|
37
|
+
private readonly keyGetter: JWTVerifyGetKey
|
38
|
+
|
39
|
+
constructor(
|
40
|
+
public readonly id: ClientId,
|
41
|
+
public readonly metadata: OAuthClientMetadata,
|
42
|
+
public readonly jwks: undefined | Jwks = metadata.jwks,
|
43
|
+
public readonly info: ClientInfo,
|
44
|
+
) {
|
45
|
+
// If the remote JWKS content is provided, we don't need to fetch it again.
|
46
|
+
this.keyGetter =
|
47
|
+
jwks || !metadata.jwks_uri
|
48
|
+
? createLocalJWKSet(jwks || { keys: [] })
|
49
|
+
: createRemoteJWKSet(new URL(metadata.jwks_uri), {})
|
50
|
+
}
|
51
|
+
|
52
|
+
public async decodeRequestObject(jar: string) {
|
53
|
+
try {
|
54
|
+
switch (this.metadata.request_object_signing_alg) {
|
55
|
+
case 'none':
|
56
|
+
return await this.jwtVerifyUnsecured(jar, {
|
57
|
+
maxTokenAge: JAR_MAX_AGE / 1000,
|
58
|
+
})
|
59
|
+
case undefined:
|
60
|
+
// https://openid.net/specs/openid-connect-registration-1_0.html#rfc.section.2
|
61
|
+
// > The default, if omitted, is that any algorithm supported by the OP
|
62
|
+
// > and the RP MAY be used.
|
63
|
+
return await this.jwtVerify(jar, {
|
64
|
+
maxTokenAge: JAR_MAX_AGE / 1000,
|
65
|
+
})
|
66
|
+
default:
|
67
|
+
return await this.jwtVerify(jar, {
|
68
|
+
maxTokenAge: JAR_MAX_AGE / 1000,
|
69
|
+
algorithms: [this.metadata.request_object_signing_alg],
|
70
|
+
})
|
71
|
+
}
|
72
|
+
} catch (err) {
|
73
|
+
const message =
|
74
|
+
err instanceof JOSEError
|
75
|
+
? `Invalid "request" object: ${err.message}`
|
76
|
+
: `Invalid "request" object`
|
77
|
+
|
78
|
+
throw new InvalidRequestError(message, err)
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
protected async jwtVerifyUnsecured<PayloadType = JWTPayload>(
|
83
|
+
token: string,
|
84
|
+
options?: Omit<JWTVerifyOptions, 'issuer'>,
|
85
|
+
): Promise<UnsecuredResult<PayloadType>> {
|
86
|
+
return UnsecuredJWT.decode(token, {
|
87
|
+
...options,
|
88
|
+
issuer: this.id,
|
89
|
+
})
|
90
|
+
}
|
91
|
+
|
92
|
+
protected async jwtVerify<PayloadType = JWTPayload>(
|
93
|
+
token: string,
|
94
|
+
options?: Omit<JWTVerifyOptions, 'issuer'>,
|
95
|
+
): Promise<JWTVerifyResult<PayloadType> & ResolvedKey<KeyLike>> {
|
96
|
+
return jwtVerify<PayloadType>(token, this.keyGetter, {
|
97
|
+
...options,
|
98
|
+
issuer: this.id,
|
99
|
+
})
|
100
|
+
}
|
101
|
+
|
102
|
+
protected getAuthMethod(endpoint: OAuthEndpointName) {
|
103
|
+
return (
|
104
|
+
this.metadata[`${endpoint}_endpoint_auth_method`] ||
|
105
|
+
this.metadata[`token_endpoint_auth_method`]
|
106
|
+
)
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1}
|
111
|
+
* @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-jwt-bearer-11#section-3}
|
112
|
+
* @see {@link https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#token-endpoint-auth-method}
|
113
|
+
*/
|
114
|
+
public async verifyCredentials(
|
115
|
+
input: OAuthClientIdentification,
|
116
|
+
endpoint: OAuthEndpointName,
|
117
|
+
checks: {
|
118
|
+
audience: string
|
119
|
+
},
|
120
|
+
): Promise<{
|
121
|
+
clientAuth: ClientAuth
|
122
|
+
// for replay protection
|
123
|
+
nonce?: string
|
124
|
+
}> {
|
125
|
+
const method = this.getAuthMethod(endpoint)
|
126
|
+
|
127
|
+
if (method === 'none') {
|
128
|
+
const clientAuth: ClientAuth = { method: 'none' }
|
129
|
+
return { clientAuth }
|
130
|
+
}
|
131
|
+
|
132
|
+
if (method === 'private_key_jwt') {
|
133
|
+
if (!('client_assertion_type' in input) || !input.client_assertion_type) {
|
134
|
+
throw new InvalidRequestError(
|
135
|
+
`client_assertion_type required for "${method}"`,
|
136
|
+
)
|
137
|
+
} else if (!input.client_assertion) {
|
138
|
+
throw new InvalidRequestError(
|
139
|
+
`client_assertion required for "${method}"`,
|
140
|
+
)
|
141
|
+
}
|
142
|
+
|
143
|
+
if (input.client_assertion_type === CLIENT_ASSERTION_TYPE_JWT_BEARER) {
|
144
|
+
const result = await this.jwtVerify<{
|
145
|
+
jti: string
|
146
|
+
}>(input.client_assertion, {
|
147
|
+
audience: checks.audience,
|
148
|
+
subject: this.id,
|
149
|
+
maxTokenAge: CLIENT_ASSERTION_MAX_AGE / 1000,
|
150
|
+
}).catch((err) => {
|
151
|
+
if (err instanceof JOSEError) {
|
152
|
+
const msg = `Validation of "client_assertion" failed: ${err.message}`
|
153
|
+
throw new InvalidClientError(msg, err)
|
154
|
+
}
|
155
|
+
|
156
|
+
throw err
|
157
|
+
})
|
158
|
+
|
159
|
+
if (!result.protectedHeader.kid) {
|
160
|
+
throw new InvalidClientError(`"kid" required in client_assertion`)
|
161
|
+
}
|
162
|
+
|
163
|
+
if (!result.payload.jti) {
|
164
|
+
throw new InvalidClientError(`"jti" required in client_assertion`)
|
165
|
+
}
|
166
|
+
|
167
|
+
const clientAuth: ClientAuth = {
|
168
|
+
method: CLIENT_ASSERTION_TYPE_JWT_BEARER,
|
169
|
+
jkt: await authJwkThumbprint(result.key),
|
170
|
+
alg: result.protectedHeader.alg,
|
171
|
+
kid: result.protectedHeader.kid,
|
172
|
+
}
|
173
|
+
|
174
|
+
return { clientAuth, nonce: result.payload.jti }
|
175
|
+
}
|
176
|
+
|
177
|
+
throw new InvalidClientError(
|
178
|
+
`Unsupported client_assertion_type "${input.client_assertion_type}"`,
|
179
|
+
)
|
180
|
+
}
|
181
|
+
|
182
|
+
// @ts-expect-error Ensure to keep Client.AUTH_METHODS_SUPPORTED in sync
|
183
|
+
// with the implementation of this function.
|
184
|
+
if (Client.AUTH_METHODS_SUPPORTED.includes(method)) {
|
185
|
+
throw new Error(
|
186
|
+
`verifyCredentials() should implement all of ${[
|
187
|
+
Client.AUTH_METHODS_SUPPORTED,
|
188
|
+
]}`,
|
189
|
+
)
|
190
|
+
}
|
191
|
+
|
192
|
+
throw new InvalidClientMetadataError(
|
193
|
+
`Unsupported ${endpoint}_endpoint_auth_method "${method}"`,
|
194
|
+
)
|
195
|
+
}
|
196
|
+
|
197
|
+
/**
|
198
|
+
* Ensures that a {@link ClientAuth} generated in the past is still valid wrt
|
199
|
+
* the current client metadata & jwks. This is used to invalidate tokens when
|
200
|
+
* the client stops advertising the key that it used to authenticate itself
|
201
|
+
* during the initial token request.
|
202
|
+
*/
|
203
|
+
public async validateClientAuth(clientAuth: ClientAuth): Promise<boolean> {
|
204
|
+
if (clientAuth.method === 'none') {
|
205
|
+
return this.getAuthMethod('token') === 'none'
|
206
|
+
}
|
207
|
+
|
208
|
+
if (clientAuth.method === CLIENT_ASSERTION_TYPE_JWT_BEARER) {
|
209
|
+
if (this.getAuthMethod('token') !== 'private_key_jwt') {
|
210
|
+
return false
|
211
|
+
}
|
212
|
+
try {
|
213
|
+
const key = await this.keyGetter(
|
214
|
+
{
|
215
|
+
kid: clientAuth.kid,
|
216
|
+
alg: clientAuth.alg,
|
217
|
+
},
|
218
|
+
{ payload: '', signature: '' },
|
219
|
+
)
|
220
|
+
const jtk = await authJwkThumbprint(key)
|
221
|
+
|
222
|
+
return jtk === clientAuth.jkt
|
223
|
+
} catch (e) {
|
224
|
+
return false
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
// @ts-expect-error
|
229
|
+
throw new Error(`Invalid method "${clientAuth.method}"`)
|
230
|
+
}
|
231
|
+
}
|
package/src/constants.ts
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
// The purpose of the prefix is to provide type safety
|
2
|
+
|
3
|
+
export const DEVICE_ID_PREFIX = 'dev-'
|
4
|
+
export const DEVICE_ID_BYTES_LENGTH = 16 // 128 bits
|
5
|
+
|
6
|
+
export const SESSION_ID_PREFIX = 'ses-'
|
7
|
+
export const SESSION_ID_BYTES_LENGTH = 16 // 128 bits - only valid if device id is valid
|
8
|
+
|
9
|
+
export const REFRESH_TOKEN_PREFIX = 'ref-'
|
10
|
+
export const REFRESH_TOKEN_BYTES_LENGTH = 32 // 256 bits
|
11
|
+
|
12
|
+
export const TOKEN_ID_PREFIX = 'tok-'
|
13
|
+
export const TOKEN_ID_BYTES_LENGTH = 16 // 128 bits - used as `jti` in JWTs (cannot be forged)
|
14
|
+
|
15
|
+
export const REQUEST_ID_PREFIX = 'req-'
|
16
|
+
export const REQUEST_ID_BYTES_LENGTH = 16 // 128 bits
|
17
|
+
|
18
|
+
export const CODE_PREFIX = 'cod-'
|
19
|
+
export const CODE_BYTES_LENGTH = 32
|
20
|
+
|
21
|
+
export const ALLOW_LOOPBACK_CLIENT_REFRESH_TOKEN = true
|
22
|
+
|
23
|
+
const SECOND = 1e3
|
24
|
+
const MINUTE = 60 * SECOND
|
25
|
+
const HOUR = 60 * MINUTE
|
26
|
+
const DAY = 24 * HOUR
|
27
|
+
const WEEK = 7 * DAY
|
28
|
+
const YEAR = 365.25 * DAY
|
29
|
+
const MONTH = YEAR / 12
|
30
|
+
|
31
|
+
/** 7 days */
|
32
|
+
export const AUTHENTICATION_MAX_AGE = 7 * DAY
|
33
|
+
|
34
|
+
/** 60 minutes */
|
35
|
+
export const TOKEN_MAX_AGE = 60 * MINUTE
|
36
|
+
|
37
|
+
/** 5 minutes */
|
38
|
+
export const AUTHORIZATION_INACTIVITY_TIMEOUT = 5 * MINUTE
|
39
|
+
|
40
|
+
/** 1 months */
|
41
|
+
export const AUTHENTICATED_REFRESH_INACTIVITY_TIMEOUT = 1 * MONTH
|
42
|
+
|
43
|
+
/** 2 days */
|
44
|
+
export const UNAUTHENTICATED_REFRESH_INACTIVITY_TIMEOUT = 2 * DAY
|
45
|
+
|
46
|
+
/** 1 week */
|
47
|
+
export const UNAUTHENTICATED_REFRESH_LIFETIME = 1 * WEEK
|
48
|
+
|
49
|
+
/** 1 year */
|
50
|
+
export const AUTHENTICATED_REFRESH_LIFETIME = 1 * YEAR
|
51
|
+
|
52
|
+
/** 5 minutes */
|
53
|
+
export const PAR_EXPIRES_IN = 5 * MINUTE
|
54
|
+
|
55
|
+
/**
|
56
|
+
* 59 seconds (should be less than a minute)
|
57
|
+
*
|
58
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc9101#section-10.2}
|
59
|
+
*/
|
60
|
+
export const JAR_MAX_AGE = 59 * SECOND
|
61
|
+
|
62
|
+
/** 1 minute */
|
63
|
+
export const CLIENT_ASSERTION_MAX_AGE = 1 * MINUTE
|
64
|
+
|
65
|
+
/** 3 minutes */
|
66
|
+
export const DPOP_NONCE_MAX_AGE = 3 * MINUTE
|
67
|
+
|
68
|
+
/** 5 seconds */
|
69
|
+
export const SESSION_FIXATION_MAX_AGE = 5 * SECOND
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { z } from 'zod'
|
2
|
+
|
3
|
+
import { deviceDetailsSchema } from './device-details.js'
|
4
|
+
import { sessionIdSchema } from './session-id.js'
|
5
|
+
|
6
|
+
export const deviceDataSchema = deviceDetailsSchema.extend({
|
7
|
+
sessionId: sessionIdSchema,
|
8
|
+
lastSeenAt: z.date(),
|
9
|
+
})
|
10
|
+
|
11
|
+
export type DeviceData = z.infer<typeof deviceDataSchema>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { IncomingMessage } from 'node:http'
|
2
|
+
|
3
|
+
import { z } from 'zod'
|
4
|
+
|
5
|
+
export const deviceDetailsSchema = z.object({
|
6
|
+
userAgent: z.string().nullable(),
|
7
|
+
ipAddress: z.string(),
|
8
|
+
})
|
9
|
+
export type DeviceDetails = z.infer<typeof deviceDetailsSchema>
|
10
|
+
|
11
|
+
export function extractDeviceDetails(
|
12
|
+
req: IncomingMessage,
|
13
|
+
trustProxy: boolean,
|
14
|
+
): DeviceDetails {
|
15
|
+
const userAgent = req.headers['user-agent'] || null
|
16
|
+
const ipAddress = extractIpAddress(req, trustProxy) || null
|
17
|
+
|
18
|
+
if (!ipAddress) {
|
19
|
+
throw new Error('Could not determine IP address')
|
20
|
+
}
|
21
|
+
|
22
|
+
return { userAgent, ipAddress }
|
23
|
+
}
|
24
|
+
|
25
|
+
export function extractIpAddress(
|
26
|
+
req: IncomingMessage,
|
27
|
+
trustProxy: boolean,
|
28
|
+
): string | undefined {
|
29
|
+
// Express app compatibility
|
30
|
+
if ('ip' in req && typeof req.ip === 'string') {
|
31
|
+
return req.ip
|
32
|
+
}
|
33
|
+
|
34
|
+
if (trustProxy) {
|
35
|
+
const forwardedFor = req.headers['x-forwarded-for']
|
36
|
+
if (typeof forwardedFor === 'string') {
|
37
|
+
const firstForward = forwardedFor.split(',')[0]!.trim()
|
38
|
+
if (firstForward) return firstForward
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
return req.socket.remoteAddress
|
43
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { z } from 'zod'
|
2
|
+
|
3
|
+
import { DEVICE_ID_BYTES_LENGTH, DEVICE_ID_PREFIX } from '../constants.js'
|
4
|
+
import { randomHexId } from '../lib/util/crypto.js'
|
5
|
+
|
6
|
+
export const DEVICE_ID_LENGTH =
|
7
|
+
DEVICE_ID_PREFIX.length + DEVICE_ID_BYTES_LENGTH * 2 // hex encoding
|
8
|
+
|
9
|
+
export const deviceIdSchema = z
|
10
|
+
.string()
|
11
|
+
.length(DEVICE_ID_LENGTH)
|
12
|
+
.refine(
|
13
|
+
(v): v is `${typeof DEVICE_ID_PREFIX}${string}` =>
|
14
|
+
v.startsWith(DEVICE_ID_PREFIX),
|
15
|
+
{
|
16
|
+
message: `Invalid device ID format`,
|
17
|
+
},
|
18
|
+
)
|
19
|
+
|
20
|
+
export type DeviceId = z.infer<typeof deviceIdSchema>
|
21
|
+
export const generateDeviceId = async (): Promise<DeviceId> => {
|
22
|
+
return `${DEVICE_ID_PREFIX}${await randomHexId(DEVICE_ID_BYTES_LENGTH)}`
|
23
|
+
}
|