@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,748 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.OAuthProvider = exports.Keyset = void 0;
|
4
|
+
const fetch_node_1 = require("@atproto-labs/fetch-node");
|
5
|
+
const simple_store_memory_1 = require("@atproto-labs/simple-store-memory");
|
6
|
+
const jwk_1 = require("@atproto/jwk");
|
7
|
+
Object.defineProperty(exports, "Keyset", { enumerable: true, get: function () { return jwk_1.Keyset; } });
|
8
|
+
const oauth_types_1 = require("@atproto/oauth-types");
|
9
|
+
const zod_1 = require("zod");
|
10
|
+
const access_token_type_js_1 = require("./access-token/access-token-type.js");
|
11
|
+
const account_manager_js_1 = require("./account/account-manager.js");
|
12
|
+
const account_store_js_1 = require("./account/account-store.js");
|
13
|
+
const assets_middleware_js_1 = require("./assets/assets-middleware.js");
|
14
|
+
const client_auth_js_1 = require("./client/client-auth.js");
|
15
|
+
const client_id_js_1 = require("./client/client-id.js");
|
16
|
+
const client_manager_js_1 = require("./client/client-manager.js");
|
17
|
+
const client_store_js_1 = require("./client/client-store.js");
|
18
|
+
const constants_js_1 = require("./constants.js");
|
19
|
+
const device_manager_js_1 = require("./device/device-manager.js");
|
20
|
+
const device_store_js_1 = require("./device/device-store.js");
|
21
|
+
const access_denied_error_js_1 = require("./errors/access-denied-error.js");
|
22
|
+
const account_selection_required_error_js_1 = require("./errors/account-selection-required-error.js");
|
23
|
+
const consent_required_error_js_1 = require("./errors/consent-required-error.js");
|
24
|
+
const invalid_client_error_js_1 = require("./errors/invalid-client-error.js");
|
25
|
+
const invalid_grant_error_js_1 = require("./errors/invalid-grant-error.js");
|
26
|
+
const invalid_parameters_error_js_1 = require("./errors/invalid-parameters-error.js");
|
27
|
+
const invalid_request_error_js_1 = require("./errors/invalid-request-error.js");
|
28
|
+
const login_required_error_js_1 = require("./errors/login-required-error.js");
|
29
|
+
const oauth_error_js_1 = require("./errors/oauth-error.js");
|
30
|
+
const unauthorized_client_error_js_1 = require("./errors/unauthorized-client-error.js");
|
31
|
+
const www_authenticate_error_js_1 = require("./errors/www-authenticate-error.js");
|
32
|
+
const index_js_1 = require("./lib/http/index.js");
|
33
|
+
const date_js_1 = require("./lib/util/date.js");
|
34
|
+
const build_metadata_js_1 = require("./metadata/build-metadata.js");
|
35
|
+
const oauth_verifier_js_1 = require("./oauth-verifier.js");
|
36
|
+
const build_error_payload_js_1 = require("./output/build-error-payload.js");
|
37
|
+
const send_authorize_page_js_1 = require("./output/send-authorize-page.js");
|
38
|
+
const send_authorize_redirect_js_1 = require("./output/send-authorize-redirect.js");
|
39
|
+
const send_error_page_js_1 = require("./output/send-error-page.js");
|
40
|
+
const oidc_payload_js_1 = require("./parameters/oidc-payload.js");
|
41
|
+
const replay_store_js_1 = require("./replay/replay-store.js");
|
42
|
+
const request_manager_js_1 = require("./request/request-manager.js");
|
43
|
+
const request_store_memory_js_1 = require("./request/request-store-memory.js");
|
44
|
+
const request_store_redis_js_1 = require("./request/request-store-redis.js");
|
45
|
+
const request_store_js_1 = require("./request/request-store.js");
|
46
|
+
const request_uri_js_1 = require("./request/request-uri.js");
|
47
|
+
const types_js_1 = require("./request/types.js");
|
48
|
+
const token_id_js_1 = require("./token/token-id.js");
|
49
|
+
const token_manager_js_1 = require("./token/token-manager.js");
|
50
|
+
const token_store_js_1 = require("./token/token-store.js");
|
51
|
+
const types_js_2 = require("./token/types.js");
|
52
|
+
class OAuthProvider extends oauth_verifier_js_1.OAuthVerifier {
|
53
|
+
metadata;
|
54
|
+
customization;
|
55
|
+
authenticationMaxAge;
|
56
|
+
accountManager;
|
57
|
+
deviceStore;
|
58
|
+
clientManager;
|
59
|
+
requestManager;
|
60
|
+
tokenManager;
|
61
|
+
constructor({ metadata, customization = undefined, authenticationMaxAge = constants_js_1.AUTHENTICATION_MAX_AGE, tokenMaxAge = constants_js_1.TOKEN_MAX_AGE, safeFetch = (0, fetch_node_1.safeFetchWrap)(), redis, store, // compound store implementation
|
62
|
+
// Requires stores
|
63
|
+
accountStore = (0, account_store_js_1.asAccountStore)(store), deviceStore = (0, device_store_js_1.asDeviceStore)(store), tokenStore = (0, token_store_js_1.asTokenStore)(store),
|
64
|
+
// These are optional
|
65
|
+
clientStore = (0, client_store_js_1.ifClientStore)(store), replayStore = (0, replay_store_js_1.ifReplayStore)(store), requestStore = (0, request_store_js_1.ifRequestStore)(store), clientJwksCache = new simple_store_memory_1.SimpleStoreMemory({
|
66
|
+
maxSize: 50_000_000,
|
67
|
+
ttl: 600e3,
|
68
|
+
}), clientMetadataCache = new simple_store_memory_1.SimpleStoreMemory({
|
69
|
+
maxSize: 50_000_000,
|
70
|
+
ttl: 600e3,
|
71
|
+
}), loopbackMetadata = oauth_types_1.atprotoLoopbackClientMetadata,
|
72
|
+
// OAuthHooks & OAuthVerifierOptions
|
73
|
+
...rest }) {
|
74
|
+
super({ replayStore, redis, ...rest });
|
75
|
+
requestStore ??= redis
|
76
|
+
? new request_store_redis_js_1.RequestStoreRedis({ redis })
|
77
|
+
: new request_store_memory_js_1.RequestStoreMemory();
|
78
|
+
this.authenticationMaxAge = authenticationMaxAge;
|
79
|
+
this.metadata = (0, build_metadata_js_1.buildMetadata)(this.issuer, this.keyset, metadata);
|
80
|
+
this.customization = customization;
|
81
|
+
this.deviceStore = deviceStore;
|
82
|
+
this.accountManager = new account_manager_js_1.AccountManager(accountStore);
|
83
|
+
this.clientManager = new client_manager_js_1.ClientManager(this.keyset, rest, clientStore || null, loopbackMetadata || null, safeFetch, clientJwksCache, clientMetadataCache);
|
84
|
+
this.requestManager = new request_manager_js_1.RequestManager(requestStore, this.signer, this.metadata, rest);
|
85
|
+
this.tokenManager = new token_manager_js_1.TokenManager(tokenStore, this.signer, rest, this.accessTokenType, tokenMaxAge);
|
86
|
+
}
|
87
|
+
get jwks() {
|
88
|
+
return this.keyset.publicJwks;
|
89
|
+
}
|
90
|
+
loginRequired(client, parameters, info) {
|
91
|
+
/** in seconds */
|
92
|
+
const authAge = (Date.now() - info.authenticatedAt.getTime()) / 1e3;
|
93
|
+
// Fool-proof (invalid date, or suspiciously in the future)
|
94
|
+
if (!Number.isFinite(authAge) || authAge < 0) {
|
95
|
+
return true;
|
96
|
+
}
|
97
|
+
/** in seconds */
|
98
|
+
const maxAge = parameters.max_age ?? client.metadata.default_max_age;
|
99
|
+
if (maxAge != null && maxAge < this.authenticationMaxAge) {
|
100
|
+
return authAge >= maxAge;
|
101
|
+
}
|
102
|
+
else {
|
103
|
+
return authAge >= this.authenticationMaxAge;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
async authenticateClient(client, endpoint, credentials) {
|
107
|
+
const { clientAuth, nonce } = await client.verifyCredentials(credentials, endpoint, { audience: this.issuer });
|
108
|
+
if (nonce != null) {
|
109
|
+
const unique = await this.replayManager.uniqueAuth(nonce, client.id);
|
110
|
+
if (!unique) {
|
111
|
+
throw new invalid_client_error_js_1.InvalidClientError(`${clientAuth.method} jti reused`);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
return clientAuth;
|
115
|
+
}
|
116
|
+
async decodeJAR(client, input) {
|
117
|
+
const result = await client.decodeRequestObject(input.request);
|
118
|
+
const payload = oauth_types_1.oauthAuthenticationRequestParametersSchema.parse(result.payload);
|
119
|
+
if (!result.payload.jti) {
|
120
|
+
throw new invalid_parameters_error_js_1.InvalidParametersError(payload, 'Request object must contain a jti claim');
|
121
|
+
}
|
122
|
+
if (!(await this.replayManager.uniqueJar(result.payload.jti, client.id))) {
|
123
|
+
throw new invalid_parameters_error_js_1.InvalidParametersError(payload, 'Request object jti is not unique');
|
124
|
+
}
|
125
|
+
if ('protectedHeader' in result) {
|
126
|
+
if (!result.protectedHeader.kid) {
|
127
|
+
throw new invalid_parameters_error_js_1.InvalidParametersError(payload, 'Missing "kid" in header');
|
128
|
+
}
|
129
|
+
return {
|
130
|
+
jkt: await (0, client_auth_js_1.authJwkThumbprint)(result.key),
|
131
|
+
payload,
|
132
|
+
protectedHeader: result.protectedHeader,
|
133
|
+
};
|
134
|
+
}
|
135
|
+
if ('header' in result) {
|
136
|
+
return {
|
137
|
+
payload,
|
138
|
+
};
|
139
|
+
}
|
140
|
+
// Should never happen
|
141
|
+
throw new Error('Invalid request object');
|
142
|
+
}
|
143
|
+
/**
|
144
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc9126}
|
145
|
+
*/
|
146
|
+
async pushedAuthorizationRequest(input, dpopJkt) {
|
147
|
+
try {
|
148
|
+
const client = await this.clientManager.getClient(input.client_id);
|
149
|
+
const clientAuth = await this.authenticateClient(client, 'pushed_authorization_request', input);
|
150
|
+
const { payload: parameters } = 'request' in input // Handle JAR
|
151
|
+
? await this.decodeJAR(client, input)
|
152
|
+
: { payload: input };
|
153
|
+
const { uri, expiresAt } = await this.requestManager.createAuthorizationRequest(client, clientAuth, parameters, null, dpopJkt);
|
154
|
+
return {
|
155
|
+
request_uri: uri,
|
156
|
+
expires_in: (0, date_js_1.dateToRelativeSeconds)(expiresAt),
|
157
|
+
};
|
158
|
+
}
|
159
|
+
catch (err) {
|
160
|
+
// https://datatracker.ietf.org/doc/html/rfc9126#section-2.3-1
|
161
|
+
// > Since initial processing of the pushed authorization request does not
|
162
|
+
// > involve resource owner interaction, error codes related to user
|
163
|
+
// > interaction, such as consent_required defined by [OIDC], are never
|
164
|
+
// > returned.
|
165
|
+
if (err instanceof access_denied_error_js_1.AccessDeniedError) {
|
166
|
+
throw new invalid_request_error_js_1.InvalidRequestError(err.error_description, err);
|
167
|
+
}
|
168
|
+
throw err;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
async loadAuthorizationRequest(client, deviceId, input) {
|
172
|
+
// Load PAR
|
173
|
+
if ('request_uri' in input) {
|
174
|
+
return this.requestManager.get(input.request_uri, client.id, deviceId);
|
175
|
+
}
|
176
|
+
// Handle JAR
|
177
|
+
if ('request' in input) {
|
178
|
+
const requestObject = await this.decodeJAR(client, input);
|
179
|
+
if ('protectedHeader' in requestObject && requestObject.protectedHeader) {
|
180
|
+
// Allow using signed JAR during "/authorize" as client authentication.
|
181
|
+
// This allows clients to skip PAR to initiate trusted sessions.
|
182
|
+
const clientAuth = {
|
183
|
+
method: oauth_types_1.CLIENT_ASSERTION_TYPE_JWT_BEARER,
|
184
|
+
kid: requestObject.protectedHeader.kid,
|
185
|
+
alg: requestObject.protectedHeader.alg,
|
186
|
+
jkt: requestObject.jkt,
|
187
|
+
};
|
188
|
+
return this.requestManager.createAuthorizationRequest(client, clientAuth, requestObject.payload, deviceId, null);
|
189
|
+
}
|
190
|
+
return this.requestManager.createAuthorizationRequest(client, { method: 'none' }, requestObject.payload, deviceId, null);
|
191
|
+
}
|
192
|
+
return this.requestManager.createAuthorizationRequest(client, { method: 'none' }, input, deviceId, null);
|
193
|
+
}
|
194
|
+
async deleteRequest(uri, parameters) {
|
195
|
+
try {
|
196
|
+
await this.requestManager.delete(uri);
|
197
|
+
}
|
198
|
+
catch (err) {
|
199
|
+
throw access_denied_error_js_1.AccessDeniedError.from(parameters, err);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
async authorize(deviceId, input) {
|
203
|
+
const { issuer } = this;
|
204
|
+
const client = await this.clientManager.getClient(input.client_id);
|
205
|
+
try {
|
206
|
+
const { uri, parameters, clientAuth } = await this.loadAuthorizationRequest(client, deviceId, input);
|
207
|
+
try {
|
208
|
+
const sessions = await this.getSessions(client, clientAuth, deviceId, parameters);
|
209
|
+
if (parameters.prompt === 'none') {
|
210
|
+
const ssoSessions = sessions.filter((s) => s.matchesHint);
|
211
|
+
if (ssoSessions.length > 1) {
|
212
|
+
throw new account_selection_required_error_js_1.AccountSelectionRequiredError(parameters);
|
213
|
+
}
|
214
|
+
if (ssoSessions.length < 1) {
|
215
|
+
throw new login_required_error_js_1.LoginRequiredError(parameters);
|
216
|
+
}
|
217
|
+
const ssoSession = ssoSessions[0];
|
218
|
+
if (ssoSession.loginRequired) {
|
219
|
+
throw new login_required_error_js_1.LoginRequiredError(parameters);
|
220
|
+
}
|
221
|
+
if (ssoSession.consentRequired) {
|
222
|
+
throw new consent_required_error_js_1.ConsentRequiredError(parameters);
|
223
|
+
}
|
224
|
+
const redirect = await this.requestManager.setAuthorized(client, uri, deviceId, ssoSession.account, ssoSession.info);
|
225
|
+
return { issuer, client, parameters, redirect };
|
226
|
+
}
|
227
|
+
// Automatic SSO when a did was provided
|
228
|
+
if (parameters.prompt == null && parameters.login_hint != null) {
|
229
|
+
const ssoSessions = sessions.filter((s) => s.matchesHint);
|
230
|
+
if (ssoSessions.length === 1) {
|
231
|
+
const ssoSession = ssoSessions[0];
|
232
|
+
if (!ssoSession.loginRequired && !ssoSession.consentRequired) {
|
233
|
+
const redirect = await this.requestManager.setAuthorized(client, uri, deviceId, ssoSession.account, ssoSession.info);
|
234
|
+
return { issuer, client, parameters, redirect };
|
235
|
+
}
|
236
|
+
}
|
237
|
+
}
|
238
|
+
return {
|
239
|
+
issuer,
|
240
|
+
client,
|
241
|
+
parameters,
|
242
|
+
authorize: { uri, sessions },
|
243
|
+
};
|
244
|
+
}
|
245
|
+
catch (err) {
|
246
|
+
await this.deleteRequest(uri, parameters);
|
247
|
+
// Transform into an AccessDeniedError to allow redirecting the user
|
248
|
+
// to the client with the error details.
|
249
|
+
throw access_denied_error_js_1.AccessDeniedError.from(parameters, err);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
catch (err) {
|
253
|
+
if (err instanceof access_denied_error_js_1.AccessDeniedError) {
|
254
|
+
return {
|
255
|
+
issuer,
|
256
|
+
client,
|
257
|
+
parameters: err.parameters,
|
258
|
+
redirect: err.toJSON(),
|
259
|
+
};
|
260
|
+
}
|
261
|
+
throw err;
|
262
|
+
}
|
263
|
+
}
|
264
|
+
async getSessions(client, clientAuth, deviceId, parameters) {
|
265
|
+
const accounts = await this.accountManager.list(deviceId);
|
266
|
+
return accounts.map(({ account, info }) => ({
|
267
|
+
account,
|
268
|
+
info,
|
269
|
+
selected: parameters.prompt !== 'select_account' &&
|
270
|
+
parameters.login_hint === account.sub,
|
271
|
+
loginRequired: parameters.prompt === 'login' ||
|
272
|
+
this.loginRequired(client, parameters, info),
|
273
|
+
consentRequired: parameters.prompt === 'consent' ||
|
274
|
+
!info.authorizedClients.includes(client.id),
|
275
|
+
matchesHint: parameters.login_hint === account.sub || parameters.login_hint == null,
|
276
|
+
}));
|
277
|
+
}
|
278
|
+
async signIn(deviceId, credentials) {
|
279
|
+
return this.accountManager.signIn(credentials, deviceId);
|
280
|
+
}
|
281
|
+
async acceptRequest(deviceId, uri, clientId, sub) {
|
282
|
+
const { issuer } = this;
|
283
|
+
const client = await this.clientManager.getClient(clientId);
|
284
|
+
try {
|
285
|
+
const { parameters, clientAuth } = await this.requestManager.get(uri, clientId, deviceId);
|
286
|
+
try {
|
287
|
+
const { account, info } = await this.accountManager.get(deviceId, sub);
|
288
|
+
// The user is trying to authorize without a fresh login
|
289
|
+
if (this.loginRequired(client, parameters, info)) {
|
290
|
+
throw new login_required_error_js_1.LoginRequiredError(parameters, 'Account authentication required.');
|
291
|
+
}
|
292
|
+
const redirect = await this.requestManager.setAuthorized(client, uri, deviceId, account, info);
|
293
|
+
await this.accountManager.addAuthorizedClient(deviceId, account, client, clientAuth);
|
294
|
+
return { issuer, client, parameters, redirect };
|
295
|
+
}
|
296
|
+
catch (err) {
|
297
|
+
await this.deleteRequest(uri, parameters);
|
298
|
+
// throw AccessDeniedError.from(parameters, err)
|
299
|
+
throw err;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
catch (err) {
|
303
|
+
if (err instanceof access_denied_error_js_1.AccessDeniedError) {
|
304
|
+
const { parameters } = err;
|
305
|
+
return { issuer, client, parameters, redirect: err.toJSON() };
|
306
|
+
}
|
307
|
+
throw err;
|
308
|
+
}
|
309
|
+
}
|
310
|
+
async rejectRequest(deviceId, uri, clientId) {
|
311
|
+
try {
|
312
|
+
const { parameters } = await this.requestManager.get(uri, clientId, deviceId);
|
313
|
+
await this.deleteRequest(uri, parameters);
|
314
|
+
// Trigger redirect (see catch block)
|
315
|
+
throw new access_denied_error_js_1.AccessDeniedError(parameters, 'Access denied');
|
316
|
+
}
|
317
|
+
catch (err) {
|
318
|
+
if (err instanceof access_denied_error_js_1.AccessDeniedError) {
|
319
|
+
return {
|
320
|
+
issuer: this.issuer,
|
321
|
+
client: await this.clientManager.getClient(clientId),
|
322
|
+
parameters: err.parameters,
|
323
|
+
redirect: err.toJSON(),
|
324
|
+
};
|
325
|
+
}
|
326
|
+
throw err;
|
327
|
+
}
|
328
|
+
}
|
329
|
+
async token(input, dpopJkt) {
|
330
|
+
const client = await this.clientManager.getClient(input.client_id);
|
331
|
+
const clientAuth = await this.authenticateClient(client, 'token', input);
|
332
|
+
if (!client.metadata.grant_types.includes(input.grant_type)) {
|
333
|
+
throw new invalid_grant_error_js_1.InvalidGrantError(`"${input.grant_type}" grant type is not allowed for this client`);
|
334
|
+
}
|
335
|
+
if (input.grant_type === 'authorization_code') {
|
336
|
+
return this.codeGrant(client, clientAuth, input, dpopJkt);
|
337
|
+
}
|
338
|
+
if (input.grant_type === 'refresh_token') {
|
339
|
+
return this.refreshTokenGrant(client, clientAuth, input, dpopJkt);
|
340
|
+
}
|
341
|
+
throw new invalid_grant_error_js_1.InvalidGrantError(
|
342
|
+
// @ts-expect-error: fool proof
|
343
|
+
`Grant type "${input.grant_type}" not supported`);
|
344
|
+
}
|
345
|
+
async codeGrant(client, clientAuth, input, dpopJkt) {
|
346
|
+
try {
|
347
|
+
const { sub, deviceId, parameters } = await this.requestManager.findCode(client, clientAuth, input.code);
|
348
|
+
const { account, info } = await this.accountManager.get(deviceId, sub);
|
349
|
+
return await this.tokenManager.create(client, clientAuth, account, { id: deviceId, info }, parameters, input, dpopJkt);
|
350
|
+
}
|
351
|
+
catch (err) {
|
352
|
+
// If a token is replayed, requestManager.findCode will throw. In that
|
353
|
+
// case, we need to revoke any token that was issued for this code.
|
354
|
+
await this.tokenManager.revoke(input.code);
|
355
|
+
// @TODO (?) in order to protect the user, we should maybe also mark the
|
356
|
+
// account-device association as expired ?
|
357
|
+
throw err;
|
358
|
+
}
|
359
|
+
}
|
360
|
+
async refreshTokenGrant(client, clientAuth, input, dpopJkt) {
|
361
|
+
return this.tokenManager.refresh(client, clientAuth, input, dpopJkt);
|
362
|
+
}
|
363
|
+
/**
|
364
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7009#section-2.1 rfc7009}
|
365
|
+
*/
|
366
|
+
async revoke(input) {
|
367
|
+
// @TODO this should also remove the account-device association (or, at
|
368
|
+
// least, mark it as expired)
|
369
|
+
await this.tokenManager.revoke(input.token);
|
370
|
+
}
|
371
|
+
/**
|
372
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7662#section-2.1 rfc7662}
|
373
|
+
*/
|
374
|
+
async introspect(input) {
|
375
|
+
const client = await this.clientManager.getClient(input.client_id);
|
376
|
+
const clientAuth = await this.authenticateClient(client, 'introspection', input);
|
377
|
+
// RFC7662 states the following:
|
378
|
+
//
|
379
|
+
// > To prevent token scanning attacks, the endpoint MUST also require some
|
380
|
+
// > form of authorization to access this endpoint, such as client
|
381
|
+
// > authentication as described in OAuth 2.0 [RFC6749] or a separate OAuth
|
382
|
+
// > 2.0 access token such as the bearer token described in OAuth 2.0 Bearer
|
383
|
+
// > Token Usage [RFC6750]. The methods of managing and validating these
|
384
|
+
// > authentication credentials are out of scope of this specification.
|
385
|
+
if (clientAuth.method === 'none') {
|
386
|
+
throw new unauthorized_client_error_js_1.UnauthorizedClientError('Client authentication required');
|
387
|
+
}
|
388
|
+
const start = Date.now();
|
389
|
+
try {
|
390
|
+
const tokenInfo = await this.tokenManager.clientTokenInfo(client, clientAuth, input.token);
|
391
|
+
return {
|
392
|
+
active: true,
|
393
|
+
scope: tokenInfo.data.parameters.scope,
|
394
|
+
client_id: tokenInfo.data.clientId,
|
395
|
+
username: tokenInfo.account.preferred_username,
|
396
|
+
token_type: tokenInfo.data.parameters.dpop_jkt ? 'DPoP' : 'Bearer',
|
397
|
+
authorization_details: tokenInfo.data.details ?? undefined,
|
398
|
+
aud: tokenInfo.account.aud,
|
399
|
+
exp: (0, date_js_1.dateToEpoch)(tokenInfo.data.expiresAt),
|
400
|
+
iat: (0, date_js_1.dateToEpoch)(tokenInfo.data.updatedAt),
|
401
|
+
iss: this.signer.issuer,
|
402
|
+
jti: tokenInfo.id,
|
403
|
+
sub: tokenInfo.account.sub,
|
404
|
+
};
|
405
|
+
}
|
406
|
+
catch (err) {
|
407
|
+
// Prevent brute force & timing attack (only for inactive tokens)
|
408
|
+
await new Promise((r) => setTimeout(r, 750 - (Date.now() - start)));
|
409
|
+
return {
|
410
|
+
active: false,
|
411
|
+
};
|
412
|
+
}
|
413
|
+
}
|
414
|
+
/**
|
415
|
+
* @see {@link https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.5.3.2 Successful UserInfo Response}
|
416
|
+
*/
|
417
|
+
async userinfo({ data, account }) {
|
418
|
+
return {
|
419
|
+
...(0, oidc_payload_js_1.oidcPayload)(data.parameters, account),
|
420
|
+
sub: account.sub,
|
421
|
+
client_id: data.clientId,
|
422
|
+
username: account.preferred_username,
|
423
|
+
};
|
424
|
+
}
|
425
|
+
async signUserinfo(userinfo) {
|
426
|
+
const client = await this.clientManager.getClient(userinfo.client_id);
|
427
|
+
return this.signer.sign({
|
428
|
+
alg: client.metadata.userinfo_signed_response_alg,
|
429
|
+
typ: 'JWT',
|
430
|
+
}, userinfo);
|
431
|
+
}
|
432
|
+
async authenticateToken(tokenType, token, dpopJkt, verifyOptions) {
|
433
|
+
if ((0, token_id_js_1.isTokenId)(token)) {
|
434
|
+
this.assertTokenTypeAllowed(tokenType, access_token_type_js_1.AccessTokenType.id);
|
435
|
+
return this.tokenManager.authenticateTokenId(tokenType, token, dpopJkt, verifyOptions);
|
436
|
+
}
|
437
|
+
return super.authenticateToken(tokenType, token, dpopJkt, verifyOptions);
|
438
|
+
}
|
439
|
+
/**
|
440
|
+
* @returns An http request handler that can be used with node's http server
|
441
|
+
* or as a middleware with express / connect.
|
442
|
+
*/
|
443
|
+
httpHandler(options) {
|
444
|
+
const router = this.buildRouter(options);
|
445
|
+
return router.buildHandler();
|
446
|
+
}
|
447
|
+
buildRouter({ onError = process.env['NODE_ENV'] === 'development'
|
448
|
+
? (req, res, err, msg) => console.error(`OAuthProvider error (${msg}):`, err)
|
449
|
+
: undefined, } = {}) {
|
450
|
+
const deviceManager = new device_manager_js_1.DeviceManager(this.deviceStore);
|
451
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
452
|
+
const server = this;
|
453
|
+
const issuerUrl = new URL(server.issuer);
|
454
|
+
const issuerOrigin = issuerUrl.origin;
|
455
|
+
const router = new index_js_1.Router(issuerUrl);
|
456
|
+
// Utils
|
457
|
+
const csrfCookie = (uri) => `csrf-${uri}`;
|
458
|
+
/**
|
459
|
+
* Creates a middleware that will serve static JSON content.
|
460
|
+
*/
|
461
|
+
const staticJson = (json) => (0, index_js_1.combineMiddlewares)([
|
462
|
+
function (req, res, next) {
|
463
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
464
|
+
res.setHeader('Cache-Control', 'max-age=300');
|
465
|
+
next();
|
466
|
+
},
|
467
|
+
(0, index_js_1.staticJsonHandler)(json),
|
468
|
+
]);
|
469
|
+
/**
|
470
|
+
* Wrap an OAuth endpoint in a middleware that will set the appropriate
|
471
|
+
* response headers and format the response as JSON.
|
472
|
+
*/
|
473
|
+
const dynamicJson = (buildJson, status) => async function (req, res) {
|
474
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
475
|
+
// https://www.rfc-editor.org/rfc/rfc6749.html#section-5.1
|
476
|
+
res.setHeader('Cache-Control', 'no-store');
|
477
|
+
res.setHeader('Pragma', 'no-cache');
|
478
|
+
// https://datatracker.ietf.org/doc/html/rfc9449#section-8.2
|
479
|
+
const dpopNonce = server.nextDpopNonce();
|
480
|
+
if (dpopNonce) {
|
481
|
+
const name = 'DPoP-Nonce';
|
482
|
+
res.setHeader(name, dpopNonce);
|
483
|
+
res.appendHeader('Access-Control-Expose-Headers', name);
|
484
|
+
}
|
485
|
+
try {
|
486
|
+
const result = await buildJson.call(this, req, res);
|
487
|
+
if (result !== undefined)
|
488
|
+
(0, index_js_1.writeJson)(res, result, status);
|
489
|
+
else if (!res.headersSent)
|
490
|
+
res.writeHead(status ?? 204).end();
|
491
|
+
}
|
492
|
+
catch (err) {
|
493
|
+
if (!res.headersSent) {
|
494
|
+
if (err instanceof www_authenticate_error_js_1.WWWAuthenticateError) {
|
495
|
+
const name = 'WWW-Authenticate';
|
496
|
+
res.setHeader(name, err.wwwAuthenticateHeader);
|
497
|
+
res.appendHeader('Access-Control-Expose-Headers', name);
|
498
|
+
}
|
499
|
+
(0, index_js_1.writeJson)(res, (0, build_error_payload_js_1.buildErrorPayload)(err), (0, build_error_payload_js_1.buildErrorStatus)(err));
|
500
|
+
}
|
501
|
+
else {
|
502
|
+
res.destroy();
|
503
|
+
}
|
504
|
+
// OAuthError are used to build expected responses, so we don't log
|
505
|
+
// them as errors.
|
506
|
+
if (!(err instanceof oauth_error_js_1.OAuthError) || err.statusCode >= 500) {
|
507
|
+
await onError?.(req, res, err, 'Unexpected error');
|
508
|
+
}
|
509
|
+
}
|
510
|
+
};
|
511
|
+
//- Public OAuth endpoints
|
512
|
+
/*
|
513
|
+
* Although OpenID compatibility is not required to implement the Atproto
|
514
|
+
* OAuth2 specification, we do support OIDC discovery in this
|
515
|
+
* implementation as we believe this may:
|
516
|
+
* 1) Make the implementation of Atproto clients easier (since lots of
|
517
|
+
* libraries support OIDC discovery)
|
518
|
+
* 2) Allow self hosted PDS' to not implement authentication themselves
|
519
|
+
* but rely on a trusted Atproto actor to act as their OIDC providers.
|
520
|
+
* By supporting OIDC in the current implementation, Bluesky's
|
521
|
+
* Authorization Server server can be used as an OIDC provider for
|
522
|
+
* these users.
|
523
|
+
*/
|
524
|
+
router.get('/.well-known/openid-configuration', staticJson(server.metadata));
|
525
|
+
router.get('/.well-known/oauth-authorization-server', staticJson(server.metadata));
|
526
|
+
// CORS preflight
|
527
|
+
router.options(/^\/oauth\/(?<endpoint>jwks|par|token|revoke|introspect|userinfo)$/, function (req, res, _next) {
|
528
|
+
res
|
529
|
+
.writeHead(204, {
|
530
|
+
'Access-Control-Allow-Origin': req.headers['origin'] || '*',
|
531
|
+
'Access-Control-Allow-Methods': this.params.endpoint === 'jwks' ? 'GET' : 'POST',
|
532
|
+
'Access-Control-Allow-Headers': 'Content-Type,Authorization,DPoP',
|
533
|
+
'Access-Control-Max-Age': '86400', // 1 day
|
534
|
+
})
|
535
|
+
.end();
|
536
|
+
});
|
537
|
+
router.get('/oauth/jwks', staticJson(server.jwks));
|
538
|
+
router.post('/oauth/par', dynamicJson(async function (req, _res) {
|
539
|
+
const input = await (0, index_js_1.validateRequestPayload)(req, types_js_1.pushedAuthorizationRequestSchema);
|
540
|
+
const dpopJkt = await server.checkDpopProof(req.headers['dpop'], req.method, this.url);
|
541
|
+
return server.pushedAuthorizationRequest(input, dpopJkt);
|
542
|
+
}, 201));
|
543
|
+
// https://datatracker.ietf.org/doc/html/rfc9126#section-2.3
|
544
|
+
router.addRoute('*', '/oauth/par', (req, res) => {
|
545
|
+
res.writeHead(405).end();
|
546
|
+
});
|
547
|
+
router.post('/oauth/token', dynamicJson(async function (req, _res) {
|
548
|
+
const input = await (0, index_js_1.validateRequestPayload)(req, types_js_2.tokenRequestSchema);
|
549
|
+
const dpopJkt = await server.checkDpopProof(req.headers['dpop'], req.method, this.url);
|
550
|
+
return server.token(input, dpopJkt);
|
551
|
+
}));
|
552
|
+
router.post('/oauth/revoke', dynamicJson(async function (req, res) {
|
553
|
+
const input = await (0, index_js_1.validateRequestPayload)(req, types_js_2.revokeSchema);
|
554
|
+
try {
|
555
|
+
await server.revoke(input);
|
556
|
+
}
|
557
|
+
catch (err) {
|
558
|
+
onError?.(req, res, err, 'Failed to revoke token');
|
559
|
+
}
|
560
|
+
}));
|
561
|
+
router.get('/oauth/revoke', dynamicJson(async function (req, res) {
|
562
|
+
(0, index_js_1.validateFetchMode)(req, res, ['navigate']);
|
563
|
+
(0, index_js_1.validateSameOrigin)(req, res, issuerOrigin);
|
564
|
+
const query = Object.fromEntries(this.url.searchParams);
|
565
|
+
const input = types_js_2.revokeSchema.parse(query, { path: ['query'] });
|
566
|
+
try {
|
567
|
+
await server.revoke(input);
|
568
|
+
}
|
569
|
+
catch (err) {
|
570
|
+
onError?.(req, res, err, 'Failed to revoke token');
|
571
|
+
}
|
572
|
+
// Same as POST + redirect to callback URL
|
573
|
+
// todo: generate JSONP response (if "callback" is provided)
|
574
|
+
throw new Error('You are successfully logged out. Redirect not implemented');
|
575
|
+
}));
|
576
|
+
router.post('/oauth/introspect', dynamicJson(async function (req, _res) {
|
577
|
+
const input = await (0, index_js_1.validateRequestPayload)(req, types_js_2.introspectSchema);
|
578
|
+
return server.introspect(input);
|
579
|
+
}));
|
580
|
+
const userinfoBodySchema = zod_1.z.object({
|
581
|
+
access_token: jwk_1.signedJwtSchema.optional(),
|
582
|
+
});
|
583
|
+
router.addRoute(['GET', 'POST'], '/oauth/userinfo', (0, index_js_1.acceptMiddleware)(async function (req, _res) {
|
584
|
+
const body = req.method === 'POST'
|
585
|
+
? await (0, index_js_1.validateRequestPayload)(req, userinfoBodySchema)
|
586
|
+
: null;
|
587
|
+
if (body?.access_token && req.headers['authorization']) {
|
588
|
+
throw new invalid_request_error_js_1.InvalidRequestError('access token must be provided in either the authorization header or the request body');
|
589
|
+
}
|
590
|
+
const auth = await server.authenticateRequest(req.method, this.url, body?.access_token // Allow credentials to be parsed from body.
|
591
|
+
? {
|
592
|
+
authorization: `Bearer ${body.access_token}`,
|
593
|
+
dpop: undefined, // DPoP can only be used with headers
|
594
|
+
}
|
595
|
+
: req.headers, {
|
596
|
+
scope: ['profile'],
|
597
|
+
});
|
598
|
+
const tokenInfo = 'tokenInfo' in auth
|
599
|
+
? auth.tokenInfo
|
600
|
+
: await server.tokenManager.getTokenInfo(auth.tokenType, auth.tokenId);
|
601
|
+
return server.userinfo(tokenInfo);
|
602
|
+
}, {
|
603
|
+
'': 'application/json',
|
604
|
+
'application/json': dynamicJson(async function (_req, _res) {
|
605
|
+
return this.data;
|
606
|
+
}),
|
607
|
+
'application/jwt': dynamicJson(async function (_req, res) {
|
608
|
+
const jwt = await server.signUserinfo(this.data);
|
609
|
+
res.writeHead(200, { 'Content-Type': 'application/jwt' }).end(jwt);
|
610
|
+
return undefined;
|
611
|
+
}),
|
612
|
+
}));
|
613
|
+
//- Private authorization endpoints
|
614
|
+
router.use((0, assets_middleware_js_1.authorizeAssetsMiddleware)());
|
615
|
+
router.get('/oauth/authorize', async function (req, res) {
|
616
|
+
try {
|
617
|
+
res.setHeader('Cache-Control', 'no-store');
|
618
|
+
(0, index_js_1.validateFetchMode)(req, res, ['navigate']);
|
619
|
+
(0, index_js_1.validateSameOrigin)(req, res, issuerOrigin);
|
620
|
+
const query = Object.fromEntries(this.url.searchParams);
|
621
|
+
const input = await types_js_1.authorizationRequestQuerySchema.parseAsync(query, {
|
622
|
+
path: ['query'],
|
623
|
+
});
|
624
|
+
const { deviceId } = await deviceManager.load(req, res);
|
625
|
+
const data = await server.authorize(deviceId, input);
|
626
|
+
switch (true) {
|
627
|
+
case 'redirect' in data: {
|
628
|
+
return await (0, send_authorize_redirect_js_1.sendAuthorizeRedirect)(res, data);
|
629
|
+
}
|
630
|
+
case 'authorize' in data: {
|
631
|
+
await (0, index_js_1.setupCsrfToken)(req, res, csrfCookie(data.authorize.uri));
|
632
|
+
return await (0, send_authorize_page_js_1.sendAuthorizePage)(res, data, server.customization);
|
633
|
+
}
|
634
|
+
default: {
|
635
|
+
// Should never happen
|
636
|
+
throw new Error('Unexpected authorization result');
|
637
|
+
}
|
638
|
+
}
|
639
|
+
}
|
640
|
+
catch (err) {
|
641
|
+
await onError?.(req, res, err, 'Failed to setup authorize');
|
642
|
+
if (!res.headersSent) {
|
643
|
+
await (0, send_error_page_js_1.sendErrorPage)(res, err, server.customization);
|
644
|
+
}
|
645
|
+
}
|
646
|
+
});
|
647
|
+
const signInPayloadSchema = zod_1.z.object({
|
648
|
+
csrf_token: zod_1.z.string(),
|
649
|
+
request_uri: request_uri_js_1.requestUriSchema,
|
650
|
+
client_id: client_id_js_1.clientIdSchema,
|
651
|
+
credentials: zod_1.z.object({
|
652
|
+
username: zod_1.z.string(),
|
653
|
+
password: zod_1.z.string(),
|
654
|
+
remember: zod_1.z.boolean().optional().default(false),
|
655
|
+
}),
|
656
|
+
});
|
657
|
+
router.post('/oauth/authorize/sign-in', async function (req, res) {
|
658
|
+
(0, index_js_1.validateFetchMode)(req, res, ['same-origin']);
|
659
|
+
(0, index_js_1.validateSameOrigin)(req, res, issuerOrigin);
|
660
|
+
const input = await (0, index_js_1.validateRequestPayload)(req, signInPayloadSchema);
|
661
|
+
(0, index_js_1.validateReferer)(req, res, {
|
662
|
+
origin: issuerOrigin,
|
663
|
+
pathname: '/oauth/authorize',
|
664
|
+
});
|
665
|
+
(0, index_js_1.validateCsrfToken)(req, res, input.csrf_token, csrfCookie(input.request_uri));
|
666
|
+
const { deviceId } = await deviceManager.load(req, res);
|
667
|
+
const { account, info } = await server.signIn(deviceId, input.credentials);
|
668
|
+
// Prevent fixation attacks
|
669
|
+
await deviceManager.rotate(req, res, deviceId);
|
670
|
+
return (0, index_js_1.writeJson)(res, {
|
671
|
+
account,
|
672
|
+
consentRequired: !info.authorizedClients.includes(input.client_id),
|
673
|
+
});
|
674
|
+
});
|
675
|
+
const acceptQuerySchema = zod_1.z.object({
|
676
|
+
csrf_token: zod_1.z.string(),
|
677
|
+
request_uri: request_uri_js_1.requestUriSchema,
|
678
|
+
client_id: client_id_js_1.clientIdSchema,
|
679
|
+
account_sub: zod_1.z.string(),
|
680
|
+
});
|
681
|
+
router.get('/oauth/authorize/accept', async function (req, res) {
|
682
|
+
try {
|
683
|
+
res.setHeader('Cache-Control', 'no-store');
|
684
|
+
(0, index_js_1.validateFetchMode)(req, res, ['navigate']);
|
685
|
+
(0, index_js_1.validateSameOrigin)(req, res, issuerOrigin);
|
686
|
+
const query = Object.fromEntries(this.url.searchParams);
|
687
|
+
const input = await acceptQuerySchema.parseAsync(query, {
|
688
|
+
path: ['query'],
|
689
|
+
});
|
690
|
+
(0, index_js_1.validateReferer)(req, res, {
|
691
|
+
origin: issuerOrigin,
|
692
|
+
pathname: '/oauth/authorize',
|
693
|
+
searchParams: [
|
694
|
+
['request_uri', input.request_uri],
|
695
|
+
['client_id', input.client_id],
|
696
|
+
],
|
697
|
+
});
|
698
|
+
(0, index_js_1.validateCsrfToken)(req, res, input.csrf_token, csrfCookie(input.request_uri), true);
|
699
|
+
const { deviceId } = await deviceManager.load(req, res);
|
700
|
+
const data = await server.acceptRequest(deviceId, input.request_uri, input.client_id, input.account_sub);
|
701
|
+
return await (0, send_authorize_redirect_js_1.sendAuthorizeRedirect)(res, data);
|
702
|
+
}
|
703
|
+
catch (err) {
|
704
|
+
await onError?.(req, res, err, 'Failed to accept authorization request');
|
705
|
+
if (!res.headersSent) {
|
706
|
+
await (0, send_error_page_js_1.sendErrorPage)(res, err, server.customization);
|
707
|
+
}
|
708
|
+
}
|
709
|
+
});
|
710
|
+
const rejectQuerySchema = zod_1.z.object({
|
711
|
+
csrf_token: zod_1.z.string(),
|
712
|
+
request_uri: request_uri_js_1.requestUriSchema,
|
713
|
+
client_id: client_id_js_1.clientIdSchema,
|
714
|
+
});
|
715
|
+
router.get('/oauth/authorize/reject', async function (req, res) {
|
716
|
+
try {
|
717
|
+
res.setHeader('Cache-Control', 'no-store');
|
718
|
+
(0, index_js_1.validateFetchMode)(req, res, ['navigate']);
|
719
|
+
(0, index_js_1.validateSameOrigin)(req, res, issuerOrigin);
|
720
|
+
const query = Object.fromEntries(this.url.searchParams);
|
721
|
+
const input = await rejectQuerySchema.parseAsync(query, {
|
722
|
+
path: ['query'],
|
723
|
+
});
|
724
|
+
(0, index_js_1.validateReferer)(req, res, {
|
725
|
+
origin: issuerOrigin,
|
726
|
+
pathname: '/oauth/authorize',
|
727
|
+
searchParams: [
|
728
|
+
['request_uri', input.request_uri],
|
729
|
+
['client_id', input.client_id],
|
730
|
+
],
|
731
|
+
});
|
732
|
+
(0, index_js_1.validateCsrfToken)(req, res, input.csrf_token, csrfCookie(input.request_uri), true);
|
733
|
+
const { deviceId } = await deviceManager.load(req, res);
|
734
|
+
const data = await server.rejectRequest(deviceId, input.request_uri, input.client_id);
|
735
|
+
return await (0, send_authorize_redirect_js_1.sendAuthorizeRedirect)(res, data);
|
736
|
+
}
|
737
|
+
catch (err) {
|
738
|
+
await onError?.(req, res, err, 'Failed to reject authorization request');
|
739
|
+
if (!res.headersSent) {
|
740
|
+
await (0, send_error_page_js_1.sendErrorPage)(res, err, server.customization);
|
741
|
+
}
|
742
|
+
}
|
743
|
+
});
|
744
|
+
return router;
|
745
|
+
}
|
746
|
+
}
|
747
|
+
exports.OAuthProvider = OAuthProvider;
|
748
|
+
//# sourceMappingURL=oauth-provider.js.map
|