@authup/server-core 1.0.0-beta.63 → 1.0.0-beta.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/database/data-source/options/module.d.ts +1 -0
- package/dist/adapters/database/data-source/options/module.d.ts.map +1 -1
- package/dist/adapters/database/data-source/options/module.mjs +33 -4
- package/dist/adapters/database/data-source/options/module.mjs.map +1 -1
- package/dist/adapters/database/domains/client/entity.d.ts +1 -2
- package/dist/adapters/database/domains/client/entity.d.ts.map +1 -1
- package/dist/adapters/database/domains/client/entity.mjs +7 -14
- package/dist/adapters/database/domains/client/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts +2 -1
- package/dist/adapters/database/domains/identity-provider-attribute/subscriber.d.ts.map +1 -1
- package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/session/entity.d.ts +8 -0
- package/dist/adapters/database/domains/session/entity.d.ts.map +1 -1
- package/dist/adapters/database/domains/session/entity.mjs +19 -0
- package/dist/adapters/database/domains/session/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user/entity.d.ts +1 -0
- package/dist/adapters/database/domains/user/entity.d.ts.map +1 -1
- package/dist/adapters/database/domains/user/entity.mjs +6 -0
- package/dist/adapters/database/domains/user/entity.mjs.map +1 -1
- package/dist/adapters/database/extra-attribute-repository/repository.mjs +1 -1
- package/dist/adapters/database/extra-attribute-repository/repository.mjs.map +1 -1
- package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs +4 -2
- package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs.map +1 -1
- package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs +1 -1
- package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs.map +1 -1
- package/dist/adapters/database/index.mjs +3 -3
- package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.d.ts +56 -0
- package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.d.ts.map +1 -0
- package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.mjs +105 -0
- package/dist/adapters/database/migrations/mysql/1787571998009-SessionUserAndClientColumns.mjs.map +1 -0
- package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.d.ts +56 -0
- package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.d.ts.map +1 -0
- package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.mjs +104 -0
- package/dist/adapters/database/migrations/postgres/1787571998009-SessionUserAndClientColumns.mjs.map +1 -0
- package/dist/adapters/database/subscriber/module.d.ts +6 -2
- package/dist/adapters/database/subscriber/module.d.ts.map +1 -1
- package/dist/adapters/database/subscriber/module.mjs +9 -5
- package/dist/adapters/database/subscriber/module.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/authorization/module.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/authorization/module.mjs.map +1 -1
- package/dist/adapters/http/constants.d.ts +18 -0
- package/dist/adapters/http/constants.d.ts.map +1 -0
- package/dist/adapters/http/constants.mjs +23 -0
- package/dist/adapters/http/constants.mjs.map +1 -0
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +3 -3
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts +6 -0
- package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/realm/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -0
- package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/session/module.d.ts +33 -1
- package/dist/adapters/http/controllers/entities/session/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/session/module.mjs +74 -0
- package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/index.mjs +3 -1
- package/dist/adapters/http/controllers/workflows/account/index.d.ts +1 -0
- package/dist/adapters/http/controllers/workflows/account/index.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/account/module.d.ts +25 -16
- package/dist/adapters/http/controllers/workflows/account/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/account/module.mjs +40 -17
- package/dist/adapters/http/controllers/workflows/account/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/account/types.d.ts +33 -0
- package/dist/adapters/http/controllers/workflows/account/types.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/activate/module.d.ts +8 -4
- package/dist/adapters/http/controllers/workflows/activate/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/activate/module.mjs +7 -9
- package/dist/adapters/http/controllers/workflows/activate/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/admin/index.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/admin/index.mjs +5 -0
- package/dist/adapters/http/controllers/workflows/admin/module.d.ts +30 -0
- package/dist/adapters/http/controllers/workflows/admin/module.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/admin/module.mjs +88 -0
- package/dist/adapters/http/controllers/workflows/admin/module.mjs.map +1 -0
- package/dist/adapters/http/controllers/workflows/admin/types.d.ts +14 -0
- package/dist/adapters/http/controllers/workflows/admin/types.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/auth-console.d.ts +16 -0
- package/dist/adapters/http/controllers/workflows/auth-console.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/auth-console.mjs +32 -0
- package/dist/adapters/http/controllers/workflows/auth-console.mjs.map +1 -0
- package/dist/adapters/http/controllers/workflows/authorize/module.d.ts +16 -1
- package/dist/adapters/http/controllers/workflows/authorize/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/authorize/module.mjs +40 -22
- package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/authorize/types.d.ts +5 -0
- package/dist/adapters/http/controllers/workflows/authorize/types.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/console-login/index.d.ts +3 -0
- package/dist/adapters/http/controllers/workflows/console-login/index.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/console-login/index.mjs +5 -0
- package/dist/adapters/http/controllers/workflows/console-login/module.d.ts +83 -0
- package/dist/adapters/http/controllers/workflows/console-login/module.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/console-login/module.mjs +230 -0
- package/dist/adapters/http/controllers/workflows/console-login/module.mjs.map +1 -0
- package/dist/adapters/http/controllers/workflows/console-login/types.d.ts +58 -0
- package/dist/adapters/http/controllers/workflows/console-login/types.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/index.d.ts +2 -0
- package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/index.mjs +5 -1
- package/dist/adapters/http/controllers/workflows/logout/module.d.ts +32 -3
- package/dist/adapters/http/controllers/workflows/logout/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/logout/module.mjs +48 -24
- package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/logout/types.d.ts +1 -1
- package/dist/adapters/http/controllers/workflows/logout/types.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/password-forgot/module.d.ts +8 -4
- package/dist/adapters/http/controllers/workflows/password-forgot/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs +7 -9
- package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/password-reset/module.d.ts +8 -4
- package/dist/adapters/http/controllers/workflows/password-reset/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/password-reset/module.mjs +7 -10
- package/dist/adapters/http/controllers/workflows/password-reset/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/register/module.d.ts +8 -4
- package/dist/adapters/http/controllers/workflows/register/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/register/module.mjs +7 -9
- package/dist/adapters/http/controllers/workflows/register/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/status/module.mjs +1 -1
- package/dist/adapters/http/controllers/workflows/token/module.d.ts +45 -2
- package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/token/module.mjs +102 -24
- package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
- package/dist/adapters/http/cookie/index.d.ts +2 -0
- package/dist/adapters/http/cookie/index.d.ts.map +1 -0
- package/dist/adapters/http/cookie/index.mjs +5 -0
- package/dist/adapters/http/cookie/session.d.ts +35 -0
- package/dist/adapters/http/cookie/session.d.ts.map +1 -0
- package/dist/adapters/http/cookie/session.mjs +62 -0
- package/dist/adapters/http/cookie/session.mjs.map +1 -0
- package/dist/adapters/http/index.d.ts +2 -0
- package/dist/adapters/http/index.d.ts.map +1 -1
- package/dist/adapters/http/index.mjs +20 -16
- package/dist/adapters/http/internal-client/index.d.ts +3 -0
- package/dist/adapters/http/internal-client/index.d.ts.map +1 -0
- package/dist/adapters/http/internal-client/index.mjs +5 -0
- package/dist/adapters/http/internal-client/module.d.ts +21 -0
- package/dist/adapters/http/internal-client/module.d.ts.map +1 -0
- package/dist/adapters/http/{ui/auth-console/http-client.mjs → internal-client/module.mjs} +16 -15
- package/dist/adapters/http/internal-client/module.mjs.map +1 -0
- package/dist/adapters/http/internal-client/types.d.ts +13 -0
- package/dist/adapters/http/internal-client/types.d.ts.map +1 -0
- package/dist/adapters/http/middleware/built-in/authorization/index.d.ts +1 -0
- package/dist/adapters/http/middleware/built-in/authorization/index.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/authorization/index.mjs +2 -1
- package/dist/adapters/http/middleware/built-in/authorization/issuance.d.ts +45 -0
- package/dist/adapters/http/middleware/built-in/authorization/issuance.d.ts.map +1 -0
- package/dist/adapters/http/middleware/built-in/authorization/issuance.mjs +61 -0
- package/dist/adapters/http/middleware/built-in/authorization/issuance.mjs.map +1 -0
- package/dist/adapters/http/middleware/built-in/authorization/module.d.ts +26 -2
- package/dist/adapters/http/middleware/built-in/authorization/module.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/authorization/module.mjs +67 -1
- package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/authorization/types.d.ts +21 -1
- package/dist/adapters/http/middleware/built-in/authorization/types.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/basic.d.ts +2 -2
- package/dist/adapters/http/middleware/built-in/basic.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/basic.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/cors.d.ts +8 -2
- package/dist/adapters/http/middleware/built-in/cors.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/cors.mjs +20 -3
- package/dist/adapters/http/middleware/built-in/cors.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/error.d.ts +2 -2
- package/dist/adapters/http/middleware/built-in/error.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/error.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/index.d.ts +1 -4
- package/dist/adapters/http/middleware/built-in/index.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/index.mjs +3 -4
- package/dist/adapters/http/middleware/built-in/internal-http-client.d.ts +17 -0
- package/dist/adapters/http/middleware/built-in/internal-http-client.d.ts.map +1 -0
- package/dist/adapters/http/middleware/built-in/internal-http-client.mjs +27 -0
- package/dist/adapters/http/middleware/built-in/internal-http-client.mjs.map +1 -0
- package/dist/adapters/http/middleware/built-in/logger.mjs +1 -1
- package/dist/adapters/http/middleware/built-in/logger.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/prometheus.d.ts +6 -5
- package/dist/adapters/http/middleware/built-in/prometheus.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/prometheus.mjs +3 -2
- package/dist/adapters/http/middleware/built-in/prometheus.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/rate-limit.d.ts +2 -2
- package/dist/adapters/http/middleware/built-in/rate-limit.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/rate-limit.mjs +15 -0
- package/dist/adapters/http/middleware/built-in/rate-limit.mjs.map +1 -1
- package/dist/adapters/http/middleware/index.mjs +3 -4
- package/dist/adapters/http/request/constants.d.ts +1 -1
- package/dist/adapters/http/request/constants.d.ts.map +1 -1
- package/dist/adapters/http/request/constants.mjs +1 -5
- package/dist/adapters/http/request/constants.mjs.map +1 -1
- package/dist/adapters/http/request/helpers/index.d.ts +1 -1
- package/dist/adapters/http/request/helpers/index.d.ts.map +1 -1
- package/dist/adapters/http/request/helpers/index.mjs +2 -2
- package/dist/adapters/http/request/helpers/locale.d.ts +2 -1
- package/dist/adapters/http/request/helpers/locale.d.ts.map +1 -1
- package/dist/adapters/http/request/helpers/locale.mjs +1 -1
- package/dist/adapters/http/request/helpers/locale.mjs.map +1 -1
- package/dist/adapters/http/request/helpers/same-origin.d.ts +38 -0
- package/dist/adapters/http/request/helpers/same-origin.d.ts.map +1 -0
- package/dist/adapters/http/request/helpers/same-origin.mjs +68 -0
- package/dist/adapters/http/request/helpers/same-origin.mjs.map +1 -0
- package/dist/adapters/http/request/index.mjs +2 -2
- package/dist/adapters/http/request/permission/module.mjs +1 -1
- package/dist/adapters/http/request/permission/module.mjs.map +1 -1
- package/dist/adapters/http/request/types.d.ts +1 -2
- package/dist/adapters/http/request/types.d.ts.map +1 -1
- package/dist/adapters/shared/ldap/module.d.ts.map +1 -1
- package/dist/adapters/shared/ldap/module.mjs +4 -1
- package/dist/adapters/shared/ldap/module.mjs.map +1 -1
- package/dist/app/builder.d.ts +4 -4
- package/dist/app/builder.d.ts.map +1 -1
- package/dist/app/builder.mjs +7 -4
- package/dist/app/builder.mjs.map +1 -1
- package/dist/app/factory.d.ts +10 -0
- package/dist/app/factory.d.ts.map +1 -1
- package/dist/app/factory.mjs +26 -2
- package/dist/app/factory.mjs.map +1 -1
- package/dist/app/index.mjs +17 -19
- package/dist/app/modules/authentication/module.d.ts.map +1 -1
- package/dist/app/modules/authentication/module.mjs +15 -2
- package/dist/app/modules/authentication/module.mjs.map +1 -1
- package/dist/app/modules/authentication/repositories/session.d.ts +4 -1
- package/dist/app/modules/authentication/repositories/session.d.ts.map +1 -1
- package/dist/app/modules/authentication/repositories/session.mjs +20 -3
- package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
- package/dist/app/modules/components/index.d.ts +1 -0
- package/dist/app/modules/components/index.d.ts.map +1 -1
- package/dist/app/modules/components/module.d.ts +3 -1
- package/dist/app/modules/components/module.d.ts.map +1 -1
- package/dist/app/modules/components/module.mjs +26 -7
- package/dist/app/modules/components/module.mjs.map +1 -1
- package/dist/app/modules/components/types.d.ts +11 -0
- package/dist/app/modules/components/types.d.ts.map +1 -0
- package/dist/app/modules/config/app-origins.d.ts +10 -0
- package/dist/app/modules/config/app-origins.d.ts.map +1 -0
- package/dist/app/modules/config/app-origins.mjs +21 -0
- package/dist/app/modules/config/app-origins.mjs.map +1 -0
- package/dist/app/modules/config/constants.d.ts +23 -50
- package/dist/app/modules/config/constants.d.ts.map +1 -1
- package/dist/app/modules/config/constants.mjs +34 -51
- package/dist/app/modules/config/constants.mjs.map +1 -1
- package/dist/app/modules/config/index.d.ts +2 -3
- package/dist/app/modules/config/index.d.ts.map +1 -1
- package/dist/app/modules/config/index.mjs +4 -8
- package/dist/app/modules/config/module.d.ts +2 -2
- package/dist/app/modules/config/module.d.ts.map +1 -1
- package/dist/app/modules/config/module.mjs +1 -1
- package/dist/app/modules/config/module.mjs.map +1 -1
- package/dist/app/modules/config/read.d.ts +29 -0
- package/dist/app/modules/config/read.d.ts.map +1 -0
- package/dist/app/modules/config/read.mjs +65 -0
- package/dist/app/modules/config/read.mjs.map +1 -0
- package/dist/app/modules/config/types.d.ts +30 -405
- package/dist/app/modules/config/types.d.ts.map +1 -1
- package/dist/app/modules/config/validator.d.ts.map +1 -1
- package/dist/app/modules/config/validator.mjs +3 -87
- package/dist/app/modules/config/validator.mjs.map +1 -1
- package/dist/app/modules/database/index.d.ts +1 -0
- package/dist/app/modules/database/index.d.ts.map +1 -1
- package/dist/app/modules/database/index.mjs +2 -1
- package/dist/app/modules/database/migration.d.ts +33 -0
- package/dist/app/modules/database/migration.d.ts.map +1 -0
- package/dist/app/modules/database/migration.mjs +52 -0
- package/dist/app/modules/database/migration.mjs.map +1 -0
- package/dist/app/modules/database/module.d.ts.map +1 -1
- package/dist/app/modules/database/module.mjs +12 -6
- package/dist/app/modules/database/module.mjs.map +1 -1
- package/dist/app/modules/database/repositories/client/repository.d.ts +6 -1
- package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/client/repository.mjs +21 -4
- package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/event/repository.d.ts +29 -2
- package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/event/repository.mjs +42 -24
- package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/helpers.d.ts +24 -1
- package/dist/app/modules/database/repositories/helpers.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/helpers.mjs +38 -1
- package/dist/app/modules/database/repositories/helpers.mjs.map +1 -1
- package/dist/app/modules/database/repositories/identity-provider/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs +4 -2
- package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/key/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/permission/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/policy/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/role/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/scope/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/trust-anchor/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/user/repository.d.ts +7 -2
- package/dist/app/modules/database/repositories/user/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/user/repository.mjs +21 -4
- package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
- package/dist/app/modules/http/constants.d.ts +3 -1
- package/dist/app/modules/http/constants.d.ts.map +1 -1
- package/dist/app/modules/http/constants.mjs +3 -2
- package/dist/app/modules/http/constants.mjs.map +1 -1
- package/dist/app/modules/http/module.d.ts +30 -9
- package/dist/app/modules/http/module.d.ts.map +1 -1
- package/dist/app/modules/http/module.mjs +31 -33
- package/dist/app/modules/http/module.mjs.map +1 -1
- package/dist/app/modules/http/modules/controller.d.ts +4 -3
- package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
- package/dist/app/modules/http/modules/controller.mjs +65 -36
- package/dist/app/modules/http/modules/controller.mjs.map +1 -1
- package/dist/app/modules/http/modules/middleware.d.ts +13 -22
- package/dist/app/modules/http/modules/middleware.d.ts.map +1 -1
- package/dist/app/modules/http/modules/middleware.mjs +20 -36
- package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
- package/dist/app/modules/identity/module.mjs +4 -4
- package/dist/app/modules/identity/repositories/client.mjs +4 -2
- package/dist/app/modules/identity/repositories/client.mjs.map +1 -1
- package/dist/app/modules/identity/repositories/user.mjs +4 -2
- package/dist/app/modules/identity/repositories/user.mjs.map +1 -1
- package/dist/app/modules/index.mjs +21 -23
- package/dist/app/modules/logger/module.mjs +1 -1
- package/dist/app/modules/logger/module.mjs.map +1 -1
- package/dist/app/modules/mail/module.d.ts.map +1 -1
- package/dist/app/modules/mail/module.mjs.map +1 -1
- package/dist/app/modules/oauth2/constants.d.ts +2 -1
- package/dist/app/modules/oauth2/constants.d.ts.map +1 -1
- package/dist/app/modules/oauth2/constants.mjs +1 -0
- package/dist/app/modules/oauth2/constants.mjs.map +1 -1
- package/dist/app/modules/oauth2/module.d.ts.map +1 -1
- package/dist/app/modules/oauth2/module.mjs +9 -4
- package/dist/app/modules/oauth2/module.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/client/repository.mjs +4 -2
- package/dist/app/modules/oauth2/repositories/client/repository.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/consent/repository.d.ts.map +1 -1
- package/dist/app/modules/oauth2/repositories/consent/repository.mjs +3 -2
- package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/console-login/index.d.ts +2 -0
- package/dist/app/modules/oauth2/repositories/console-login/index.d.ts.map +1 -0
- package/dist/app/modules/oauth2/repositories/console-login/index.mjs +5 -0
- package/dist/app/modules/oauth2/repositories/console-login/store.d.ts +19 -0
- package/dist/app/modules/oauth2/repositories/console-login/store.d.ts.map +1 -0
- package/dist/app/modules/oauth2/repositories/console-login/store.mjs +47 -0
- package/dist/app/modules/oauth2/repositories/console-login/store.mjs.map +1 -0
- package/dist/app/modules/oauth2/repositories/constants.d.ts +1 -0
- package/dist/app/modules/oauth2/repositories/constants.d.ts.map +1 -1
- package/dist/app/modules/oauth2/repositories/constants.mjs +1 -0
- package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/index.d.ts +1 -0
- package/dist/app/modules/oauth2/repositories/index.d.ts.map +1 -1
- package/dist/app/modules/oauth2/repositories/index.mjs +3 -1
- package/dist/app/modules/oauth2/repositories/session-token/repository.d.ts +2 -2
- package/dist/app/modules/oauth2/repositories/session-token/repository.d.ts.map +1 -1
- package/dist/app/modules/oauth2/repositories/session-token/repository.mjs +5 -3
- package/dist/app/modules/oauth2/repositories/session-token/repository.mjs.map +1 -1
- package/dist/app/modules/provisioning/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/module.mjs +5 -6
- package/dist/app/modules/provisioning/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/composite/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/sources/composite/module.mjs +2 -1
- package/dist/app/modules/provisioning/sources/composite/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/default/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/sources/default/module.mjs +2 -1
- package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
- package/dist/app/modules/runtime/module.d.ts.map +1 -1
- package/dist/app/modules/runtime/module.mjs +2 -1
- package/dist/app/modules/runtime/module.mjs.map +1 -1
- package/dist/app/types.d.ts +16 -0
- package/dist/app/types.d.ts.map +1 -1
- package/dist/cli/commands/config.d.ts +40 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.mjs +65 -0
- package/dist/cli/commands/config.mjs.map +1 -0
- package/dist/cli/commands/healthcheck.d.ts +3 -2
- package/dist/cli/commands/healthcheck.d.ts.map +1 -1
- package/dist/cli/commands/healthcheck.mjs +6 -3
- package/dist/cli/commands/healthcheck.mjs.map +1 -1
- package/dist/cli/commands/index.d.ts +3 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.mjs +3 -1
- package/dist/cli/commands/migration.d.ts +3 -10
- package/dist/cli/commands/migration.d.ts.map +1 -1
- package/dist/cli/commands/migration.mjs +17 -9
- package/dist/cli/commands/migration.mjs.map +1 -1
- package/dist/cli/commands/shutdown.d.ts +16 -0
- package/dist/cli/commands/shutdown.d.ts.map +1 -0
- package/dist/cli/commands/shutdown.mjs +41 -0
- package/dist/cli/commands/shutdown.mjs.map +1 -0
- package/dist/cli/commands/start.d.ts +3 -2
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.mjs +3 -21
- package/dist/cli/commands/start.mjs.map +1 -1
- package/dist/cli/commands/types.d.ts.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/module.d.ts +0 -2
- package/dist/cli/module.d.ts.map +1 -1
- package/dist/cli/module.mjs +4 -3
- package/dist/cli/module.mjs.map +1 -1
- package/dist/components/oauth2-cleaner/module.d.ts +2 -2
- package/dist/components/oauth2-cleaner/module.d.ts.map +1 -1
- package/dist/components/oauth2-cleaner/module.mjs +10 -7
- package/dist/components/oauth2-cleaner/module.mjs.map +1 -1
- package/dist/core/authentication/index.mjs +2 -1
- package/dist/core/authentication/session/constants.d.ts +10 -0
- package/dist/core/authentication/session/constants.d.ts.map +1 -0
- package/dist/core/authentication/session/constants.mjs +16 -0
- package/dist/core/authentication/session/constants.mjs.map +1 -0
- package/dist/core/authentication/session/index.d.ts +1 -0
- package/dist/core/authentication/session/index.d.ts.map +1 -1
- package/dist/core/authentication/session/index.mjs +2 -1
- package/dist/core/authentication/session/module.d.ts +2 -1
- package/dist/core/authentication/session/module.d.ts.map +1 -1
- package/dist/core/authentication/session/module.mjs +7 -1
- package/dist/core/authentication/session/module.mjs.map +1 -1
- package/dist/core/authentication/session/types.d.ts +70 -1
- package/dist/core/authentication/session/types.d.ts.map +1 -1
- package/dist/core/authentication/session/types.mjs.map +1 -1
- package/dist/core/entities/client/schema.d.ts.map +1 -1
- package/dist/core/entities/client/schema.mjs +1 -2
- package/dist/core/entities/client/schema.mjs.map +1 -1
- package/dist/core/entities/client/service.d.ts.map +1 -1
- package/dist/core/entities/client/service.mjs +15 -1
- package/dist/core/entities/client/service.mjs.map +1 -1
- package/dist/core/entities/client/system-clients.d.ts +0 -5
- package/dist/core/entities/client/system-clients.d.ts.map +1 -1
- package/dist/core/entities/client/system-clients.mjs +0 -6
- package/dist/core/entities/client/system-clients.mjs.map +1 -1
- package/dist/core/entities/client/types.d.ts +12 -0
- package/dist/core/entities/client/types.d.ts.map +1 -1
- package/dist/core/entities/client-permission/service.mjs +1 -1
- package/dist/core/entities/client-permission/service.mjs.map +1 -1
- package/dist/core/entities/event/constants.d.ts +1 -6
- package/dist/core/entities/event/constants.d.ts.map +1 -1
- package/dist/core/entities/event/constants.mjs +1 -5
- package/dist/core/entities/event/constants.mjs.map +1 -1
- package/dist/core/entities/event/entity-event-handler.d.ts.map +1 -1
- package/dist/core/entities/event/entity-event-handler.mjs +3 -2
- package/dist/core/entities/event/entity-event-handler.mjs.map +1 -1
- package/dist/core/entities/event/service.d.ts.map +1 -1
- package/dist/core/entities/event/service.mjs +3 -3
- package/dist/core/entities/event/service.mjs.map +1 -1
- package/dist/core/entities/event/types.d.ts +15 -1
- package/dist/core/entities/event/types.d.ts.map +1 -1
- package/dist/core/entities/permission/service.mjs +1 -2
- package/dist/core/entities/permission/service.mjs.map +1 -1
- package/dist/core/entities/role-permission/service.mjs +1 -1
- package/dist/core/entities/role-permission/service.mjs.map +1 -1
- package/dist/core/entities/session/service.d.ts +13 -1
- package/dist/core/entities/session/service.d.ts.map +1 -1
- package/dist/core/entities/session/service.mjs +19 -16
- package/dist/core/entities/session/service.mjs.map +1 -1
- package/dist/core/entities/user/schema.d.ts.map +1 -1
- package/dist/core/entities/user/schema.mjs +1 -0
- package/dist/core/entities/user/schema.mjs.map +1 -1
- package/dist/core/entities/user/service.d.ts.map +1 -1
- package/dist/core/entities/user/service.mjs +21 -1
- package/dist/core/entities/user/service.mjs.map +1 -1
- package/dist/core/entities/user/types.d.ts +12 -0
- package/dist/core/entities/user/types.d.ts.map +1 -1
- package/dist/core/entities/user-permission/service.mjs +1 -1
- package/dist/core/entities/user-permission/service.mjs.map +1 -1
- package/dist/core/identity/permission/junction-grant.mjs +1 -1
- package/dist/core/identity/permission/junction-grant.mjs.map +1 -1
- package/dist/core/identity/provider/account/module.mjs +1 -1
- package/dist/core/identity/provider/account/module.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs +1 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs.map +1 -1
- package/dist/core/identity/registration/service.d.ts.map +1 -1
- package/dist/core/identity/registration/service.mjs +2 -1
- package/dist/core/identity/registration/service.mjs.map +1 -1
- package/dist/core/index.mjs +11 -3
- package/dist/core/oauth2/authorization/helpers.d.ts +14 -0
- package/dist/core/oauth2/authorization/helpers.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/helpers.mjs +9 -1
- package/dist/core/oauth2/authorization/helpers.mjs.map +1 -1
- package/dist/core/oauth2/authorization/index.mjs +2 -2
- package/dist/core/oauth2/authorization/module.mjs +1 -1
- package/dist/core/oauth2/authorization/module.mjs.map +1 -1
- package/dist/core/oauth2/backchannel-logout/constants.d.ts +16 -0
- package/dist/core/oauth2/backchannel-logout/constants.d.ts.map +1 -0
- package/dist/core/oauth2/backchannel-logout/constants.mjs +20 -0
- package/dist/core/oauth2/backchannel-logout/constants.mjs.map +1 -0
- package/dist/core/oauth2/backchannel-logout/index.d.ts +4 -0
- package/dist/core/oauth2/backchannel-logout/index.d.ts.map +1 -0
- package/dist/core/oauth2/backchannel-logout/index.mjs +6 -0
- package/dist/core/oauth2/backchannel-logout/module.d.ts +26 -0
- package/dist/core/oauth2/backchannel-logout/module.d.ts.map +1 -0
- package/dist/core/oauth2/backchannel-logout/module.mjs +78 -0
- package/dist/core/oauth2/backchannel-logout/module.mjs.map +1 -0
- package/dist/core/oauth2/backchannel-logout/types.d.ts +29 -0
- package/dist/core/oauth2/backchannel-logout/types.d.ts.map +1 -0
- package/dist/core/oauth2/console-login/constants.d.ts +19 -0
- package/dist/core/oauth2/console-login/constants.d.ts.map +1 -0
- package/dist/core/oauth2/console-login/constants.mjs +24 -0
- package/dist/core/oauth2/console-login/constants.mjs.map +1 -0
- package/dist/core/oauth2/console-login/index.d.ts +3 -0
- package/dist/core/oauth2/console-login/index.d.ts.map +1 -0
- package/dist/core/oauth2/console-login/index.mjs +5 -0
- package/dist/core/oauth2/console-login/types.d.ts +53 -0
- package/dist/core/oauth2/console-login/types.d.ts.map +1 -0
- package/dist/core/oauth2/end-session/service.mjs +1 -1
- package/dist/core/oauth2/end-session/service.mjs.map +1 -1
- package/dist/core/oauth2/federated-login/module.mjs +3 -3
- package/dist/core/oauth2/federated-login/module.mjs.map +1 -1
- package/dist/core/oauth2/index.d.ts +4 -0
- package/dist/core/oauth2/index.d.ts.map +1 -1
- package/dist/core/oauth2/index.mjs +13 -3
- package/dist/core/oauth2/introspection/index.d.ts +3 -0
- package/dist/core/oauth2/introspection/index.d.ts.map +1 -0
- package/dist/core/oauth2/introspection/index.mjs +5 -0
- package/dist/core/oauth2/introspection/module.d.ts +14 -0
- package/dist/core/oauth2/introspection/module.d.ts.map +1 -0
- package/dist/core/oauth2/introspection/module.mjs +49 -0
- package/dist/core/oauth2/introspection/module.mjs.map +1 -0
- package/dist/core/oauth2/introspection/types.d.ts +45 -0
- package/dist/core/oauth2/introspection/types.d.ts.map +1 -0
- package/dist/core/oauth2/introspection/types.mjs +4 -0
- package/dist/core/oauth2/openid/claims.d.ts +20 -2
- package/dist/core/oauth2/openid/claims.d.ts.map +1 -1
- package/dist/core/oauth2/openid/claims.mjs +18 -4
- package/dist/core/oauth2/openid/claims.mjs.map +1 -1
- package/dist/core/oauth2/session-credential/constants.d.ts +30 -0
- package/dist/core/oauth2/session-credential/constants.d.ts.map +1 -0
- package/dist/core/oauth2/session-credential/constants.mjs +34 -0
- package/dist/core/oauth2/session-credential/constants.mjs.map +1 -0
- package/dist/core/oauth2/session-credential/index.d.ts +3 -0
- package/dist/core/oauth2/session-credential/index.d.ts.map +1 -0
- package/dist/core/oauth2/session-credential/index.mjs +6 -0
- package/dist/core/oauth2/session-credential/module.d.ts +31 -0
- package/dist/core/oauth2/session-credential/module.d.ts.map +1 -0
- package/dist/core/oauth2/session-credential/module.mjs +43 -0
- package/dist/core/oauth2/session-credential/module.mjs.map +1 -0
- package/dist/core/oauth2/session-token/constants.d.ts +10 -0
- package/dist/core/oauth2/session-token/constants.d.ts.map +1 -0
- package/dist/core/oauth2/session-token/constants.mjs +16 -0
- package/dist/core/oauth2/session-token/constants.mjs.map +1 -0
- package/dist/core/oauth2/session-token/index.d.ts +1 -0
- package/dist/core/oauth2/session-token/index.d.ts.map +1 -1
- package/dist/core/oauth2/session-token/index.mjs +2 -1
- package/dist/core/oauth2/session-token/types.d.ts +13 -2
- package/dist/core/oauth2/session-token/types.d.ts.map +1 -1
- package/dist/core/provisioning/merge/module.mjs +5 -3
- package/dist/core/provisioning/merge/module.mjs.map +1 -1
- package/dist/core/query/module.mjs +1 -1
- package/dist/core/query/module.mjs.map +1 -1
- package/dist/core/security/policy/evaluator.mjs +1 -1
- package/dist/core/security/policy/evaluator.mjs.map +1 -1
- package/dist/index.mjs +62 -59
- package/dist/path.mjs +1 -1
- package/dist/swagger.json +466 -104
- package/dist/utils/error.d.ts +6 -0
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.mjs +6 -2
- package/dist/utils/error.mjs.map +1 -1
- package/dist/utils/index.mjs +2 -2
- package/package.json +31 -25
- package/dist/adapters/http/middleware/built-in/assets.d.ts +0 -11
- package/dist/adapters/http/middleware/built-in/assets.d.ts.map +0 -1
- package/dist/adapters/http/middleware/built-in/assets.mjs +0 -91
- package/dist/adapters/http/middleware/built-in/assets.mjs.map +0 -1
- package/dist/adapters/http/middleware/built-in/theme.d.ts +0 -15
- package/dist/adapters/http/middleware/built-in/theme.d.ts.map +0 -1
- package/dist/adapters/http/middleware/built-in/theme.mjs +0 -27
- package/dist/adapters/http/middleware/built-in/theme.mjs.map +0 -1
- package/dist/adapters/http/middleware/built-in/types.d.ts +0 -14
- package/dist/adapters/http/middleware/built-in/types.d.ts.map +0 -1
- package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts +0 -15
- package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts.map +0 -1
- package/dist/adapters/http/middleware/built-in/ui-http-client.mjs +0 -25
- package/dist/adapters/http/middleware/built-in/ui-http-client.mjs.map +0 -1
- package/dist/adapters/http/request/helpers/redirect.d.ts +0 -14
- package/dist/adapters/http/request/helpers/redirect.d.ts.map +0 -1
- package/dist/adapters/http/request/helpers/redirect.mjs +0 -36
- package/dist/adapters/http/request/helpers/redirect.mjs.map +0 -1
- package/dist/adapters/http/ui/account-console/index.d.ts +0 -4
- package/dist/adapters/http/ui/account-console/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/account-console/index.mjs +0 -6
- package/dist/adapters/http/ui/account-console/module.d.ts +0 -28
- package/dist/adapters/http/ui/account-console/module.d.ts.map +0 -1
- package/dist/adapters/http/ui/account-console/module.mjs +0 -80
- package/dist/adapters/http/ui/account-console/module.mjs.map +0 -1
- package/dist/adapters/http/ui/account-console/ref.d.ts +0 -30
- package/dist/adapters/http/ui/account-console/ref.d.ts.map +0 -1
- package/dist/adapters/http/ui/account-console/ref.mjs +0 -50
- package/dist/adapters/http/ui/account-console/ref.mjs.map +0 -1
- package/dist/adapters/http/ui/account-console/types.d.ts +0 -11
- package/dist/adapters/http/ui/account-console/types.d.ts.map +0 -1
- package/dist/adapters/http/ui/auth-console/http-client.d.ts +0 -22
- package/dist/adapters/http/ui/auth-console/http-client.d.ts.map +0 -1
- package/dist/adapters/http/ui/auth-console/http-client.mjs.map +0 -1
- package/dist/adapters/http/ui/auth-console/index.d.ts +0 -6
- package/dist/adapters/http/ui/auth-console/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/auth-console/index.mjs +0 -8
- package/dist/adapters/http/ui/auth-console/module.d.ts +0 -4
- package/dist/adapters/http/ui/auth-console/module.d.ts.map +0 -1
- package/dist/adapters/http/ui/auth-console/module.mjs +0 -73
- package/dist/adapters/http/ui/auth-console/module.mjs.map +0 -1
- package/dist/adapters/http/ui/auth-console/resolve.d.ts +0 -21
- package/dist/adapters/http/ui/auth-console/resolve.d.ts.map +0 -1
- package/dist/adapters/http/ui/auth-console/resolve.mjs +0 -53
- package/dist/adapters/http/ui/auth-console/resolve.mjs.map +0 -1
- package/dist/adapters/http/ui/auth-console/serve.d.ts +0 -9
- package/dist/adapters/http/ui/auth-console/serve.d.ts.map +0 -1
- package/dist/adapters/http/ui/auth-console/serve.mjs +0 -35
- package/dist/adapters/http/ui/auth-console/serve.mjs.map +0 -1
- package/dist/adapters/http/ui/auth-console/types.d.ts +0 -26
- package/dist/adapters/http/ui/auth-console/types.d.ts.map +0 -1
- package/dist/adapters/http/ui/console-packages/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/console-packages/index.mjs +0 -5
- package/dist/adapters/http/ui/console-packages/module.d.ts +0 -33
- package/dist/adapters/http/ui/console-packages/module.d.ts.map +0 -1
- package/dist/adapters/http/ui/console-packages/module.mjs +0 -70
- package/dist/adapters/http/ui/console-packages/module.mjs.map +0 -1
- package/dist/adapters/http/ui/console-packages/types.d.ts +0 -12
- package/dist/adapters/http/ui/console-packages/types.d.ts.map +0 -1
- package/dist/adapters/http/ui/index.d.ts +0 -6
- package/dist/adapters/http/ui/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/index.mjs +0 -25
- package/dist/adapters/http/ui/shared/html.d.ts +0 -76
- package/dist/adapters/http/ui/shared/html.d.ts.map +0 -1
- package/dist/adapters/http/ui/shared/html.mjs +0 -104
- package/dist/adapters/http/ui/shared/html.mjs.map +0 -1
- package/dist/adapters/http/ui/shared/index.d.ts +0 -2
- package/dist/adapters/http/ui/shared/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/shared/index.mjs +0 -5
- package/dist/adapters/http/ui/theme/apply.d.ts +0 -12
- package/dist/adapters/http/ui/theme/apply.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/apply.mjs +0 -29
- package/dist/adapters/http/ui/theme/apply.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/assets.d.ts +0 -20
- package/dist/adapters/http/ui/theme/assets.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/assets.mjs +0 -86
- package/dist/adapters/http/ui/theme/assets.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/constants.d.ts +0 -16
- package/dist/adapters/http/ui/theme/constants.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/constants.mjs +0 -20
- package/dist/adapters/http/ui/theme/constants.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/contract/constants.d.ts +0 -120
- package/dist/adapters/http/ui/theme/contract/constants.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/contract/constants.mjs +0 -136
- package/dist/adapters/http/ui/theme/contract/constants.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/contract/head.d.ts +0 -12
- package/dist/adapters/http/ui/theme/contract/head.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/contract/head.mjs +0 -61
- package/dist/adapters/http/ui/theme/contract/head.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/contract/index.d.ts +0 -6
- package/dist/adapters/http/ui/theme/contract/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/contract/index.mjs +0 -8
- package/dist/adapters/http/ui/theme/contract/manifest.d.ts +0 -25
- package/dist/adapters/http/ui/theme/contract/manifest.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/contract/manifest.mjs +0 -77
- package/dist/adapters/http/ui/theme/contract/manifest.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/contract/types.d.ts +0 -26
- package/dist/adapters/http/ui/theme/contract/types.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/contract/utils.d.ts +0 -11
- package/dist/adapters/http/ui/theme/contract/utils.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/contract/utils.mjs +0 -22
- package/dist/adapters/http/ui/theme/contract/utils.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/index.d.ts +0 -7
- package/dist/adapters/http/ui/theme/index.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/index.mjs +0 -13
- package/dist/adapters/http/ui/theme/module.d.ts +0 -79
- package/dist/adapters/http/ui/theme/module.d.ts.map +0 -1
- package/dist/adapters/http/ui/theme/module.mjs +0 -206
- package/dist/adapters/http/ui/theme/module.mjs.map +0 -1
- package/dist/adapters/http/ui/theme/types.d.ts +0 -42
- package/dist/adapters/http/ui/theme/types.d.ts.map +0 -1
- package/dist/app/modules/config/helpers.d.ts +0 -9
- package/dist/app/modules/config/helpers.d.ts.map +0 -1
- package/dist/app/modules/config/helpers.mjs +0 -22
- package/dist/app/modules/config/helpers.mjs.map +0 -1
- package/dist/app/modules/config/normalize.d.ts +0 -3
- package/dist/app/modules/config/normalize.d.ts.map +0 -1
- package/dist/app/modules/config/normalize.mjs +0 -117
- package/dist/app/modules/config/normalize.mjs.map +0 -1
- package/dist/app/modules/config/origins.d.ts +0 -25
- package/dist/app/modules/config/origins.d.ts.map +0 -1
- package/dist/app/modules/config/origins.mjs +0 -46
- package/dist/app/modules/config/origins.mjs.map +0 -1
- package/dist/app/modules/config/read/env.d.ts +0 -3
- package/dist/app/modules/config/read/env.d.ts.map +0 -1
- package/dist/app/modules/config/read/env.mjs +0 -139
- package/dist/app/modules/config/read/env.mjs.map +0 -1
- package/dist/app/modules/config/read/fs.d.ts +0 -3
- package/dist/app/modules/config/read/fs.d.ts.map +0 -1
- package/dist/app/modules/config/read/fs.mjs +0 -60
- package/dist/app/modules/config/read/fs.mjs.map +0 -1
- package/dist/app/modules/config/read/index.d.ts +0 -5
- package/dist/app/modules/config/read/index.d.ts.map +0 -1
- package/dist/app/modules/config/read/index.mjs +0 -7
- package/dist/app/modules/config/read/module.d.ts +0 -4
- package/dist/app/modules/config/read/module.d.ts.map +0 -1
- package/dist/app/modules/config/read/module.mjs +0 -29
- package/dist/app/modules/config/read/module.mjs.map +0 -1
- package/dist/app/modules/config/read/types.d.ts +0 -9
- package/dist/app/modules/config/read/types.d.ts.map +0 -1
- package/dist/app/modules/config/trust-proxy.d.ts +0 -28
- package/dist/app/modules/config/trust-proxy.d.ts.map +0 -1
- package/dist/app/modules/config/trust-proxy.mjs +0 -64
- package/dist/app/modules/config/trust-proxy.mjs.map +0 -1
- package/dist/cli/config.d.ts +0 -18
- package/dist/cli/config.d.ts.map +0 -1
- package/dist/cli/config.mjs +0 -34
- package/dist/cli/config.mjs.map +0 -1
- package/dist/cli/types.d.ts.map +0 -1
- package/dist/utils/host.d.ts +0 -2
- package/dist/utils/host.d.ts.map +0 -1
- package/dist/utils/host.mjs +0 -12
- package/dist/utils/host.mjs.map +0 -1
- /package/dist/adapters/http/{middleware/built-in → controllers/workflows/account}/types.mjs +0 -0
- /package/dist/adapters/http/{ui/console-packages → controllers/workflows/admin}/index.d.ts +0 -0
- /package/dist/adapters/http/{ui/account-console → controllers/workflows/admin}/types.mjs +0 -0
- /package/dist/adapters/http/{ui/auth-console → controllers/workflows/console-login}/types.mjs +0 -0
- /package/dist/adapters/http/{ui/console-packages → internal-client}/types.mjs +0 -0
- /package/dist/{adapters/http/ui/theme/contract → app/modules/components}/types.mjs +0 -0
- /package/dist/cli/{types.d.ts → commands/types.d.ts} +0 -0
- /package/dist/{adapters/http/ui/theme → cli/commands}/types.mjs +0 -0
- /package/dist/{app/modules/config/read → core/oauth2/backchannel-logout}/types.mjs +0 -0
- /package/dist/{cli → core/oauth2/console-login}/types.mjs +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/console-login/index.ts"],"names":[],"mappings":"AAOA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a pending console login holds while the browser is away at
|
|
3
|
+
* `/authorize` (plan 088). Only what the redemption needs, and nothing a
|
|
4
|
+
* leaked entry would make redeemable on its own: the browser additionally
|
|
5
|
+
* has to present the login cookie naming it.
|
|
6
|
+
*/
|
|
7
|
+
export type ConsoleLoginPending = {
|
|
8
|
+
/**
|
|
9
|
+
* The `state` the authorize request carried. Validated against the
|
|
10
|
+
* callback's own `state` BEFORE the entry is consumed, so a second tab's
|
|
11
|
+
* callback cannot burn the first tab's login.
|
|
12
|
+
*/
|
|
13
|
+
state: string;
|
|
14
|
+
/**
|
|
15
|
+
* The PKCE verifier the token exchange presents. The console client is
|
|
16
|
+
* public, so a code cannot be redeemed without it.
|
|
17
|
+
*/
|
|
18
|
+
codeVerifier: string;
|
|
19
|
+
/**
|
|
20
|
+
* The `redirect_uri` the authorize request carried. RFC 6749 §4.1.3
|
|
21
|
+
* requires the token request to repeat it verbatim, and the verifier
|
|
22
|
+
* compares the raw stored string, so it is replayed from here rather than
|
|
23
|
+
* rebuilt from the callback URL.
|
|
24
|
+
*/
|
|
25
|
+
redirectUri: string;
|
|
26
|
+
/**
|
|
27
|
+
* The realm the login was started in. Required: the console client is
|
|
28
|
+
* identified by NAME, and a name-identified client needs a realm hint at
|
|
29
|
+
* `/authorize` and at `/token` alike (client names are unique per realm,
|
|
30
|
+
* and every realm carries the same-named system clients).
|
|
31
|
+
*/
|
|
32
|
+
realmId: string;
|
|
33
|
+
};
|
|
34
|
+
export interface IConsoleLoginStore {
|
|
35
|
+
/**
|
|
36
|
+
* @returns the id of the pending login
|
|
37
|
+
*/
|
|
38
|
+
save(data: ConsoleLoginPending): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Reads WITHOUT dropping, so the callback can check `state` before it
|
|
41
|
+
* spends anything. One browser holds one login cookie, so a second tab's
|
|
42
|
+
* kick overwrites the first tab's id: consuming before the check would let
|
|
43
|
+
* tab A's stale callback burn tab B's live login. A read alone redeems
|
|
44
|
+
* nothing: the entry still has to be consumed, and the code still has to
|
|
45
|
+
* match the verifier it holds.
|
|
46
|
+
*/
|
|
47
|
+
find(id: string): Promise<ConsoleLoginPending | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Reads and DROPS it. Single use: one pending login redeems once.
|
|
50
|
+
*/
|
|
51
|
+
consume(id: string): Promise<ConsoleLoginPending | null>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/console-login/types.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAC9B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAC/B;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,mBAAmB,GAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAEvD;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;CAC7D"}
|
|
@@ -53,7 +53,7 @@ var OAuth2EndSessionService = class {
|
|
|
53
53
|
}
|
|
54
54
|
if (hintVerified && data.client_id) {
|
|
55
55
|
const expected = isUUID(data.client_id) ? data.client_id : client?.id;
|
|
56
|
-
if (audiences.length === 0 || !
|
|
56
|
+
if (!expected || audiences.length === 0 || !audiences.includes(expected)) {
|
|
57
57
|
hintVerified = false;
|
|
58
58
|
sub = void 0;
|
|
59
59
|
subKind = void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["isSimpleURLMatch","isUUID","EventName","EventRefType","EventScope","OAuth2TokenKind","OAuth2EndSessionService","tokenVerifier","sessionManager","clientRepository","realmRepository","eventService","hintGracePeriod","ctx","verify","data","hintVerified","sub","subKind","sessionId","hintRealmId","audiences","id_token_hint","payload","ignoreExpiry","skipActiveCheck","kind","ID_TOKEN","isWithinHintGraceWindow","sub_kind","sid","session_id","undefined","realm_id","aud","Array","isArray","filter","entry","clientId","client_id","length","client","realmKey","realm_name","realm","resolve","findOneByIdOrName","id","expected","includes","clientName","redirectUri","name","post_logout_redirect_uri","isValidPostLogoutRedirect","postLogoutRedirectUri","state","revoke","session","findOneById","record","scope","OAUTH2","LOGOUT","refType","SESSION","refId","actorType","actorId","realmId","exp","nowSeconds","Math","floor","Date","now","registered","candidate","parsed","URL","protocol","username","password","split"],"sources":["../../../../src/core/oauth2/end-session/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isSimpleURLMatch, isUUID } from '@authup/kit';\nimport type { Client, IdentityType } from '@authup/core-kit';\nimport { EventName, EventRefType, EventScope } from '@authup/core-kit';\nimport type { OAuth2TokenPayload } from '@authup/specs';\nimport { OAuth2TokenKind } from '@authup/specs';\nimport type { IEventService, IRealmRepository } from '../../entities/index.ts';\nimport type { ISessionManager } from '../../authentication/index.ts';\nimport type { IOAuth2ClientRepository } from '../client/index.ts';\nimport type { IOAuth2TokenVerifier } from '../token/index.ts';\nimport type {\n IOAuth2EndSessionService,\n OAuth2EndSessionRequest,\n OAuth2EndSessionResult,\n OAuth2EndSessionServiceContext,\n} from './types.ts';\n\nexport class OAuth2EndSessionService implements IOAuth2EndSessionService {\n protected tokenVerifier: IOAuth2TokenVerifier;\n\n protected sessionManager: ISessionManager;\n\n protected clientRepository: IOAuth2ClientRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected eventService?: IEventService;\n\n protected hintGracePeriod: number;\n\n constructor(ctx: OAuth2EndSessionServiceContext) {\n this.tokenVerifier = ctx.tokenVerifier;\n this.sessionManager = ctx.sessionManager;\n this.clientRepository = ctx.clientRepository;\n this.realmRepository = ctx.realmRepository;\n this.eventService = ctx.eventService;\n this.hintGracePeriod = ctx.hintGracePeriod ?? 0;\n }\n\n async verify(data: OAuth2EndSessionRequest): Promise<OAuth2EndSessionResult> {\n let hintVerified = false;\n let sub: string | undefined;\n let subKind: string | undefined;\n let sessionId: string | undefined;\n let hintRealmId: string | undefined;\n let audiences: string[] = [];\n\n if (data.id_token_hint) {\n try {\n // Signature + kind are the anchors; exp is skipped (a logout hint\n // is routinely expired) and the cache blocklist is irrelevant.\n const payload = await this.tokenVerifier.verify(data.id_token_hint, {\n ignoreExpiry: true,\n skipActiveCheck: true,\n });\n\n // MUST be an id_token — access/refresh tokens also carry\n // session_id, so accepting them would let a leaked access token\n // act as a logout weapon.\n if (payload.kind === OAuth2TokenKind.ID_TOKEN && this.isWithinHintGraceWindow(payload)) {\n hintVerified = true;\n sub = payload.sub;\n subKind = payload.sub_kind;\n sessionId = payload.sid ?? payload.session_id ?? undefined;\n hintRealmId = payload.realm_id ?? undefined;\n // aud may be a single string or an array (JWT spec).\n const { aud } = payload;\n if (Array.isArray(aud)) {\n audiences = aud.filter((entry): entry is string => typeof entry === 'string');\n } else if (typeof aud === 'string') {\n audiences = [aud];\n }\n }\n } catch {\n // forged / unverifiable hint → stays unverified (no revoke)\n }\n }\n\n // Resolve a single client for the aud cross-check and redirect\n // validation: the request's client_id, else the hint's sole audience\n // (ambiguous for a multi-aud hint).\n const clientId = data.client_id ?? (audiences.length === 1 ? audiences[0] : undefined);\n\n let client: Client | null = null;\n if (clientId) {\n // Scope a name-identified client to the request's realm hint; a\n // VERIFIED hint's own realm claim serves as fallback (claims from an\n // unverified hint are never trusted). No master fallback here\n // (unlike /token): a bogus hint must NOT silently resolve a\n // same-named client in master → null realm.\n const realmKey = data.realm_id ?? data.realm_name ?? (hintVerified ? hintRealmId : undefined);\n const realm = await this.realmRepository.resolve(realmKey, false);\n\n // Fail closed instead of dropping the realm predicate: a supplied\n // realm key that does not resolve never degrades to an unscoped\n // lookup, and a NAME-form client_id without any realm key is\n // ambiguous (client names are only unique per realm, and every\n // realm carries the same-named system clients — same rule as the\n // /authorize verifier). A UUID is globally unique and needs no\n // scope; the sole-aud-derived clientId is always a UUID.\n if (realm) {\n client = await this.clientRepository.findOneByIdOrName(clientId, realm.id);\n } else if (!realmKey && isUUID(clientId)) {\n client = await this.clientRepository.findOneByIdOrName(clientId);\n }\n }\n\n // aud/client_id cross-check: when the request supplies a client_id on a\n // verified hint, it MUST denote one of the hint's audiences. The aud is\n // the client UUID, so a name-form client_id is compared via its resolved\n // client's id. Fail closed: an aud-less hint, or a name that did not\n // resolve, counts as unverified.\n if (hintVerified && data.client_id) {\n const expected = isUUID(data.client_id) ? data.client_id : client?.id;\n if (audiences.length === 0 || !expected || !audiences.includes(expected)) {\n hintVerified = false;\n sub = undefined;\n subKind = undefined;\n sessionId = undefined;\n }\n }\n\n let clientName: string | undefined;\n let redirectUri: string | undefined;\n\n // Redirect validation is independent of hint verification — the\n // click-gated confirm page (unverified hint / hint-less request) still\n // honors a registered post-logout redirect.\n if (client) {\n clientName = client.name;\n if (\n data.post_logout_redirect_uri &&\n this.isValidPostLogoutRedirect(client.postLogoutRedirectUri, data.post_logout_redirect_uri)\n ) {\n redirectUri = data.post_logout_redirect_uri;\n }\n }\n\n return {\n hintVerified,\n ...(hintVerified ? {\n sub,\n subKind,\n sessionId,\n } : {}),\n ...(clientId ? { clientId } : {}),\n ...(clientName ? { clientName } : {}),\n ...(redirectUri ? { redirectUri, ...(data.state ? { state: data.state } : {}) } : {}),\n };\n }\n\n async revoke(sessionId: string, sub: string, subKind: string): Promise<boolean> {\n const session = await this.sessionManager.findOneById(sessionId);\n if (!session) {\n return false;\n }\n\n // Never revoke a session that does not belong to the hint's subject.\n if (session.sub !== sub || session.subKind !== subKind) {\n return false;\n }\n\n await this.sessionManager.revoke(sessionId);\n\n await this.eventService?.record({\n scope: EventScope.OAUTH2,\n name: EventName.LOGOUT,\n refType: EventRefType.SESSION,\n refId: sessionId,\n sessionId,\n actorType: session.subKind as `${IdentityType}`,\n actorId: session.sub,\n realmId: session.realmId,\n });\n\n return true;\n }\n\n /**\n * With a positive `hintGracePeriod`, an expired hint is honored only within\n * the window past `exp` — beyond it a leaked id_token stops being a\n * replayable remote logout (the hint counts as unverified; the click-gated\n * confirm page still works). 0 keeps spec/Keycloak parity: any expired hint.\n */\n protected isWithinHintGraceWindow(payload: OAuth2TokenPayload): boolean {\n if (this.hintGracePeriod <= 0) {\n return true;\n }\n\n // a bounded window without an exp claim to judge against fails closed\n if (typeof payload.exp !== 'number') {\n return false;\n }\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n return nowSeconds - payload.exp <= this.hintGracePeriod;\n }\n\n /**\n * A post-logout redirect is honored only when it is an absolute http(s) URL\n * that matches a registered client redirect pattern (defense against open\n * redirects to attacker-controlled URLs).\n */\n protected isValidPostLogoutRedirect(\n registered: string | null | undefined,\n candidate: string,\n ): boolean {\n let parsed: URL;\n try {\n parsed = new URL(candidate);\n } catch {\n return false;\n }\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return false;\n }\n\n // The matcher canonicalizes the candidate (userinfo dropped) while the\n // redirect is built from the raw value, so a credential blob would\n // ride the Location header (#3455).\n if (parsed.username || parsed.password) {\n return false;\n }\n\n if (!registered) {\n return false;\n }\n\n // isSimpleURLMatch, never isSimpleMatch: matched against the raw\n // string, a `*` in a registered pattern's host absorbs a `?`, `#` or\n // `\\`, which would turn this endpoint into a server-issued open\n // redirect carrying `state`.\n return isSimpleURLMatch(candidate, registered.split(','));\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["isSimpleURLMatch","isUUID","EventName","EventRefType","EventScope","OAuth2TokenKind","OAuth2EndSessionService","tokenVerifier","sessionManager","clientRepository","realmRepository","eventService","hintGracePeriod","ctx","verify","data","hintVerified","sub","subKind","sessionId","hintRealmId","audiences","id_token_hint","payload","ignoreExpiry","skipActiveCheck","kind","ID_TOKEN","isWithinHintGraceWindow","sub_kind","sid","session_id","undefined","realm_id","aud","Array","isArray","filter","entry","clientId","client_id","length","client","realmKey","realm_name","realm","resolve","findOneByIdOrName","id","expected","includes","clientName","redirectUri","name","post_logout_redirect_uri","isValidPostLogoutRedirect","postLogoutRedirectUri","state","revoke","session","findOneById","record","scope","OAUTH2","LOGOUT","refType","SESSION","refId","actorType","actorId","realmId","exp","nowSeconds","Math","floor","Date","now","registered","candidate","parsed","URL","protocol","username","password","split"],"sources":["../../../../src/core/oauth2/end-session/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isSimpleURLMatch, isUUID } from '@authup/kit';\nimport type { Client, IdentityType } from '@authup/core-kit';\nimport { EventName, EventRefType, EventScope } from '@authup/core-kit';\nimport type { OAuth2TokenPayload } from '@authup/specs';\nimport { OAuth2TokenKind } from '@authup/specs';\nimport type { IEventService, IRealmRepository } from '../../entities/index.ts';\nimport type { ISessionManager } from '../../authentication/index.ts';\nimport type { IOAuth2ClientRepository } from '../client/index.ts';\nimport type { IOAuth2TokenVerifier } from '../token/index.ts';\nimport type {\n IOAuth2EndSessionService,\n OAuth2EndSessionRequest,\n OAuth2EndSessionResult,\n OAuth2EndSessionServiceContext,\n} from './types.ts';\n\nexport class OAuth2EndSessionService implements IOAuth2EndSessionService {\n protected tokenVerifier: IOAuth2TokenVerifier;\n\n protected sessionManager: ISessionManager;\n\n protected clientRepository: IOAuth2ClientRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected eventService?: IEventService;\n\n protected hintGracePeriod: number;\n\n constructor(ctx: OAuth2EndSessionServiceContext) {\n this.tokenVerifier = ctx.tokenVerifier;\n this.sessionManager = ctx.sessionManager;\n this.clientRepository = ctx.clientRepository;\n this.realmRepository = ctx.realmRepository;\n this.eventService = ctx.eventService;\n this.hintGracePeriod = ctx.hintGracePeriod ?? 0;\n }\n\n async verify(data: OAuth2EndSessionRequest): Promise<OAuth2EndSessionResult> {\n let hintVerified = false;\n let sub: string | undefined;\n let subKind: string | undefined;\n let sessionId: string | undefined;\n let hintRealmId: string | undefined;\n let audiences: string[] = [];\n\n if (data.id_token_hint) {\n try {\n // Signature + kind are the anchors; exp is skipped (a logout hint\n // is routinely expired) and the cache blocklist is irrelevant.\n const payload = await this.tokenVerifier.verify(data.id_token_hint, {\n ignoreExpiry: true,\n skipActiveCheck: true,\n });\n\n // MUST be an id_token — access/refresh tokens also carry\n // session_id, so accepting them would let a leaked access token\n // act as a logout weapon.\n if (payload.kind === OAuth2TokenKind.ID_TOKEN && this.isWithinHintGraceWindow(payload)) {\n hintVerified = true;\n sub = payload.sub;\n subKind = payload.sub_kind;\n sessionId = payload.sid ?? payload.session_id ?? undefined;\n hintRealmId = payload.realm_id ?? undefined;\n // aud may be a single string or an array (JWT spec).\n const { aud } = payload;\n if (Array.isArray(aud)) {\n audiences = aud.filter((entry): entry is string => typeof entry === 'string');\n } else if (typeof aud === 'string') {\n audiences = [aud];\n }\n }\n } catch {\n // forged / unverifiable hint → stays unverified (no revoke)\n }\n }\n\n // Resolve a single client for the aud cross-check and redirect\n // validation: the request's client_id, else the hint's sole audience\n // (ambiguous for a multi-aud hint).\n const clientId = data.client_id ?? (audiences.length === 1 ? audiences[0] : undefined);\n\n let client: Client | null = null;\n if (clientId) {\n // Scope a name-identified client to the request's realm hint; a\n // VERIFIED hint's own realm claim serves as fallback (claims from an\n // unverified hint are never trusted). No master fallback here\n // (unlike /token): a bogus hint must NOT silently resolve a\n // same-named client in master → null realm.\n const realmKey = data.realm_id ?? data.realm_name ?? (hintVerified ? hintRealmId : undefined);\n const realm = await this.realmRepository.resolve(realmKey, false);\n\n // Fail closed instead of dropping the realm predicate: a supplied\n // realm key that does not resolve never degrades to an unscoped\n // lookup, and a NAME-form client_id without any realm key is\n // ambiguous (client names are only unique per realm, and every\n // realm carries the same-named system clients — same rule as the\n // /authorize verifier). A UUID is globally unique and needs no\n // scope; the sole-aud-derived clientId is always a UUID.\n if (realm) {\n client = await this.clientRepository.findOneByIdOrName(clientId, realm.id);\n } else if (!realmKey && isUUID(clientId)) {\n client = await this.clientRepository.findOneByIdOrName(clientId);\n }\n }\n\n // aud/client_id cross-check: when the request supplies a client_id on a\n // verified hint, it MUST denote one of the hint's audiences. The aud is\n // the client UUID, so a name-form client_id is compared via its resolved\n // client's id. Fail closed: an aud-less hint, or a name that did not\n // resolve, counts as unverified.\n if (hintVerified && data.client_id) {\n const expected = isUUID(data.client_id) ? data.client_id : client?.id;\n if (!expected || audiences.length === 0 || !audiences.includes(expected)) {\n hintVerified = false;\n sub = undefined;\n subKind = undefined;\n sessionId = undefined;\n }\n }\n\n let clientName: string | undefined;\n let redirectUri: string | undefined;\n\n // Redirect validation is independent of hint verification — the\n // click-gated confirm page (unverified hint / hint-less request) still\n // honors a registered post-logout redirect.\n if (client) {\n clientName = client.name;\n if (\n data.post_logout_redirect_uri &&\n this.isValidPostLogoutRedirect(client.postLogoutRedirectUri, data.post_logout_redirect_uri)\n ) {\n redirectUri = data.post_logout_redirect_uri;\n }\n }\n\n return {\n hintVerified,\n ...(hintVerified ? {\n sub,\n subKind,\n sessionId,\n } : {}),\n ...(clientId ? { clientId } : {}),\n ...(clientName ? { clientName } : {}),\n ...(redirectUri ? { redirectUri, ...(data.state ? { state: data.state } : {}) } : {}),\n };\n }\n\n async revoke(sessionId: string, sub: string, subKind: string): Promise<boolean> {\n const session = await this.sessionManager.findOneById(sessionId);\n if (!session) {\n return false;\n }\n\n // Never revoke a session that does not belong to the hint's subject.\n if (session.sub !== sub || session.subKind !== subKind) {\n return false;\n }\n\n await this.sessionManager.revoke(sessionId);\n\n await this.eventService?.record({\n scope: EventScope.OAUTH2,\n name: EventName.LOGOUT,\n refType: EventRefType.SESSION,\n refId: sessionId,\n sessionId,\n actorType: session.subKind as `${IdentityType}`,\n actorId: session.sub,\n realmId: session.realmId,\n });\n\n return true;\n }\n\n /**\n * With a positive `hintGracePeriod`, an expired hint is honored only within\n * the window past `exp` — beyond it a leaked id_token stops being a\n * replayable remote logout (the hint counts as unverified; the click-gated\n * confirm page still works). 0 keeps spec/Keycloak parity: any expired hint.\n */\n protected isWithinHintGraceWindow(payload: OAuth2TokenPayload): boolean {\n if (this.hintGracePeriod <= 0) {\n return true;\n }\n\n // a bounded window without an exp claim to judge against fails closed\n if (typeof payload.exp !== 'number') {\n return false;\n }\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n return nowSeconds - payload.exp <= this.hintGracePeriod;\n }\n\n /**\n * A post-logout redirect is honored only when it is an absolute http(s) URL\n * that matches a registered client redirect pattern (defense against open\n * redirects to attacker-controlled URLs).\n */\n protected isValidPostLogoutRedirect(\n registered: string | null | undefined,\n candidate: string,\n ): boolean {\n let parsed: URL;\n try {\n parsed = new URL(candidate);\n } catch {\n return false;\n }\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return false;\n }\n\n // The matcher canonicalizes the candidate (userinfo dropped) while the\n // redirect is built from the raw value, so a credential blob would\n // ride the Location header (#3455).\n if (parsed.username || parsed.password) {\n return false;\n }\n\n if (!registered) {\n return false;\n }\n\n // isSimpleURLMatch, never isSimpleMatch: matched against the raw\n // string, a `*` in a registered pattern's host absorbs a `?`, `#` or\n // `\\`, which would turn this endpoint into a server-issued open\n // redirect carrying `state`.\n return isSimpleURLMatch(candidate, registered.split(','));\n }\n}\n"],"mappings":";;;;;;;AAuBA,IAAaM,0BAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAqC;EAC7C,KAAKN,gBAAgBM,IAAIN;EACzB,KAAKC,iBAAiBK,IAAIL;EAC1B,KAAKC,mBAAmBI,IAAIJ;EAC5B,KAAKC,kBAAkBG,IAAIH;EAC3B,KAAKC,eAAeE,IAAIF;EACxB,KAAKC,kBAAkBC,IAAID,mBAAmB;CAClD;CAEA,MAAME,OAAOC,MAAgE;EACzE,IAAIC,eAAe;EACnB,IAAIC;EACJ,IAAIC;EACJ,IAAIC;EACJ,IAAIC;EACJ,IAAIC,YAAsB,CAAA;EAE1B,IAAIN,KAAKO,eACL,IAAI;GAGA,MAAMC,UAAU,MAAM,KAAKhB,cAAcO,OAAOC,KAAKO,eAAe;IAChEE,cAAc;IACdC,iBAAiB;GACrB,CAAA;GAKA,IAAIF,QAAQG,SAASrB,gBAAgBsB,YAAY,KAAKC,wBAAwBL,OAAAA,GAAU;IACpFP,eAAe;IACfC,MAAMM,QAAQN;IACdC,UAAUK,QAAQM;IAClBV,YAAYI,QAAQO,OAAOP,QAAQQ,cAAcC,KAAAA;IACjDZ,cAAcG,QAAQU,YAAYD,KAAAA;IAElC,MAAM,EAAEE,QAAQX;IAChB,IAAIY,MAAMC,QAAQF,GAAAA,GACdb,YAAYa,IAAIG,QAAQC,UAA2B,OAAOA,UAAU,QAAA;SACjE,IAAI,OAAOJ,QAAQ,UACtBb,YAAY,CAACa,GAAI;GAEzB;EACJ,QAAQ,CAER;EAMJ,MAAMK,WAAWxB,KAAKyB,cAAcnB,UAAUoB,WAAW,IAAIpB,UAAU,KAAKW,KAAAA;EAE5E,IAAIU,SAAwB;EAC5B,IAAIH,UAAU;GAMV,MAAMI,WAAW5B,KAAKkB,YAAYlB,KAAK6B,eAAe5B,eAAeI,cAAcY,KAAAA;GACnF,MAAMa,QAAQ,MAAM,KAAKnC,gBAAgBoC,QAAQH,UAAU,KAAA;GAS3D,IAAIE,OACAH,SAAS,MAAM,KAAKjC,iBAAiBsC,kBAAkBR,UAAUM,MAAMG,EAAE;QACtE,IAAI,CAACL,YAAY1C,OAAOsC,QAAAA,GAC3BG,SAAS,MAAM,KAAKjC,iBAAiBsC,kBAAkBR,QAAAA;EAE/D;EAOA,IAAIvB,gBAAgBD,KAAKyB,WAAW;GAChC,MAAMS,WAAWhD,OAAOc,KAAKyB,SAAS,IAAIzB,KAAKyB,YAAYE,QAAQM;GACnE,IAAI,CAACC,YAAY5B,UAAUoB,WAAW,KAAK,CAACpB,UAAU6B,SAASD,QAAAA,GAAW;IACtEjC,eAAe;IACfC,MAAMe,KAAAA;IACNd,UAAUc,KAAAA;IACVb,YAAYa,KAAAA;GAChB;EACJ;EAEA,IAAImB;EACJ,IAAIC;EAKJ,IAAIV,QAAQ;GACRS,aAAaT,OAAOW;GACpB,IACItC,KAAKuC,4BACL,KAAKC,0BAA0Bb,OAAOc,uBAAuBzC,KAAKuC,wBAAwB,GAE1FF,cAAcrC,KAAKuC;EAE3B;EAEA,OAAO;GACHtC;GACA,GAAIA,eAAe;IACfC;IACAC;IACAC;GACJ,IAAI,CAAC;GACL,GAAIoB,WAAW,EAAEA,SAAS,IAAI,CAAC;GAC/B,GAAIY,aAAa,EAAEA,WAAW,IAAI,CAAC;GACnC,GAAIC,cAAc;IAAEA;IAAa,GAAIrC,KAAK0C,QAAQ,EAAEA,OAAO1C,KAAK0C,MAAM,IAAI,CAAC;GAAG,IAAI,CAAC;EACvF;CACJ;CAEA,MAAMC,OAAOvC,WAAmBF,KAAaC,SAAmC;EAC5E,MAAMyC,UAAU,MAAM,KAAKnD,eAAeoD,YAAYzC,SAAAA;EACtD,IAAI,CAACwC,SACD,OAAO;EAIX,IAAIA,QAAQ1C,QAAQA,OAAO0C,QAAQzC,YAAYA,SAC3C,OAAO;EAGX,MAAM,KAAKV,eAAekD,OAAOvC,SAAAA;EAEjC,MAAM,KAAKR,cAAckD,OAAO;GAC5BC,OAAO1D,WAAW2D;GAClBV,MAAMnD,UAAU8D;GAChBC,SAAS9D,aAAa+D;GACtBC,OAAOhD;GACPA;GACAiD,WAAWT,QAAQzC;GACnBmD,SAASV,QAAQ1C;GACjBqD,SAASX,QAAQW;EACrB,CAAA;EAEA,OAAO;CACX;;;;;;IAQA,wBAAkC/C,SAAsC;EACpE,IAAI,KAAKX,mBAAmB,GACxB,OAAO;EAIX,IAAI,OAAOW,QAAQgD,QAAQ,UACvB,OAAO;EAIX,OADmBE,KAAKC,MAAMC,KAAKC,IAAG,IAAK,GACpCJ,IAAajD,QAAQgD,OAAO,KAAK3D;CAC5C;;;;;IAOA,0BACIiE,YACAC,WACO;EACP,IAAIC;EACJ,IAAI;GACAA,SAAS,IAAIC,IAAIF,SAAAA;EACrB,QAAQ;GACJ,OAAO;EACX;EAEA,IAAIC,OAAOE,aAAa,WAAWF,OAAOE,aAAa,UACnD,OAAO;EAMX,IAAIF,OAAOG,YAAYH,OAAOI,UAC1B,OAAO;EAGX,IAAI,CAACN,YACD,OAAO;EAOX,OAAO7E,iBAAiB8E,WAAWD,WAAWO,MAAM,GAAA,CAAA;CACxD;AACJ"}
|
|
@@ -3,9 +3,9 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { deriveAmrAcr } from "../authorization/helpers.mjs";
|
|
5
5
|
import { toIdentityPolicyData } from "../../identity/permission/identity-policy-data.mjs";
|
|
6
|
-
import { OAUTH2_FEDERATED_LOGIN_TTL } from "./constants.mjs";
|
|
7
6
|
import { describeError } from "../../../utils/error.mjs";
|
|
8
7
|
import "../../../utils/index.mjs";
|
|
8
|
+
import { OAUTH2_FEDERATED_LOGIN_TTL } from "./constants.mjs";
|
|
9
9
|
import { isIdentityProviderAssuranceError } from "../../identity/provider/authentication/protocols/oauth2/assurance.mjs";
|
|
10
10
|
import { createIdentityProviderOAuth2Authenticator } from "../../identity/provider/authentication/factory.mjs";
|
|
11
11
|
import { buildOAuth2BearerTokenResponse } from "../response/bearer.mjs";
|
|
@@ -67,7 +67,7 @@ var OAuth2FederatedLoginService = class {
|
|
|
67
67
|
}
|
|
68
68
|
if (provider.realmId && verified.client.realmId !== provider.realmId) throw OAuth2RequestError.malformed("The provider and client realm do not match.");
|
|
69
69
|
const redirectUri = verified.data.redirect_uri;
|
|
70
|
-
if (!
|
|
70
|
+
if (!redirectUri || !verified.redirectUriVerified) throw OAuth2RequestError.malformed("The redirect_uri was not verified.");
|
|
71
71
|
if (!isSafeRedirectURLScheme(redirectUri)) throw new InternalError("The redirect_uri scheme is not allowed.");
|
|
72
72
|
if (!provider.enabled) return {
|
|
73
73
|
kind: "refused",
|
|
@@ -109,7 +109,7 @@ var OAuth2FederatedLoginService = class {
|
|
|
109
109
|
realm
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
|
-
if (this.accessPolicyEvaluator
|
|
112
|
+
if (subject && this.accessPolicyEvaluator) allowed = await this.accessPolicyEvaluator.evaluate(verified.client.accessPolicyId, subject);
|
|
113
113
|
if (!allowed) return {
|
|
114
114
|
kind: "refused",
|
|
115
115
|
refusal: OAuth2FederatedLoginRefusal.ACCESS_DENIED,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["isSafeRedirectURLScheme","EventName","EventRefType","EventScope","IdentityType","ScopeName","SessionAuthMethod","BadRequestError","InternalError","OAuth2ErrorCode","OAuth2RequestError","OAuth2SubKind","isOAuth2Error","describeError","createIdentityProviderOAuth2Authenticator","isIdentityProviderAssuranceError","toIdentityPolicyData","deriveAmrAcr","buildOAuth2BearerTokenResponse","OAUTH2_FEDERATED_LOGIN_TTL","OAuth2FederatedLoginRefusal","OAuth2FederatedLoginService","options","accountManager","realmRepository","codeRequestVerifier","sessionManager","pendingLoginStore","accessTokenIssuer","refreshTokenIssuer","accessPolicyEvaluator","eventService","metrics","logger","authenticatorFactory","ctx","provider","baseURL","clientId","complete","input","code","codeRequest","verified","verify","e","kind","refusal","CODE_REQUEST","realmId","client","malformed","redirectUri","data","redirect_uri","redirectUriVerified","enabled","PROVIDER_DISABLED","error","LOGIN_REQUIRED","authenticator","client_id","user","authenticate","warn","id","ASSURANCE_INSUFFICIENT","ACCESS_DENIED","active","USER_INACTIVE","accessPolicyId","realm","resolve","allowed","subject","type","USER","evaluate","session","create","userAgent","request","undefined","ipAddress","sub","subKind","mfaAt","authMethod","EXTERNAL","expiresAt","Date","now","toISOString","pendingLoginId","save","sessionId","providerId","userName","name","completeHandoff","refuse","pending","consume","existing","findOneById","parse","refresh","payload","session_id","user_agent","remote_address","scope","GLOBAL","sub_kind","realm_id","realm_name","accessToken","accessTokenPayload","issue","refreshToken","refreshTokenPayload","record","OAUTH2","LOGIN","refType","SESSION","refId","actorType","actorId","actorName","requestIpAddress","requestUserAgent","reason","recordLogin"],"sources":["../../../../src/core/oauth2/federated-login/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isSafeRedirectURLScheme } from '@authup/kit';\nimport type { User } from '@authup/core-kit';\nimport {\n EventName,\n EventRefType,\n EventScope,\n IdentityType,\n ScopeName,\n SessionAuthMethod,\n} from '@authup/core-kit';\nimport { BadRequestError, InternalError } from '@authup/errors';\nimport type { Logger } from '@authup/server-kit';\nimport type { OAuth2TokenGrantResponse, OAuth2TokenPayload } from '@authup/specs';\nimport {\n OAuth2ErrorCode,\n OAuth2RequestError,\n OAuth2SubKind,\n isOAuth2Error,\n} from '@authup/specs';\nimport { describeError } from '../../../utils/index.ts';\nimport type { IEventService, IRealmRepository } from '../../entities/index.ts';\nimport type { IAuthFlowMetrics } from '../../metrics/index.ts';\nimport type { ISessionManager } from '../../authentication/index.ts';\n// Deep imports, never the `core/identity` barrel: it reaches back into\n// this module through the core barrel, and the cycle would TDZ-crash.\nimport type { IIdentityProviderAccountManager } from '../../identity/provider/account/types.ts';\nimport { createIdentityProviderOAuth2Authenticator } from '../../identity/provider/authentication/factory.ts';\nimport { isIdentityProviderAssuranceError } from '../../identity/provider/authentication/protocols/oauth2/assurance.ts';\nimport { toIdentityPolicyData } from '../../identity/permission/identity-policy-data.ts';\nimport type { IOAuth2AccessPolicyEvaluator } from '../access-policy/index.ts';\nimport type {\n IOAuth2AuthorizationCodeRequestVerifier,\n OAuth2AuthorizationCodeRequestVerificationResult,\n} from '../authorization/index.ts';\nimport { deriveAmrAcr } from '../authorization/helpers.ts';\nimport { buildOAuth2BearerTokenResponse } from '../response/index.ts';\nimport type { IOAuth2TokenIssuer } from '../token/index.ts';\nimport { OAUTH2_FEDERATED_LOGIN_TTL } from './constants.ts';\nimport type {\n IOAuth2FederatedLoginService,\n IOAuth2FederatedLoginStore,\n OAuth2FederatedLoginAuthenticatorFactory,\n OAuth2FederatedLoginCompleteHandoffInput,\n OAuth2FederatedLoginCompleteInput,\n OAuth2FederatedLoginCompleteResult,\n OAuth2FederatedLoginServiceContext,\n OAuth2FederatedLoginServiceOptions,\n} from './types.ts';\nimport { OAuth2FederatedLoginRefusal } from './types.ts';\n\nexport class OAuth2FederatedLoginService implements IOAuth2FederatedLoginService {\n protected options : OAuth2FederatedLoginServiceOptions;\n\n protected accountManager : IIdentityProviderAccountManager;\n\n protected realmRepository : IRealmRepository;\n\n protected codeRequestVerifier : IOAuth2AuthorizationCodeRequestVerifier;\n\n protected sessionManager : ISessionManager;\n\n protected pendingLoginStore : IOAuth2FederatedLoginStore;\n\n protected accessTokenIssuer : IOAuth2TokenIssuer;\n\n protected refreshTokenIssuer : IOAuth2TokenIssuer;\n\n protected accessPolicyEvaluator? : IOAuth2AccessPolicyEvaluator;\n\n protected eventService? : IEventService;\n\n protected metrics? : IAuthFlowMetrics;\n\n protected logger? : Logger;\n\n protected authenticatorFactory : OAuth2FederatedLoginAuthenticatorFactory;\n\n constructor(ctx: OAuth2FederatedLoginServiceContext) {\n this.options = ctx.options;\n this.accountManager = ctx.accountManager;\n this.realmRepository = ctx.realmRepository;\n this.codeRequestVerifier = ctx.codeRequestVerifier;\n this.sessionManager = ctx.sessionManager;\n this.pendingLoginStore = ctx.pendingLoginStore;\n this.accessTokenIssuer = ctx.accessTokenIssuer;\n this.refreshTokenIssuer = ctx.refreshTokenIssuer;\n this.accessPolicyEvaluator = ctx.accessPolicyEvaluator;\n this.eventService = ctx.eventService;\n this.metrics = ctx.metrics;\n this.logger = ctx.logger;\n this.authenticatorFactory = ctx.authenticatorFactory ??\n ((provider, options) => createIdentityProviderOAuth2Authenticator({\n accountManager: this.accountManager,\n provider,\n logger: options.logger,\n options: {\n baseURL: options.baseURL,\n clientId: options.clientId,\n },\n }));\n }\n\n async complete(input: OAuth2FederatedLoginCompleteInput): Promise<OAuth2FederatedLoginCompleteResult> {\n const {\n code, \n codeRequest, \n provider, \n } = input;\n\n // Re-verify the request BEFORE the provider's single-use code is\n // spent. It re-resolves the client (active, grant allowlist, scopes)\n // and re-matches the redirect_uri against the client's registered\n // patterns, so a client deactivated (or a pattern removed) while the\n // person was away at the provider cannot still receive a code, and a\n // refused completion provisions no user.\n //\n // Only a refusal is reported as one; a server failure keeps throwing.\n let verified : OAuth2AuthorizationCodeRequestVerificationResult;\n try {\n verified = await this.codeRequestVerifier.verify(codeRequest);\n } catch (e) {\n if (!isOAuth2Error(e)) {\n throw e;\n }\n\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.CODE_REQUEST,\n codeRequest,\n };\n }\n\n // The provider and the client must share a realm, the completion-side\n // half of the plan-041 binding. It rests on the client the\n // verification just resolved rather than the `realm_id` carried on\n // the state blob: that value is only there because `authorize-out`\n // stores the VERIFIED request, so a guard reading it would disappear\n // silently for any state that reached here without the stamp. A\n // realm-less (global) provider matches every client by design.\n if (provider.realmId && verified.client.realmId !== provider.realmId) {\n throw OAuth2RequestError.malformed('The provider and client realm do not match.');\n }\n\n // A stored code request always carries a redirect_uri (that mount is\n // required in OAuth2AuthorizationCodeRequestValidator, unlike\n // `state`), so a verified request is a verified redirect target. The\n // guard keeps the redirect decision resting on the match itself,\n // which is the only thing here that knows the uri was ever matched.\n const redirectUri = verified.data.redirect_uri;\n if (!verified.redirectUriVerified || !redirectUri) {\n throw OAuth2RequestError.malformed('The redirect_uri was not verified.');\n }\n\n // A non-http(s) target is navigated from the interstitial page, which\n // `location.assign`s it and renders it as an href, so a\n // script-capable scheme would execute on the IdP origin. The client\n // validator and the code-request verifier both refuse such a scheme;\n // this fails closed should either gap, and it runs before the\n // provider's single-use code is spent, a user provisioned or a code\n // minted.\n if (!isSafeRedirectURLScheme(redirectUri)) {\n throw new InternalError('The redirect_uri scheme is not allowed.');\n }\n\n // The provider must still be enabled, the rule the link path already\n // applies. Disabling a provider has to stop logins in flight too,\n // otherwise it only stops new ones. Checked before the exchange, so\n // the refusal contacts the provider not at all.\n if (!provider.enabled) {\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.PROVIDER_DISABLED,\n error: OAuth2ErrorCode.LOGIN_REQUIRED,\n codeRequest: verified.data,\n };\n }\n\n const authenticator = this.authenticatorFactory(provider, {\n baseURL: this.options.baseURL,\n clientId: verified.data.client_id,\n logger: this.logger,\n });\n\n let user : User;\n try {\n user = await authenticator.authenticate({ code });\n } catch (e) {\n // The upstream did not meet the provider's assurance allow-list\n // (issue #3477). No user is provisioned and no account linked\n // because the gate throws inside `resolveIdentity`, before the\n // account manager runs - not because of where this catch sits.\n // The reason only goes to the log: the marker\n // set the hosted page maps is deliberately closed, so `access_denied`\n // is what the browser sees.\n if (!isIdentityProviderAssuranceError(e)) {\n throw e;\n }\n\n this.logger?.warn(describeError(\n e,\n `The identity provider (${provider.id}) login was refused.`,\n ));\n\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.ASSURANCE_INSUFFICIENT,\n error: OAuth2ErrorCode.ACCESS_DENIED,\n codeRequest: verified.data,\n };\n }\n\n // The local login path refuses an inactive user (EntityInactiveError),\n // and a federated login must not be the way around that. Only\n // reachable for an already-linked user: a first login provisions an\n // active one.\n if (!user.active) {\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.USER_INACTIVE,\n error: OAuth2ErrorCode.ACCESS_DENIED,\n codeRequest: verified.data,\n };\n }\n\n // Application access policy (plan 052), federated leg. A policy id\n // with no wired evaluator denies (fail closed).\n if (verified.client.accessPolicyId) {\n const realm = await this.realmRepository.resolve(provider.realmId, true);\n let allowed = false;\n\n const subject = toIdentityPolicyData({\n type: IdentityType.USER,\n data: {\n ...user,\n realm,\n },\n });\n if (this.accessPolicyEvaluator && subject) {\n allowed = await this.accessPolicyEvaluator.evaluate(\n verified.client.accessPolicyId,\n subject,\n );\n }\n\n if (!allowed) {\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.ACCESS_DENIED,\n error: OAuth2ErrorCode.ACCESS_DENIED,\n codeRequest: verified.data,\n };\n }\n }\n\n // The callback establishes the session and stops there. The RP's\n // code is issued at the end of the hosted authorize ladder, so a\n // federated login passes the same gates a password login does: the\n // second factor, inline enrollment, prompt/max_age freshness,\n // acr_values step-up and consent (plan 094).\n //\n // Its lifetime is the pending login's: an abandoned one self-expires and\n // is swept with the regular session sweep, and redemption extends it\n // to the regular one.\n const session = await this.sessionManager.create({\n userAgent: input.request?.userAgent ?? undefined,\n ipAddress: input.request?.ipAddress ?? undefined,\n realmId: user.realmId,\n // no `clientId`: a USER-subject session, and the column is the\n // client-SUBJECT foreign key. The application lands on the\n // token rows at the /token exchange.\n sub: user.id,\n subKind: IdentityType.USER,\n mfaAt: null,\n authMethod: SessionAuthMethod.EXTERNAL,\n expiresAt: new Date(Date.now() + OAUTH2_FEDERATED_LOGIN_TTL).toISOString(),\n });\n\n const pendingLoginId = await this.pendingLoginStore.save({\n sessionId: session.id,\n providerId: provider.id,\n userName: user.name,\n });\n\n return {\n kind: 'issued',\n pendingLoginId,\n codeRequest: verified.data,\n };\n }\n\n async completeHandoff(input: OAuth2FederatedLoginCompleteHandoffInput): Promise<OAuth2TokenGrantResponse> {\n // One message for every refusal: the caller is anonymous, so an\n // unknown pending login, an expired one and a foreign one must not\n // be distinguishable.\n const refuse = () => new BadRequestError('The login request is unknown or expired.');\n\n const pending = await this.pendingLoginStore.consume(input.pendingLoginId);\n if (!pending) {\n throw refuse();\n }\n\n // The browser binding is the cookie the callback set, which only the\n // browser that started this login carries and no other origin can\n // write. So there is nothing here to prove beyond the provider the\n // completion was addressed at.\n //\n // The callback request's address and agent are deliberately not\n // compared: both are chosen by whoever makes that request (under the\n // shipped `trustProxy: true` the address is the client-supplied\n // left-most `X-Forwarded-For` entry), and comparing them across a\n // top-level navigation and the page's own request is the shape issue\n // #3439 rejected.\n if (pending.providerId !== input.providerId) {\n throw refuse();\n }\n\n const existing = await this.sessionManager.findOneById(pending.sessionId);\n if (!existing) {\n throw refuse();\n }\n\n // The pending session carries the pending login's own deadline, and\n // the lookup is by id alone. Today the cache entry above expires with\n // it, so this only fires on clock skew between the two stores, but the\n // expiry must be enforced where it is written: `refresh` would extend\n // an abandoned login into a regular session.\n if (Date.parse(existing.expiresAt) <= Date.now()) {\n throw refuse();\n }\n\n const realm = await this.realmRepository.resolve(existing.realmId, true);\n\n // The login is complete now, so the pending session becomes a\n // regular one.\n const session = await this.sessionManager.refresh(existing);\n\n const payload : Partial<OAuth2TokenPayload> = {\n session_id: session.id,\n user_agent: session.userAgent,\n remote_address: session.ipAddress,\n scope: ScopeName.GLOBAL,\n sub: session.sub,\n sub_kind: OAuth2SubKind.USER,\n realm_id: session.realmId,\n realm_name: realm.name,\n ...deriveAmrAcr(session),\n };\n\n const [accessToken, accessTokenPayload] = await this.accessTokenIssuer.issue(payload);\n const [refreshToken, refreshTokenPayload] = await this.refreshTokenIssuer.issue(payload);\n\n await this.eventService?.record({\n scope: EventScope.OAUTH2,\n name: EventName.LOGIN,\n refType: EventRefType.SESSION,\n refId: session.id,\n clientId: null,\n sessionId: session.id,\n actorType: IdentityType.USER,\n actorId: session.sub,\n actorName: pending.userName ?? null,\n realmId: session.realmId,\n requestIpAddress: session.ipAddress ?? null,\n requestUserAgent: session.userAgent ?? null,\n data: { reason: 'federated', providerId: pending.providerId },\n });\n this.metrics?.recordLogin('success');\n\n return buildOAuth2BearerTokenResponse({\n accessToken,\n accessTokenPayload,\n refreshToken,\n refreshTokenPayload,\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["isSafeRedirectURLScheme","EventName","EventRefType","EventScope","IdentityType","ScopeName","SessionAuthMethod","BadRequestError","InternalError","OAuth2ErrorCode","OAuth2RequestError","OAuth2SubKind","isOAuth2Error","describeError","createIdentityProviderOAuth2Authenticator","isIdentityProviderAssuranceError","toIdentityPolicyData","deriveAmrAcr","buildOAuth2BearerTokenResponse","OAUTH2_FEDERATED_LOGIN_TTL","OAuth2FederatedLoginRefusal","OAuth2FederatedLoginService","options","accountManager","realmRepository","codeRequestVerifier","sessionManager","pendingLoginStore","accessTokenIssuer","refreshTokenIssuer","accessPolicyEvaluator","eventService","metrics","logger","authenticatorFactory","ctx","provider","baseURL","clientId","complete","input","code","codeRequest","verified","verify","e","kind","refusal","CODE_REQUEST","realmId","client","malformed","redirectUri","data","redirect_uri","redirectUriVerified","enabled","PROVIDER_DISABLED","error","LOGIN_REQUIRED","authenticator","client_id","user","authenticate","warn","id","ASSURANCE_INSUFFICIENT","ACCESS_DENIED","active","USER_INACTIVE","accessPolicyId","realm","resolve","allowed","subject","type","USER","evaluate","session","create","userAgent","request","undefined","ipAddress","sub","subKind","mfaAt","authMethod","EXTERNAL","expiresAt","Date","now","toISOString","pendingLoginId","save","sessionId","providerId","userName","name","completeHandoff","refuse","pending","consume","existing","findOneById","parse","refresh","payload","session_id","user_agent","remote_address","scope","GLOBAL","sub_kind","realm_id","realm_name","accessToken","accessTokenPayload","issue","refreshToken","refreshTokenPayload","record","OAUTH2","LOGIN","refType","SESSION","refId","actorType","actorId","actorName","requestIpAddress","requestUserAgent","reason","recordLogin"],"sources":["../../../../src/core/oauth2/federated-login/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isSafeRedirectURLScheme } from '@authup/kit';\nimport type { User } from '@authup/core-kit';\nimport {\n EventName,\n EventRefType,\n EventScope,\n IdentityType,\n ScopeName,\n SessionAuthMethod,\n} from '@authup/core-kit';\nimport { BadRequestError, InternalError } from '@authup/errors';\nimport type { Logger } from '@authup/server-kit';\nimport type { OAuth2TokenGrantResponse, OAuth2TokenPayload } from '@authup/specs';\nimport {\n OAuth2ErrorCode,\n OAuth2RequestError,\n OAuth2SubKind,\n isOAuth2Error,\n} from '@authup/specs';\nimport { describeError } from '../../../utils/index.ts';\nimport type { IEventService, IRealmRepository } from '../../entities/index.ts';\nimport type { IAuthFlowMetrics } from '../../metrics/index.ts';\nimport type { ISessionManager } from '../../authentication/index.ts';\n// Deep imports, never the `core/identity` barrel: it reaches back into\n// this module through the core barrel, and the cycle would TDZ-crash.\nimport type { IIdentityProviderAccountManager } from '../../identity/provider/account/types.ts';\nimport { createIdentityProviderOAuth2Authenticator } from '../../identity/provider/authentication/factory.ts';\nimport { isIdentityProviderAssuranceError } from '../../identity/provider/authentication/protocols/oauth2/assurance.ts';\nimport { toIdentityPolicyData } from '../../identity/permission/identity-policy-data.ts';\nimport type { IOAuth2AccessPolicyEvaluator } from '../access-policy/index.ts';\nimport type {\n IOAuth2AuthorizationCodeRequestVerifier,\n OAuth2AuthorizationCodeRequestVerificationResult,\n} from '../authorization/index.ts';\nimport { deriveAmrAcr } from '../authorization/helpers.ts';\nimport { buildOAuth2BearerTokenResponse } from '../response/index.ts';\nimport type { IOAuth2TokenIssuer } from '../token/index.ts';\nimport { OAUTH2_FEDERATED_LOGIN_TTL } from './constants.ts';\nimport type {\n IOAuth2FederatedLoginService,\n IOAuth2FederatedLoginStore,\n OAuth2FederatedLoginAuthenticatorFactory,\n OAuth2FederatedLoginCompleteHandoffInput,\n OAuth2FederatedLoginCompleteInput,\n OAuth2FederatedLoginCompleteResult,\n OAuth2FederatedLoginServiceContext,\n OAuth2FederatedLoginServiceOptions,\n} from './types.ts';\nimport { OAuth2FederatedLoginRefusal } from './types.ts';\n\nexport class OAuth2FederatedLoginService implements IOAuth2FederatedLoginService {\n protected options : OAuth2FederatedLoginServiceOptions;\n\n protected accountManager : IIdentityProviderAccountManager;\n\n protected realmRepository : IRealmRepository;\n\n protected codeRequestVerifier : IOAuth2AuthorizationCodeRequestVerifier;\n\n protected sessionManager : ISessionManager;\n\n protected pendingLoginStore : IOAuth2FederatedLoginStore;\n\n protected accessTokenIssuer : IOAuth2TokenIssuer;\n\n protected refreshTokenIssuer : IOAuth2TokenIssuer;\n\n protected accessPolicyEvaluator? : IOAuth2AccessPolicyEvaluator;\n\n protected eventService? : IEventService;\n\n protected metrics? : IAuthFlowMetrics;\n\n protected logger? : Logger;\n\n protected authenticatorFactory : OAuth2FederatedLoginAuthenticatorFactory;\n\n constructor(ctx: OAuth2FederatedLoginServiceContext) {\n this.options = ctx.options;\n this.accountManager = ctx.accountManager;\n this.realmRepository = ctx.realmRepository;\n this.codeRequestVerifier = ctx.codeRequestVerifier;\n this.sessionManager = ctx.sessionManager;\n this.pendingLoginStore = ctx.pendingLoginStore;\n this.accessTokenIssuer = ctx.accessTokenIssuer;\n this.refreshTokenIssuer = ctx.refreshTokenIssuer;\n this.accessPolicyEvaluator = ctx.accessPolicyEvaluator;\n this.eventService = ctx.eventService;\n this.metrics = ctx.metrics;\n this.logger = ctx.logger;\n this.authenticatorFactory = ctx.authenticatorFactory ??\n ((provider, options) => createIdentityProviderOAuth2Authenticator({\n accountManager: this.accountManager,\n provider,\n logger: options.logger,\n options: {\n baseURL: options.baseURL,\n clientId: options.clientId,\n },\n }));\n }\n\n async complete(input: OAuth2FederatedLoginCompleteInput): Promise<OAuth2FederatedLoginCompleteResult> {\n const {\n code, \n codeRequest, \n provider, \n } = input;\n\n // Re-verify the request BEFORE the provider's single-use code is\n // spent. It re-resolves the client (active, grant allowlist, scopes)\n // and re-matches the redirect_uri against the client's registered\n // patterns, so a client deactivated (or a pattern removed) while the\n // person was away at the provider cannot still receive a code, and a\n // refused completion provisions no user.\n //\n // Only a refusal is reported as one; a server failure keeps throwing.\n let verified : OAuth2AuthorizationCodeRequestVerificationResult;\n try {\n verified = await this.codeRequestVerifier.verify(codeRequest);\n } catch (e) {\n if (!isOAuth2Error(e)) {\n throw e;\n }\n\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.CODE_REQUEST,\n codeRequest,\n };\n }\n\n // The provider and the client must share a realm, the completion-side\n // half of the plan-041 binding. It rests on the client the\n // verification just resolved rather than the `realm_id` carried on\n // the state blob: that value is only there because `authorize-out`\n // stores the VERIFIED request, so a guard reading it would disappear\n // silently for any state that reached here without the stamp. A\n // realm-less (global) provider matches every client by design.\n if (provider.realmId && verified.client.realmId !== provider.realmId) {\n throw OAuth2RequestError.malformed('The provider and client realm do not match.');\n }\n\n // A stored code request always carries a redirect_uri (that mount is\n // required in OAuth2AuthorizationCodeRequestValidator, unlike\n // `state`), so a verified request is a verified redirect target. The\n // guard keeps the redirect decision resting on the match itself,\n // which is the only thing here that knows the uri was ever matched.\n const redirectUri = verified.data.redirect_uri;\n if (!redirectUri || !verified.redirectUriVerified) {\n throw OAuth2RequestError.malformed('The redirect_uri was not verified.');\n }\n\n // A non-http(s) target is navigated from the interstitial page, which\n // `location.assign`s it and renders it as an href, so a\n // script-capable scheme would execute on the IdP origin. The client\n // validator and the code-request verifier both refuse such a scheme;\n // this fails closed should either gap, and it runs before the\n // provider's single-use code is spent, a user provisioned or a code\n // minted.\n if (!isSafeRedirectURLScheme(redirectUri)) {\n throw new InternalError('The redirect_uri scheme is not allowed.');\n }\n\n // The provider must still be enabled, the rule the link path already\n // applies. Disabling a provider has to stop logins in flight too,\n // otherwise it only stops new ones. Checked before the exchange, so\n // the refusal contacts the provider not at all.\n if (!provider.enabled) {\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.PROVIDER_DISABLED,\n error: OAuth2ErrorCode.LOGIN_REQUIRED,\n codeRequest: verified.data,\n };\n }\n\n const authenticator = this.authenticatorFactory(provider, {\n baseURL: this.options.baseURL,\n clientId: verified.data.client_id,\n logger: this.logger,\n });\n\n let user : User;\n try {\n user = await authenticator.authenticate({ code });\n } catch (e) {\n // The upstream did not meet the provider's assurance allow-list\n // (issue #3477). No user is provisioned and no account linked\n // because the gate throws inside `resolveIdentity`, before the\n // account manager runs - not because of where this catch sits.\n // The reason only goes to the log: the marker\n // set the hosted page maps is deliberately closed, so `access_denied`\n // is what the browser sees.\n if (!isIdentityProviderAssuranceError(e)) {\n throw e;\n }\n\n this.logger?.warn(describeError(\n e,\n `The identity provider (${provider.id}) login was refused.`,\n ));\n\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.ASSURANCE_INSUFFICIENT,\n error: OAuth2ErrorCode.ACCESS_DENIED,\n codeRequest: verified.data,\n };\n }\n\n // The local login path refuses an inactive user (EntityInactiveError),\n // and a federated login must not be the way around that. Only\n // reachable for an already-linked user: a first login provisions an\n // active one.\n if (!user.active) {\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.USER_INACTIVE,\n error: OAuth2ErrorCode.ACCESS_DENIED,\n codeRequest: verified.data,\n };\n }\n\n // Application access policy (plan 052), federated leg. A policy id\n // with no wired evaluator denies (fail closed).\n if (verified.client.accessPolicyId) {\n const realm = await this.realmRepository.resolve(provider.realmId, true);\n let allowed = false;\n\n const subject = toIdentityPolicyData({\n type: IdentityType.USER,\n data: {\n ...user,\n realm,\n },\n });\n if (subject && this.accessPolicyEvaluator) {\n allowed = await this.accessPolicyEvaluator.evaluate(\n verified.client.accessPolicyId,\n subject,\n );\n }\n\n if (!allowed) {\n return {\n kind: 'refused',\n refusal: OAuth2FederatedLoginRefusal.ACCESS_DENIED,\n error: OAuth2ErrorCode.ACCESS_DENIED,\n codeRequest: verified.data,\n };\n }\n }\n\n // The callback establishes the session and stops there. The RP's\n // code is issued at the end of the hosted authorize ladder, so a\n // federated login passes the same gates a password login does: the\n // second factor, inline enrollment, prompt/max_age freshness,\n // acr_values step-up and consent (plan 094).\n //\n // Its lifetime is the pending login's: an abandoned one self-expires and\n // is swept with the regular session sweep, and redemption extends it\n // to the regular one.\n const session = await this.sessionManager.create({\n userAgent: input.request?.userAgent ?? undefined,\n ipAddress: input.request?.ipAddress ?? undefined,\n realmId: user.realmId,\n // no `clientId`: a USER-subject session, and the column is the\n // client-SUBJECT foreign key. The application lands on the\n // token rows at the /token exchange.\n sub: user.id,\n subKind: IdentityType.USER,\n mfaAt: null,\n authMethod: SessionAuthMethod.EXTERNAL,\n expiresAt: new Date(Date.now() + OAUTH2_FEDERATED_LOGIN_TTL).toISOString(),\n });\n\n const pendingLoginId = await this.pendingLoginStore.save({\n sessionId: session.id,\n providerId: provider.id,\n userName: user.name,\n });\n\n return {\n kind: 'issued',\n pendingLoginId,\n codeRequest: verified.data,\n };\n }\n\n async completeHandoff(input: OAuth2FederatedLoginCompleteHandoffInput): Promise<OAuth2TokenGrantResponse> {\n // One message for every refusal: the caller is anonymous, so an\n // unknown pending login, an expired one and a foreign one must not\n // be distinguishable.\n const refuse = () => new BadRequestError('The login request is unknown or expired.');\n\n const pending = await this.pendingLoginStore.consume(input.pendingLoginId);\n if (!pending) {\n throw refuse();\n }\n\n // The browser binding is the cookie the callback set, which only the\n // browser that started this login carries and no other origin can\n // write. So there is nothing here to prove beyond the provider the\n // completion was addressed at.\n //\n // The callback request's address and agent are deliberately not\n // compared: both are chosen by whoever makes that request (under the\n // shipped `trustProxy: true` the address is the client-supplied\n // left-most `X-Forwarded-For` entry), and comparing them across a\n // top-level navigation and the page's own request is the shape issue\n // #3439 rejected.\n if (pending.providerId !== input.providerId) {\n throw refuse();\n }\n\n const existing = await this.sessionManager.findOneById(pending.sessionId);\n if (!existing) {\n throw refuse();\n }\n\n // The pending session carries the pending login's own deadline, and\n // the lookup is by id alone. Today the cache entry above expires with\n // it, so this only fires on clock skew between the two stores, but the\n // expiry must be enforced where it is written: `refresh` would extend\n // an abandoned login into a regular session.\n if (Date.parse(existing.expiresAt) <= Date.now()) {\n throw refuse();\n }\n\n const realm = await this.realmRepository.resolve(existing.realmId, true);\n\n // The login is complete now, so the pending session becomes a\n // regular one.\n const session = await this.sessionManager.refresh(existing);\n\n const payload : Partial<OAuth2TokenPayload> = {\n session_id: session.id,\n user_agent: session.userAgent,\n remote_address: session.ipAddress,\n scope: ScopeName.GLOBAL,\n sub: session.sub,\n sub_kind: OAuth2SubKind.USER,\n realm_id: session.realmId,\n realm_name: realm.name,\n ...deriveAmrAcr(session),\n };\n\n const [accessToken, accessTokenPayload] = await this.accessTokenIssuer.issue(payload);\n const [refreshToken, refreshTokenPayload] = await this.refreshTokenIssuer.issue(payload);\n\n await this.eventService?.record({\n scope: EventScope.OAUTH2,\n name: EventName.LOGIN,\n refType: EventRefType.SESSION,\n refId: session.id,\n clientId: null,\n sessionId: session.id,\n actorType: IdentityType.USER,\n actorId: session.sub,\n actorName: pending.userName ?? null,\n realmId: session.realmId,\n requestIpAddress: session.ipAddress ?? null,\n requestUserAgent: session.userAgent ?? null,\n data: { reason: 'federated', providerId: pending.providerId },\n });\n this.metrics?.recordLogin('success');\n\n return buildOAuth2BearerTokenResponse({\n accessToken,\n accessTokenPayload,\n refreshToken,\n refreshTokenPayload,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAyDA,IAAaqB,8BAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAyC;EACjD,KAAKb,UAAUa,IAAIb;EACnB,KAAKC,iBAAiBY,IAAIZ;EAC1B,KAAKC,kBAAkBW,IAAIX;EAC3B,KAAKC,sBAAsBU,IAAIV;EAC/B,KAAKC,iBAAiBS,IAAIT;EAC1B,KAAKC,oBAAoBQ,IAAIR;EAC7B,KAAKC,oBAAoBO,IAAIP;EAC7B,KAAKC,qBAAqBM,IAAIN;EAC9B,KAAKC,wBAAwBK,IAAIL;EACjC,KAAKC,eAAeI,IAAIJ;EACxB,KAAKC,UAAUG,IAAIH;EACnB,KAAKC,SAASE,IAAIF;EAClB,KAAKC,uBAAuBC,IAAID,0BAC1BE,UAAUd,YAAYR,0CAA0C;GAC9DS,gBAAgB,KAAKA;GACrBa;GACAH,QAAQX,QAAQW;GAChBX,SAAS;IACLe,SAASf,QAAQe;IACjBC,UAAUhB,QAAQgB;GACtB;EACJ,CAAA;CACR;CAEA,MAAMC,SAASC,OAAuF;EAClG,MAAM,EACFC,MACAC,aACAN,aACAI;EAUJ,IAAIG;EACJ,IAAI;GACAA,WAAW,MAAM,KAAKlB,oBAAoBmB,OAAOF,WAAAA;EACrD,SAASG,GAAG;GACR,IAAI,CAACjC,cAAciC,CAAAA,GACf,MAAMA;GAGV,OAAO;IACHC,MAAM;IACNC,SAAS3B,4BAA4B4B;IACrCN;GACJ;EACJ;EASA,IAAIN,SAASa,WAAWN,SAASO,OAAOD,YAAYb,SAASa,SACzD,MAAMvC,mBAAmByC,UAAU,6CAAA;EAQvC,MAAMC,cAAcT,SAASU,KAAKC;EAClC,IAAI,CAACF,eAAe,CAACT,SAASY,qBAC1B,MAAM7C,mBAAmByC,UAAU,oCAAA;EAUvC,IAAI,CAACnD,wBAAwBoD,WAAAA,GACzB,MAAM,IAAI5C,cAAc,yCAAA;EAO5B,IAAI,CAAC4B,SAASoB,SACV,OAAO;GACHV,MAAM;GACNC,SAAS3B,4BAA4BqC;GACrCC,OAAOjD,gBAAgBkD;GACvBjB,aAAaC,SAASU;EAC1B;EAGJ,MAAMO,gBAAgB,KAAK1B,qBAAqBE,UAAU;GACtDC,SAAS,KAAKf,QAAQe;GACtBC,UAAUK,SAASU,KAAKQ;GACxB5B,QAAQ,KAAKA;EACjB,CAAA;EAEA,IAAI6B;EACJ,IAAI;GACAA,OAAO,MAAMF,cAAcG,aAAa,EAAEtB,KAAK,CAAA;EACnD,SAASI,GAAG;GAQR,IAAI,CAAC9B,iCAAiC8B,CAAAA,GAClC,MAAMA;GAGV,KAAKZ,QAAQ+B,KAAKnD,cACdgC,GACA,0BAA0BT,SAAS6B,GAAG,qBAAqB,CAAA;GAG/D,OAAO;IACHnB,MAAM;IACNC,SAAS3B,4BAA4B8C;IACrCR,OAAOjD,gBAAgB0D;IACvBzB,aAAaC,SAASU;GAC1B;EACJ;EAMA,IAAI,CAACS,KAAKM,QACN,OAAO;GACHtB,MAAM;GACNC,SAAS3B,4BAA4BiD;GACrCX,OAAOjD,gBAAgB0D;GACvBzB,aAAaC,SAASU;EAC1B;EAKJ,IAAIV,SAASO,OAAOoB,gBAAgB;GAChC,MAAMC,QAAQ,MAAM,KAAK/C,gBAAgBgD,QAAQpC,SAASa,SAAS,IAAA;GACnE,IAAIwB,UAAU;GAEd,MAAMC,UAAU1D,qBAAqB;IACjC2D,MAAMvE,aAAawE;IACnBvB,MAAM;KACF,GAAGS;KACHS;IACJ;GACJ,CAAA;GACA,IAAIG,WAAW,KAAK5C,uBAChB2C,UAAU,MAAM,KAAK3C,sBAAsB+C,SACvClC,SAASO,OAAOoB,gBAChBI,OAAAA;GAIR,IAAI,CAACD,SACD,OAAO;IACH3B,MAAM;IACNC,SAAS3B,4BAA4B+C;IACrCT,OAAOjD,gBAAgB0D;IACvBzB,aAAaC,SAASU;GAC1B;EAER;EAWA,MAAMyB,UAAU,MAAM,KAAKpD,eAAeqD,OAAO;GAC7CC,WAAWxC,MAAMyC,SAASD,aAAaE,KAAAA;GACvCC,WAAW3C,MAAMyC,SAASE,aAAaD,KAAAA;GACvCjC,SAASa,KAAKb;GAIdmC,KAAKtB,KAAKG;GACVoB,SAASjF,aAAawE;GACtBU,OAAO;GACPC,YAAYjF,kBAAkBkF;GAC9BC,WAAW,IAAIC,KAAKA,KAAKC,IAAG,IAAKxE,0BAAAA,CAAAA,CAA4ByE,YAAW;EAC5E,CAAA;EAQA,OAAO;GACH9C,MAAM;GACN+C,gBAAAA,MARyB,KAAKlE,kBAAkBmE,KAAK;IACrDC,WAAWjB,QAAQb;IACnB+B,YAAY5D,SAAS6B;IACrBgC,UAAUnC,KAAKoC;GACnB,CAAA;GAKIxD,aAAaC,SAASU;EAC1B;CACJ;CAEA,MAAM8C,gBAAgB3D,OAAoF;EAItG,MAAM4D,eAAe,IAAI7F,gBAAgB,0CAAA;EAEzC,MAAM8F,UAAU,MAAM,KAAK1E,kBAAkB2E,QAAQ9D,MAAMqD,cAAc;EACzE,IAAI,CAACQ,SACD,MAAMD,OAAAA;EAcV,IAAIC,QAAQL,eAAexD,MAAMwD,YAC7B,MAAMI,OAAAA;EAGV,MAAMG,WAAW,MAAM,KAAK7E,eAAe8E,YAAYH,QAAQN,SAAS;EACxE,IAAI,CAACQ,UACD,MAAMH,OAAAA;EAQV,IAAIV,KAAKe,MAAMF,SAASd,SAAS,KAAKC,KAAKC,IAAG,GAC1C,MAAMS,OAAAA;EAGV,MAAM7B,QAAQ,MAAM,KAAK/C,gBAAgBgD,QAAQ+B,SAAStD,SAAS,IAAA;EAInE,MAAM6B,UAAU,MAAM,KAAKpD,eAAegF,QAAQH,QAAAA;EAElD,MAAMI,UAAwC;GAC1CC,YAAY9B,QAAQb;GACpB4C,YAAY/B,QAAQE;GACpB8B,gBAAgBhC,QAAQK;GACxB4B,OAAO1G,UAAU2G;GACjB5B,KAAKN,QAAQM;GACb6B,UAAUtG,cAAciE;GACxBsC,UAAUpC,QAAQ7B;GAClBkE,YAAY5C,MAAM2B;GAClB,GAAGjF,aAAa6D,OAAAA;EACpB;EAEA,MAAM,CAACsC,aAAaC,sBAAsB,MAAM,KAAKzF,kBAAkB0F,MAAMX,OAAAA;EAC7E,MAAM,CAACY,cAAcC,uBAAuB,MAAM,KAAK3F,mBAAmByF,MAAMX,OAAAA;EAEhF,MAAM,KAAK5E,cAAc0F,OAAO;GAC5BV,OAAO5G,WAAWuH;GAClBxB,MAAMjG,UAAU0H;GAChBC,SAAS1H,aAAa2H;GACtBC,OAAOhD,QAAQb;GACf3B,UAAU;GACVyD,WAAWjB,QAAQb;GACnB8D,WAAW3H,aAAawE;GACxBoD,SAASlD,QAAQM;GACjB6C,WAAW5B,QAAQJ,YAAY;GAC/BhD,SAAS6B,QAAQ7B;GACjBiF,kBAAkBpD,QAAQK,aAAa;GACvCgD,kBAAkBrD,QAAQE,aAAa;GACvC3B,MAAM;IAAE+E,QAAQ;IAAapC,YAAYK,QAAQL;GAAW;EAChE,CAAA;EACA,KAAKhE,SAASqG,YAAY,SAAA;EAE1B,OAAOnH,+BAA+B;GAClCkG;GACAC;GACAE;GACAC;EACJ,CAAA;CACJ;AACJ"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export * from './access-policy/index.ts';
|
|
2
2
|
export * from './authorization/index.ts';
|
|
3
|
+
export * from './backchannel-logout/index.ts';
|
|
3
4
|
export * from './client/index.ts';
|
|
5
|
+
export * from './console-login/index.ts';
|
|
6
|
+
export * from './session-credential/index.ts';
|
|
4
7
|
export * from './end-session/index.ts';
|
|
5
8
|
export * from './federated-login/index.ts';
|
|
6
9
|
export * from './grant-types/index.ts';
|
|
10
|
+
export * from './introspection/index.ts';
|
|
7
11
|
export * from './mfa-login/index.ts';
|
|
8
12
|
export * from './openid/index.ts';
|
|
9
13
|
export * from './response/index.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/oauth2/index.ts"],"names":[],"mappings":"AAOA,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/oauth2/index.ts"],"names":[],"mappings":"AAOA,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC"}
|
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { OAuth2AccessPolicyEvaluator } from "./access-policy/module.mjs";
|
|
5
5
|
import "./access-policy/index.mjs";
|
|
6
6
|
import { OAuth2AuthorizationCodeIssuer } from "./authorization/code/issuer/module.mjs";
|
|
7
|
-
import { base64URLEncode, buildOAuth2CodeChallenge, buildOAuth2TokenHash, deriveAmrAcr, generateOAuth2CodeVerifier } from "./authorization/helpers.mjs";
|
|
7
|
+
import { base64URLEncode, buildOAuth2CodeChallenge, buildOAuth2TokenHash, createOAuth2PKCE, deriveAmrAcr, generateOAuth2CodeVerifier } from "./authorization/helpers.mjs";
|
|
8
8
|
import { OAuth2AuthorizationCodeVerifier } from "./authorization/code/verifier/module.mjs";
|
|
9
9
|
import { OAuth2ClientAuthenticator } from "./client/authenticator.mjs";
|
|
10
10
|
import { assertClientGrantAllowed } from "./client/grant-type.mjs";
|
|
@@ -14,6 +14,13 @@ import { OAuth2AuthorizationCodeRequestValidator } from "./authorization/code-re
|
|
|
14
14
|
import { OAuth2AuthorizationStateManager } from "./authorization/state/module.mjs";
|
|
15
15
|
import { OAuth2Authorization } from "./authorization/module.mjs";
|
|
16
16
|
import "./authorization/index.mjs";
|
|
17
|
+
import { OAUTH2_BACKCHANNEL_LOGOUT_EVENT, OAUTH2_BACKCHANNEL_LOGOUT_MAX_AGE, OAUTH2_BACKCHANNEL_LOGOUT_TIMEOUT } from "./backchannel-logout/constants.mjs";
|
|
18
|
+
import { OAuth2BackchannelLogoutNotifier } from "./backchannel-logout/module.mjs";
|
|
19
|
+
import "./backchannel-logout/index.mjs";
|
|
20
|
+
import { CONSOLE_LOGIN_COOKIE, CONSOLE_LOGIN_TTL } from "./console-login/constants.mjs";
|
|
21
|
+
import { SESSION_COOKIE, SESSION_REFRESH_THROTTLE, SESSION_SECRET_LENGTH } from "./session-credential/constants.mjs";
|
|
22
|
+
import { createSessionSecret, hashSessionSecret } from "./session-credential/module.mjs";
|
|
23
|
+
import "./session-credential/index.mjs";
|
|
17
24
|
import { OAuth2EndSessionService } from "./end-session/service.mjs";
|
|
18
25
|
import { OAuth2EndSessionRequestValidator } from "./end-session/validator.mjs";
|
|
19
26
|
import "./end-session/index.mjs";
|
|
@@ -26,13 +33,16 @@ import { OAuth2AuthorizeGrant } from "./grant-types/authorize.mjs";
|
|
|
26
33
|
import { ClientCredentialsGrant } from "./grant-types/client-credentials.mjs";
|
|
27
34
|
import { IdentityGrantType } from "./grant-types/identity.mjs";
|
|
28
35
|
import { PasswordGrantType } from "./grant-types/password.mjs";
|
|
36
|
+
import { SESSION_TOKEN_EXPIRY_SWEEP_BATCH_SIZE } from "./session-token/constants.mjs";
|
|
29
37
|
import { SESSION_TOKEN_RELATION_MISSING_ERROR_INSTANCE, SessionTokenRelationMissingError, isSessionTokenRelationMissingError } from "./session-token/error.mjs";
|
|
30
38
|
import "./session-token/index.mjs";
|
|
31
39
|
import { OAuth2RefreshTokenGrant } from "./grant-types/refresh-token.mjs";
|
|
32
40
|
import "./grant-types/index.mjs";
|
|
41
|
+
import { OAuth2OpenIDClaimsBuilder } from "./openid/claims.mjs";
|
|
42
|
+
import { resolveIntrospectionSubject } from "./introspection/module.mjs";
|
|
43
|
+
import "./introspection/index.mjs";
|
|
33
44
|
import { OAuth2MfaLoginService } from "./mfa-login/module.mjs";
|
|
34
45
|
import "./mfa-login/index.mjs";
|
|
35
|
-
import { OAuth2OpenIDClaimsBuilder } from "./openid/claims.mjs";
|
|
36
46
|
import "./openid/index.mjs";
|
|
37
47
|
import { OAuth2ScopeAttributesResolver } from "./scope/resolver.mjs";
|
|
38
48
|
import "./scope/index.mjs";
|
|
@@ -44,4 +54,4 @@ import { OAuth2TokenRevoker } from "./token/revoker/module.mjs";
|
|
|
44
54
|
import { OAuth2TokenSigner } from "./token/signer/module.mjs";
|
|
45
55
|
import { OAuth2TokenVerifier } from "./token/verifier/module.mjs";
|
|
46
56
|
import "./token/index.mjs";
|
|
47
|
-
export { ClientCredentialsGrant, IdentityGrantType, OAUTH2_FEDERATED_LOGIN_COOKIE, OAUTH2_FEDERATED_LOGIN_TTL, OAuth2AccessPolicyEvaluator, OAuth2AccessTokenIssuer, OAuth2Authorization, OAuth2AuthorizationCodeIssuer, OAuth2AuthorizationCodeRequestValidator, OAuth2AuthorizationCodeRequestVerifier, OAuth2AuthorizationCodeVerifier, OAuth2AuthorizationStateManager, OAuth2AuthorizeGrant, OAuth2ClientAuthenticator, OAuth2EndSessionRequestValidator, OAuth2EndSessionService, OAuth2FederatedLoginRefusal, OAuth2FederatedLoginService, OAuth2MfaLoginService, OAuth2MfaTokenIssuer, OAuth2OpenIDClaimsBuilder, OAuth2OpenIDTokenIssuer, OAuth2RefreshTokenGrant, OAuth2RefreshTokenIssuer, OAuth2ScopeAttributesResolver, OAuth2TokenRevoker, OAuth2TokenSigner, OAuth2TokenVerifier, PasswordGrantType, SESSION_TOKEN_RELATION_MISSING_ERROR_INSTANCE, SessionTokenRelationMissingError, assertClientGrantAllowed, base64URLEncode, buildOAuth2BearerTokenResponse, buildOAuth2CodeChallenge, buildOAuth2TokenHash, deriveAmrAcr, generateOAuth2CodeVerifier, isSessionTokenRelationMissingError };
|
|
57
|
+
export { CONSOLE_LOGIN_COOKIE, CONSOLE_LOGIN_TTL, ClientCredentialsGrant, IdentityGrantType, OAUTH2_BACKCHANNEL_LOGOUT_EVENT, OAUTH2_BACKCHANNEL_LOGOUT_MAX_AGE, OAUTH2_BACKCHANNEL_LOGOUT_TIMEOUT, OAUTH2_FEDERATED_LOGIN_COOKIE, OAUTH2_FEDERATED_LOGIN_TTL, OAuth2AccessPolicyEvaluator, OAuth2AccessTokenIssuer, OAuth2Authorization, OAuth2AuthorizationCodeIssuer, OAuth2AuthorizationCodeRequestValidator, OAuth2AuthorizationCodeRequestVerifier, OAuth2AuthorizationCodeVerifier, OAuth2AuthorizationStateManager, OAuth2AuthorizeGrant, OAuth2BackchannelLogoutNotifier, OAuth2ClientAuthenticator, OAuth2EndSessionRequestValidator, OAuth2EndSessionService, OAuth2FederatedLoginRefusal, OAuth2FederatedLoginService, OAuth2MfaLoginService, OAuth2MfaTokenIssuer, OAuth2OpenIDClaimsBuilder, OAuth2OpenIDTokenIssuer, OAuth2RefreshTokenGrant, OAuth2RefreshTokenIssuer, OAuth2ScopeAttributesResolver, OAuth2TokenRevoker, OAuth2TokenSigner, OAuth2TokenVerifier, PasswordGrantType, SESSION_COOKIE, SESSION_REFRESH_THROTTLE, SESSION_SECRET_LENGTH, SESSION_TOKEN_EXPIRY_SWEEP_BATCH_SIZE, SESSION_TOKEN_RELATION_MISSING_ERROR_INSTANCE, SessionTokenRelationMissingError, assertClientGrantAllowed, base64URLEncode, buildOAuth2BearerTokenResponse, buildOAuth2CodeChallenge, buildOAuth2TokenHash, createOAuth2PKCE, createSessionSecret, deriveAmrAcr, generateOAuth2CodeVerifier, hashSessionSecret, isSessionTokenRelationMissingError, resolveIntrospectionSubject };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/introspection/index.ts"],"names":[],"mappings":"AAOA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { OAuth2IntrospectionSubject, OAuth2IntrospectionSubjectContext, OAuth2IntrospectionSubjectInput } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The subject half of an introspection answer: resolve the identity, build its
|
|
4
|
+
* OpenID claims and, only for an active credential, project its permissions.
|
|
5
|
+
*
|
|
6
|
+
* One owner for that projection, so a second consumer (the console session
|
|
7
|
+
* endpoint, plan 088) cannot drift from `POST /token/introspect`. The token
|
|
8
|
+
* half (verification, the `active` derivation, the RFC 7662 reporting rules)
|
|
9
|
+
* stays in the controller, which also owns the response spread order.
|
|
10
|
+
*
|
|
11
|
+
* @throws OAuth2RequestError when the subject no longer resolves.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveIntrospectionSubject(ctx: OAuth2IntrospectionSubjectContext, input: OAuth2IntrospectionSubjectInput): Promise<OAuth2IntrospectionSubject>;
|
|
14
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/introspection/module.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACR,0BAA0B,EAC1B,iCAAiC,EACjC,+BAA+B,EAClC,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC7C,GAAG,EAAE,iCAAiC,EACtC,KAAK,EAAE,+BAA+B,GACtC,OAAO,CAAC,0BAA0B,CAAC,CA2CtC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { OAuth2OpenIDClaimsBuilder } from "../openid/claims.mjs";
|
|
5
|
+
import { buildPermissionKey } from "@authup/access";
|
|
6
|
+
import { OAuth2RequestError } from "@authup/specs";
|
|
7
|
+
//#region src/core/oauth2/introspection/module.ts
|
|
8
|
+
/**
|
|
9
|
+
* The subject half of an introspection answer: resolve the identity, build its
|
|
10
|
+
* OpenID claims and, only for an active credential, project its permissions.
|
|
11
|
+
*
|
|
12
|
+
* One owner for that projection, so a second consumer (the console session
|
|
13
|
+
* endpoint, plan 088) cannot drift from `POST /token/introspect`. The token
|
|
14
|
+
* half (verification, the `active` derivation, the RFC 7662 reporting rules)
|
|
15
|
+
* stays in the controller, which also owns the response spread order.
|
|
16
|
+
*
|
|
17
|
+
* @throws OAuth2RequestError when the subject no longer resolves.
|
|
18
|
+
*/ async function resolveIntrospectionSubject(ctx, input) {
|
|
19
|
+
const identity = await ctx.identityResolver.resolve(input.subKind, input.sub);
|
|
20
|
+
if (!identity) throw OAuth2RequestError.identityInvalid();
|
|
21
|
+
const claims = new OAuth2OpenIDClaimsBuilder().fromIdentity(identity);
|
|
22
|
+
if (!input.active) return {
|
|
23
|
+
identity,
|
|
24
|
+
claims
|
|
25
|
+
};
|
|
26
|
+
const permissions = await ctx.identityPermissionProvider.getFor({
|
|
27
|
+
id: input.sub,
|
|
28
|
+
type: input.subKind,
|
|
29
|
+
clientId: input.clientId,
|
|
30
|
+
realmId: input.realmId
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
identity,
|
|
34
|
+
claims,
|
|
35
|
+
permissions: Object.values(permissions.reduce((acc, binding) => {
|
|
36
|
+
const key = buildPermissionKey(binding.permission);
|
|
37
|
+
if (!acc[key]) acc[key] = {
|
|
38
|
+
name: binding.permission.name,
|
|
39
|
+
client_id: binding.permission.clientId,
|
|
40
|
+
realm_id: binding.permission.realmId
|
|
41
|
+
};
|
|
42
|
+
return acc;
|
|
43
|
+
}, {}))
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { resolveIntrospectionSubject };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["buildPermissionKey","OAuth2RequestError","OAuth2OpenIDClaimsBuilder","resolveIntrospectionSubject","ctx","input","identity","identityResolver","resolve","subKind","sub","identityInvalid","claimsBuilder","claims","fromIdentity","active","permissions","identityPermissionProvider","getFor","id","type","clientId","realmId","Object","values","reduce","acc","binding","key","permission","name","client_id","realm_id"],"sources":["../../../../src/core/oauth2/introspection/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { buildPermissionKey } from '@authup/access';\nimport type { OAuth2TokenPermission } from '@authup/specs';\nimport { OAuth2RequestError } from '@authup/specs';\nimport { OAuth2OpenIDClaimsBuilder } from '../openid/claims.ts';\nimport type {\n OAuth2IntrospectionSubject,\n OAuth2IntrospectionSubjectContext,\n OAuth2IntrospectionSubjectInput,\n} from './types.ts';\n\n/**\n * The subject half of an introspection answer: resolve the identity, build its\n * OpenID claims and, only for an active credential, project its permissions.\n *\n * One owner for that projection, so a second consumer (the console session\n * endpoint, plan 088) cannot drift from `POST /token/introspect`. The token\n * half (verification, the `active` derivation, the RFC 7662 reporting rules)\n * stays in the controller, which also owns the response spread order.\n *\n * @throws OAuth2RequestError when the subject no longer resolves.\n */\nexport async function resolveIntrospectionSubject(\n ctx: OAuth2IntrospectionSubjectContext,\n input: OAuth2IntrospectionSubjectInput,\n) : Promise<OAuth2IntrospectionSubject> {\n const identity = await ctx.identityResolver.resolve(input.subKind, input.sub);\n if (!identity) {\n // todo: differentiate between client & user\n throw OAuth2RequestError.identityInvalid();\n }\n\n const claimsBuilder = new OAuth2OpenIDClaimsBuilder();\n const claims = claimsBuilder.fromIdentity(identity);\n\n if (!input.active) {\n return {\n identity,\n claims,\n };\n }\n\n // todo: only receive client specific permissions\n const permissions = await ctx.identityPermissionProvider.getFor({\n id: input.sub,\n type: input.subKind,\n clientId: input.clientId,\n realmId: input.realmId,\n });\n\n return {\n identity,\n claims,\n // todo: permissions property should be removed.\n permissions: Object.values(\n permissions.reduce((acc, binding) => {\n const key = buildPermissionKey(binding.permission);\n if (!acc[key]) {\n acc[key] = {\n name: binding.permission.name,\n client_id: binding.permission.clientId,\n realm_id: binding.permission.realmId,\n } as OAuth2TokenPermission;\n }\n return acc;\n }, {} as Record<string, OAuth2TokenPermission>),\n ),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;GA4BA,eAAsBG,4BAClBC,KACAC,OAAsC;CAEtC,MAAMC,WAAW,MAAMF,IAAIG,iBAAiBC,QAAQH,MAAMI,SAASJ,MAAMK,GAAG;CAC5E,IAAI,CAACJ,UAED,MAAML,mBAAmBU,gBAAe;CAI5C,MAAME,SAASD,IADWV,0BACXU,CAAAA,CAAcE,aAAaR,QAAAA;CAE1C,IAAI,CAACD,MAAMU,QACP,OAAO;EACHT;EACAO;CACJ;CAIJ,MAAMG,cAAc,MAAMZ,IAAIa,2BAA2BC,OAAO;EAC5DC,IAAId,MAAMK;EACVU,MAAMf,MAAMI;EACZY,UAAUhB,MAAMgB;EAChBC,SAASjB,MAAMiB;CACnB,CAAA;CAEA,OAAO;EACHhB;EACAO;EAEAG,aAAaO,OAAOC,OAChBR,YAAYS,QAAQC,KAAKC,YAAAA;GACrB,MAAMC,MAAM5B,mBAAmB2B,QAAQE,UAAU;GACjD,IAAI,CAACH,IAAIE,MACLF,IAAIE,OAAO;IACPE,MAAMH,QAAQE,WAAWC;IACzBC,WAAWJ,QAAQE,WAAWR;IAC9BW,UAAUL,QAAQE,WAAWP;GACjC;GAEJ,OAAOI;EACX,GAAG,CAAC,CAAA,CAAA;CAEZ;AACJ"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Identity, IdentityType } from '@authup/core-kit';
|
|
2
|
+
import type { OAuth2TokenPermission, OpenIDTokenPayload } from '@authup/specs';
|
|
3
|
+
import type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';
|
|
4
|
+
import type { IIdentityResolver } from '../../identity/resolver/types.ts';
|
|
5
|
+
export type OAuth2IntrospectionSubjectContext = {
|
|
6
|
+
identityResolver: IIdentityResolver;
|
|
7
|
+
identityPermissionProvider: IIdentityPermissionProvider;
|
|
8
|
+
};
|
|
9
|
+
export type OAuth2IntrospectionSubjectInput = {
|
|
10
|
+
/**
|
|
11
|
+
* Subject id.
|
|
12
|
+
*/
|
|
13
|
+
sub: string;
|
|
14
|
+
/**
|
|
15
|
+
* Subject kind (user, client).
|
|
16
|
+
*/
|
|
17
|
+
subKind: `${IdentityType}`;
|
|
18
|
+
/**
|
|
19
|
+
* The client the projection is scoped to. For a token this is the
|
|
20
|
+
* payload's `client_id`; for the console session endpoint it is the
|
|
21
|
+
* console's own client id, never `RequestIdentity.clientId` (which for a
|
|
22
|
+
* user identity is the user row's own unrelated column).
|
|
23
|
+
*/
|
|
24
|
+
clientId?: string | null;
|
|
25
|
+
/**
|
|
26
|
+
* The realm the projection is scoped to.
|
|
27
|
+
*/
|
|
28
|
+
realmId?: string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the credential the projection describes is usable. Permissions
|
|
31
|
+
* are resolved ONLY when it is: an inactive credential reports who it
|
|
32
|
+
* belonged to and nothing about what they may do, and a dead credential
|
|
33
|
+
* must not pay for a permission read.
|
|
34
|
+
*/
|
|
35
|
+
active: boolean;
|
|
36
|
+
};
|
|
37
|
+
export type OAuth2IntrospectionSubject = {
|
|
38
|
+
identity: Identity;
|
|
39
|
+
claims: OpenIDTokenPayload;
|
|
40
|
+
/**
|
|
41
|
+
* Present only for an `active` input.
|
|
42
|
+
*/
|
|
43
|
+
permissions?: OAuth2TokenPermission[];
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/introspection/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAE1E,MAAM,MAAM,iCAAiC,GAAG;IAC5C,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,0BAA0B,EAAE,2BAA2B,CAAC;CAC3D,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC1C;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACrC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACzC,CAAC"}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import type { Client, Identity, User } from '@authup/core-kit';
|
|
2
|
-
import type { OpenIDTokenPayload } from '@authup/specs';
|
|
2
|
+
import type { OpenIDClaims, OpenIDTokenPayload } from '@authup/specs';
|
|
3
3
|
import type { ObjectLiteral } from 'validup';
|
|
4
4
|
type AttributeMapTuple<T> = {
|
|
5
5
|
[K in keyof T]: [K, (value: unknown) => any];
|
|
6
6
|
}[keyof T];
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Keyed on `OpenIDClaims`, never on `OpenIDTokenPayload`: the latter inherits
|
|
9
|
+
* `JWTClaims`' `[key: string]: any`, so `keyof` collapses to `string | number`
|
|
10
|
+
* and the map accepts any claim name at all — a typo compiles and the claim is
|
|
11
|
+
* simply never emitted, which is the failure mode #3518 is about. `OpenIDClaims`
|
|
12
|
+
* carries no index signature, so a name that is not a claim fails the build.
|
|
13
|
+
* `Partial`, because a map declares only the claims its entity can supply.
|
|
14
|
+
*/
|
|
15
|
+
type AttributeMap<T extends Record<string, any>> = Partial<Record<keyof OpenIDClaims, keyof T | AttributeMapTuple<T>>>;
|
|
8
16
|
export declare class OAuth2OpenIDClaimsBuilder {
|
|
9
17
|
protected clientMap: AttributeMap<Client>;
|
|
10
18
|
protected userMap: AttributeMap<User>;
|
|
@@ -16,6 +24,16 @@ export declare class OAuth2OpenIDClaimsBuilder {
|
|
|
16
24
|
fromIdentity(identity: Identity): OpenIDTokenPayload;
|
|
17
25
|
fromClient(input: Client): OpenIDTokenPayload;
|
|
18
26
|
fromUser(input: User): OpenIDTokenPayload;
|
|
27
|
+
/**
|
|
28
|
+
* A claim is emitted only for a value that exists AND is not nullish.
|
|
29
|
+
*
|
|
30
|
+
* The map reads entity columns, several of which are nullable, and OIDC
|
|
31
|
+
* models an unavailable claim as one that is not returned rather than one
|
|
32
|
+
* returned as `null` — so a user without a display name must omit
|
|
33
|
+
* `nickname`, not answer `nickname: null` (#3518). Emitting the null also
|
|
34
|
+
* put a JSON `null` claim value into every id_token, which no relying
|
|
35
|
+
* party expects.
|
|
36
|
+
*/
|
|
19
37
|
protected extract<T extends ObjectLiteral = ObjectLiteral>(attributeMap: AttributeMap<T>, attributes: T): OpenIDTokenPayload;
|
|
20
38
|
}
|
|
21
39
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/openid/claims.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,MAAM,EACN,QAAQ,EACR,IAAI,EACP,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../../../../src/core/oauth2/openid/claims.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,MAAM,EACN,QAAQ,EACR,IAAI,EACP,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,KAAK,iBAAiB,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,GAAG,CAAC;CAC/C,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;;;;GAOG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAC7D,MAAM,YAAY,EACtB,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAC7B,CAAC,CAAC;AAEH,qBAAa,yBAAyB;IAClC,SAAS,CAAC,SAAS,EAAG,YAAY,CAAC,MAAM,CAAC,CAcxC;IAEF,SAAS,CAAC,OAAO,EAAG,YAAY,CAAC,IAAI,CAAC,CAmBpC;IAEF;;;;OAIG;IACH,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAI,kBAAkB;IAQrD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAI,kBAAkB;IAI9C,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAI,kBAAkB;IAI1C;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,aAAa,GAAG,aAAa,EACrD,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,EAC7B,UAAU,EAAE,CAAC,GACb,kBAAkB;CAuCzB"}
|