@authup/server-core 1.0.0-beta.62 → 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 +9 -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 +14 -0
- 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/adapters/oauth2/grant-types/refresh_token.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +8 -2
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.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/client/module.mjs +1 -1
- package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +23 -1
- package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +86 -47
- 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/authenticator-challenge/module.d.ts +2 -0
- package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +21 -3
- package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs.map +1 -1
- 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 +44 -21
- 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 +117 -26
- 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 +10 -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 -397
- 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.d.ts +3 -1
- package/dist/app/modules/database/repositories/identity-provider/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/identity-provider/repository.mjs +3 -3
- package/dist/app/modules/database/repositories/identity-provider/repository.mjs.map +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 +70 -38
- 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 +3 -1
- package/dist/app/modules/oauth2/constants.d.ts.map +1 -1
- package/dist/app/modules/oauth2/constants.mjs +2 -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 +14 -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 +2 -0
- package/dist/app/modules/oauth2/repositories/constants.d.ts.map +1 -1
- package/dist/app/modules/oauth2/repositories/constants.mjs +2 -0
- package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/federated-login/index.d.ts +2 -0
- package/dist/app/modules/oauth2/repositories/federated-login/index.d.ts.map +1 -0
- package/dist/app/modules/oauth2/repositories/federated-login/index.mjs +5 -0
- package/dist/app/modules/oauth2/repositories/federated-login/store.d.ts +9 -0
- package/dist/app/modules/oauth2/repositories/federated-login/store.d.ts.map +1 -0
- package/dist/app/modules/oauth2/repositories/federated-login/store.mjs +33 -0
- package/dist/app/modules/oauth2/repositories/federated-login/store.mjs.map +1 -0
- package/dist/app/modules/oauth2/repositories/index.d.ts +2 -0
- package/dist/app/modules/oauth2/repositories/index.d.ts.map +1 -1
- package/dist/app/modules/oauth2/repositories/index.mjs +5 -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 +17 -3
- 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/identity-provider/types.d.ts +9 -1
- package/dist/core/entities/identity-provider/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/index.mjs +2 -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 +2 -2
- package/dist/core/identity/provider/account/module.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/index.mjs +2 -1
- package/dist/core/identity/provider/authentication/protocols/index.mjs +2 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.d.ts +46 -0
- package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.d.ts.map +1 -0
- package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs +89 -0
- package/dist/core/identity/provider/authentication/protocols/oauth2/assurance.mjs.map +1 -0
- package/dist/core/identity/provider/authentication/protocols/oauth2/index.d.ts +1 -0
- package/dist/core/identity/provider/authentication/protocols/oauth2/index.d.ts.map +1 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/index.mjs +2 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/module.d.ts.map +1 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs +9 -2
- package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
- package/dist/core/identity/provider/index.mjs +2 -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 +14 -4
- 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 +15 -2
- 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.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/module.mjs +6 -4
- package/dist/core/oauth2/authorization/module.mjs.map +1 -1
- package/dist/core/oauth2/authorization/state/types.d.ts +8 -0
- package/dist/core/oauth2/authorization/state/types.d.ts.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/constants.d.ts +22 -0
- package/dist/core/oauth2/federated-login/constants.d.ts.map +1 -0
- package/dist/core/oauth2/federated-login/constants.mjs +27 -0
- package/dist/core/oauth2/federated-login/constants.mjs.map +1 -0
- package/dist/core/oauth2/federated-login/index.d.ts +1 -0
- package/dist/core/oauth2/federated-login/index.d.ts.map +1 -1
- package/dist/core/oauth2/federated-login/index.mjs +2 -1
- package/dist/core/oauth2/federated-login/module.d.ts +12 -3
- package/dist/core/oauth2/federated-login/module.d.ts.map +1 -1
- package/dist/core/oauth2/federated-login/module.mjs +98 -42
- package/dist/core/oauth2/federated-login/module.mjs.map +1 -1
- package/dist/core/oauth2/federated-login/types.d.ts +82 -24
- package/dist/core/oauth2/federated-login/types.d.ts.map +1 -1
- package/dist/core/oauth2/federated-login/types.mjs +5 -0
- package/dist/core/oauth2/federated-login/types.mjs.map +1 -1
- package/dist/core/oauth2/grant-types/authorize.mjs +1 -1
- package/dist/core/oauth2/grant-types/client-credentials.mjs +1 -1
- package/dist/core/oauth2/grant-types/identity.mjs +1 -1
- package/dist/core/oauth2/grant-types/password.mjs +1 -1
- package/dist/core/oauth2/grant-types/refresh-token.mjs +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 +15 -4
- 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/oauth2/token/verifier/module.d.ts.map +1 -1
- package/dist/core/oauth2/token/verifier/module.mjs +3 -3
- package/dist/core/oauth2/token/verifier/module.mjs.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 +573 -163
- 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 +32 -26
- 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,230 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { SYSTEM_CLIENT_SCOPE_NAMES } from "../../../../../core/entities/client/system-clients.mjs";
|
|
5
|
+
import { createOAuth2PKCE } from "../../../../../core/oauth2/authorization/helpers.mjs";
|
|
6
|
+
import { CONSOLE_LOGIN_COOKIE, CONSOLE_LOGIN_TTL } from "../../../../../core/oauth2/console-login/constants.mjs";
|
|
7
|
+
import { createSessionSecret } from "../../../../../core/oauth2/session-credential/module.mjs";
|
|
8
|
+
import "../../../../../core/index.mjs";
|
|
9
|
+
import { isSameOriginRequest } from "../../../request/helpers/same-origin.mjs";
|
|
10
|
+
import "../../../request/index.mjs";
|
|
11
|
+
import { setSessionCookie } from "../../../cookie/session.mjs";
|
|
12
|
+
import "../../../cookie/index.mjs";
|
|
13
|
+
import { INTERNAL_HTTP_CLIENT_FACTORY_STORE_KEY } from "../../../middleware/built-in/internal-http-client.mjs";
|
|
14
|
+
import "../../../middleware/index.mjs";
|
|
15
|
+
import { createNanoID, getURLBasePath } from "@authup/kit";
|
|
16
|
+
import { BadRequestError, InternalError } from "@authup/errors";
|
|
17
|
+
import { OAuth2ErrorCode, OAuth2SubKind, OAuth2TokenKind, serializeOAuth2Scope } from "@authup/specs";
|
|
18
|
+
import { sendRedirect } from "routup";
|
|
19
|
+
import { setResponseCookie, unsetResponseCookie, useRequestCookie } from "@routup/basic/cookie";
|
|
20
|
+
import { useRequestQuery } from "@routup/basic/query";
|
|
21
|
+
//#region src/adapters/http/controllers/workflows/console-login/module.ts
|
|
22
|
+
/**
|
|
23
|
+
* The OAuth2 error codes the callback echoes back to the console. Closed on
|
|
24
|
+
* purpose: everything else collapses into one generic marker, so nothing a
|
|
25
|
+
* redirect carries reaches a rendered page as-is.
|
|
26
|
+
*
|
|
27
|
+
* `access_denied` is the one the consoles render specially (an accessPolicyId
|
|
28
|
+
* on the console client); the other two land on the same generic notice but
|
|
29
|
+
* say something true in a log or a bug report.
|
|
30
|
+
*/ const CALLBACK_ERROR_CODES = [
|
|
31
|
+
OAuth2ErrorCode.ACCESS_DENIED,
|
|
32
|
+
OAuth2ErrorCode.LOGIN_REQUIRED,
|
|
33
|
+
OAuth2ErrorCode.CONSENT_REQUIRED
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* A console's server-side login (plan 088): the kick and the code redemption.
|
|
37
|
+
* Both exist so no OAuth2 token ever reaches the console's JavaScript. The
|
|
38
|
+
* browser holds an opaque, `HttpOnly` credential naming its `auth_sessions`
|
|
39
|
+
* row instead.
|
|
40
|
+
*
|
|
41
|
+
* One instance per console, parameterized by the client it authenticates
|
|
42
|
+
* against and the path it is served under (`console/account`,
|
|
43
|
+
* `console/admin`: the two pending-login cookies stay apart by RFC 6265 path
|
|
44
|
+
* matching); the account and the admin console differ in nothing else here.
|
|
45
|
+
*/ var ConsoleLogin = class {
|
|
46
|
+
definition;
|
|
47
|
+
baseURL;
|
|
48
|
+
loginStore;
|
|
49
|
+
sessionRepository;
|
|
50
|
+
sessionManager;
|
|
51
|
+
tokenVerifier;
|
|
52
|
+
tokenRevoker;
|
|
53
|
+
logger;
|
|
54
|
+
constructor(definition, ctx) {
|
|
55
|
+
this.definition = definition;
|
|
56
|
+
this.baseURL = ctx.options.baseURL;
|
|
57
|
+
this.loginStore = ctx.loginStore;
|
|
58
|
+
this.sessionRepository = ctx.sessionRepository;
|
|
59
|
+
this.sessionManager = ctx.sessionManager;
|
|
60
|
+
this.tokenVerifier = ctx.tokenVerifier;
|
|
61
|
+
this.tokenRevoker = ctx.tokenRevoker;
|
|
62
|
+
this.logger = ctx.logger;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Start a console login: mint PKCE + `state`, park them in the pending
|
|
66
|
+
* login, and send the browser to `/authorize`.
|
|
67
|
+
*
|
|
68
|
+
* The verifier never reaches the browser, which is what moves the code
|
|
69
|
+
* exchange server-side: the callback is the only party that can redeem the
|
|
70
|
+
* code it comes back with.
|
|
71
|
+
*/ async login(event) {
|
|
72
|
+
const realmId = useRequestQuery(event, "realmId");
|
|
73
|
+
if (typeof realmId !== "string" || realmId.length === 0) throw new BadRequestError("A realm is required to sign in.");
|
|
74
|
+
const pkce = await createOAuth2PKCE();
|
|
75
|
+
const state = createNanoID();
|
|
76
|
+
const redirectUri = this.buildCallbackURL();
|
|
77
|
+
const id = await this.loginStore.save({
|
|
78
|
+
state,
|
|
79
|
+
codeVerifier: pkce.code_verifier,
|
|
80
|
+
redirectUri,
|
|
81
|
+
realmId
|
|
82
|
+
});
|
|
83
|
+
this.setLoginCookie(event, id);
|
|
84
|
+
const url = new URL(`${this.trimmedBaseURL()}/authorize`);
|
|
85
|
+
url.searchParams.set("response_type", "code");
|
|
86
|
+
url.searchParams.set("client_id", this.definition.clientName);
|
|
87
|
+
url.searchParams.set("realm_id", realmId);
|
|
88
|
+
url.searchParams.set("scope", serializeOAuth2Scope(SYSTEM_CLIENT_SCOPE_NAMES));
|
|
89
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
90
|
+
url.searchParams.set("state", state);
|
|
91
|
+
url.searchParams.set("code_challenge", pkce.code_challenge);
|
|
92
|
+
url.searchParams.set("code_challenge_method", pkce.code_challenge_method);
|
|
93
|
+
url.searchParams.set("prompt", "select_account");
|
|
94
|
+
event.response.headers.set("cache-control", "no-store");
|
|
95
|
+
return sendRedirect(event, url.href);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Redeem the authorization code and hand the browser its session cookie.
|
|
99
|
+
*
|
|
100
|
+
* Nothing token-shaped leaves this method: the pair is verified, used to
|
|
101
|
+
* find the session it belongs to, and revoked before the response is
|
|
102
|
+
* built. What the browser gets back is the opaque `auth_sessions.secret`.
|
|
103
|
+
*/ async callback(event) {
|
|
104
|
+
if (!isSameOriginRequest(event, this.baseURL, { logger: this.logger })) throw new BadRequestError("The login request did not originate from this origin.");
|
|
105
|
+
const pendingId = useRequestCookie(event, CONSOLE_LOGIN_COOKIE);
|
|
106
|
+
this.unsetLoginCookie(event);
|
|
107
|
+
if (typeof pendingId !== "string" || pendingId.length === 0) return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);
|
|
108
|
+
const query = useRequestQuery(event);
|
|
109
|
+
const pending = await this.loginStore.find(pendingId);
|
|
110
|
+
if (!pending) return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);
|
|
111
|
+
if (typeof query.state !== "string" || query.state !== pending.state) return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);
|
|
112
|
+
const consumed = await this.loginStore.consume(pendingId);
|
|
113
|
+
if (!consumed) return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);
|
|
114
|
+
if (typeof query.error === "string" && query.error.length > 0) return this.refuse(event, this.mapCallbackError(query.error));
|
|
115
|
+
if (typeof query.code !== "string" || query.code.length === 0) return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);
|
|
116
|
+
let payload;
|
|
117
|
+
let session;
|
|
118
|
+
try {
|
|
119
|
+
const grant = await this.resolveHttpClient(event).token.createWithAuthorizationCode({
|
|
120
|
+
code: query.code,
|
|
121
|
+
redirect_uri: consumed.redirectUri,
|
|
122
|
+
client_id: this.definition.clientName,
|
|
123
|
+
realm_id: consumed.realmId,
|
|
124
|
+
code_verifier: consumed.codeVerifier
|
|
125
|
+
});
|
|
126
|
+
payload = await this.tokenVerifier.verify(grant.access_token);
|
|
127
|
+
await this.revokeGrant(grant.access_token, grant.refresh_token);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
this.logger?.warn(`The console login could not be completed: ${e}`);
|
|
130
|
+
return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);
|
|
131
|
+
}
|
|
132
|
+
if (payload.kind !== OAuth2TokenKind.ACCESS || payload.sub_kind !== OAuth2SubKind.USER || !payload.sub || !payload.session_id || !payload.client_id || !payload.scope) return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);
|
|
133
|
+
try {
|
|
134
|
+
session = await this.sessionManager.findOneById(payload.session_id);
|
|
135
|
+
} catch {
|
|
136
|
+
session = null;
|
|
137
|
+
}
|
|
138
|
+
if (!session) return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);
|
|
139
|
+
const ttl = new Date(session.expiresAt).getTime() - Date.now();
|
|
140
|
+
if (ttl <= 0) return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);
|
|
141
|
+
const secret = createSessionSecret();
|
|
142
|
+
await this.sessionRepository.updateSecret(session.id, secret);
|
|
143
|
+
setSessionCookie(event, this.baseURL, secret, ttl);
|
|
144
|
+
event.response.headers.set("cache-control", "no-store");
|
|
145
|
+
return sendRedirect(event, this.buildConsoleURL());
|
|
146
|
+
}
|
|
147
|
+
resolveHttpClient(event) {
|
|
148
|
+
const factory = event.store[INTERNAL_HTTP_CLIENT_FACTORY_STORE_KEY];
|
|
149
|
+
if (!factory) throw new InternalError("No http client is available to redeem the authorization code.");
|
|
150
|
+
return factory();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Revoke what the exchange returned. Best effort per token: a revoke that
|
|
154
|
+
* fails must not leave the visitor without a session, and both tokens are
|
|
155
|
+
* unreachable to anyone but this process either way.
|
|
156
|
+
*/ async revokeGrant(accessToken, refreshToken) {
|
|
157
|
+
const tokens = refreshToken ? [accessToken, refreshToken] : [accessToken];
|
|
158
|
+
for (const token of tokens) try {
|
|
159
|
+
const payload = await this.tokenVerifier.verify(token, { skipActiveCheck: true });
|
|
160
|
+
await this.tokenRevoker.revoke(payload);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
this.logger?.warn(`A console login token could not be revoked: ${e}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
mapCallbackError(input) {
|
|
166
|
+
if (CALLBACK_ERROR_CODES.includes(input)) return input;
|
|
167
|
+
return OAuth2ErrorCode.INVALID_REQUEST;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Land a refusal on the console rather than in a JSON body: this is a
|
|
171
|
+
* top-level navigation at the end of a login, and the person behind it has
|
|
172
|
+
* to be told something. The marker set is closed, so nothing
|
|
173
|
+
* attacker-shaped is echoed.
|
|
174
|
+
*/ refuse(event, error) {
|
|
175
|
+
const params = new URLSearchParams({ error });
|
|
176
|
+
event.response.headers.set("cache-control", "no-store");
|
|
177
|
+
const target = this.definition.refusalPath ? `${this.buildConsoleURL()}/${this.definition.refusalPath}` : this.buildConsoleURL();
|
|
178
|
+
return sendRedirect(event, `${target}?${params.toString()}`);
|
|
179
|
+
}
|
|
180
|
+
trimmedBaseURL() {
|
|
181
|
+
return this.baseURL.replace(/\/+$/, "");
|
|
182
|
+
}
|
|
183
|
+
basePath() {
|
|
184
|
+
return getURLBasePath(this.baseURL);
|
|
185
|
+
}
|
|
186
|
+
buildConsoleURL() {
|
|
187
|
+
return getURLBasePath(this.definition.consoleUrl);
|
|
188
|
+
}
|
|
189
|
+
buildCallbackURL() {
|
|
190
|
+
return `${this.trimmedBaseURL()}/${this.definition.segment}/callback`;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Whether the cookies may carry the `Secure` flag. Read from the parsed
|
|
194
|
+
* URL rather than the raw string: `publicUrl` is validated but never
|
|
195
|
+
* canonicalized, so a configured `HTTPS://...` would leave a prefix test
|
|
196
|
+
* false and silently drop the flag.
|
|
197
|
+
*/ isSecureBaseURL() {
|
|
198
|
+
try {
|
|
199
|
+
return new URL(this.baseURL).protocol === "https:";
|
|
200
|
+
} catch {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Scoped to the routes that read it, so it never rides an ordinary API
|
|
206
|
+
* request and two consoles keep separate logins in flight, and
|
|
207
|
+
* `SameSite=Lax` because the return leg is a top-level navigation that
|
|
208
|
+
* may come back through an external identity provider, which a `Strict`
|
|
209
|
+
* cookie would not accompany. It holds nothing but the id of a single-use
|
|
210
|
+
* cache entry.
|
|
211
|
+
*/ buildLoginCookiePath() {
|
|
212
|
+
return `${this.basePath()}/${this.definition.segment}`;
|
|
213
|
+
}
|
|
214
|
+
setLoginCookie(event, value) {
|
|
215
|
+
setResponseCookie(event, CONSOLE_LOGIN_COOKIE, value, {
|
|
216
|
+
httpOnly: true,
|
|
217
|
+
sameSite: "lax",
|
|
218
|
+
secure: this.isSecureBaseURL(),
|
|
219
|
+
path: this.buildLoginCookiePath(),
|
|
220
|
+
maxAge: CONSOLE_LOGIN_TTL / 1e3
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
unsetLoginCookie(event) {
|
|
224
|
+
unsetResponseCookie(event, CONSOLE_LOGIN_COOKIE, { path: this.buildLoginCookiePath() });
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
//#endregion
|
|
228
|
+
export { ConsoleLogin };
|
|
229
|
+
|
|
230
|
+
//# sourceMappingURL=module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["BadRequestError","InternalError","createNanoID","getURLBasePath","OAuth2ErrorCode","OAuth2SubKind","OAuth2TokenKind","serializeOAuth2Scope","setResponseCookie","unsetResponseCookie","useRequestCookie","useRequestQuery","sendRedirect","CONSOLE_LOGIN_COOKIE","CONSOLE_LOGIN_TTL","SYSTEM_CLIENT_SCOPE_NAMES","createOAuth2PKCE","createSessionSecret","setSessionCookie","INTERNAL_HTTP_CLIENT_FACTORY_STORE_KEY","isSameOriginRequest","CALLBACK_ERROR_CODES","ACCESS_DENIED","LOGIN_REQUIRED","CONSENT_REQUIRED","ConsoleLogin","definition","baseURL","loginStore","sessionRepository","sessionManager","tokenVerifier","tokenRevoker","logger","ctx","options","login","event","realmId","length","pkce","state","redirectUri","buildCallbackURL","id","save","codeVerifier","code_verifier","setLoginCookie","url","URL","trimmedBaseURL","searchParams","set","clientName","code_challenge","code_challenge_method","response","headers","href","callback","pendingId","unsetLoginCookie","refuse","INVALID_REQUEST","query","pending","find","consumed","consume","error","mapCallbackError","code","payload","session","client","resolveHttpClient","grant","token","createWithAuthorizationCode","redirect_uri","client_id","realm_id","verify","access_token","revokeGrant","refresh_token","e","warn","INVALID_GRANT","kind","ACCESS","sub_kind","USER","sub","session_id","scope","findOneById","ttl","Date","expiresAt","getTime","now","secret","updateSecret","buildConsoleURL","factory","store","accessToken","refreshToken","tokens","skipActiveCheck","revoke","input","includes","params","URLSearchParams","target","refusalPath","toString","replace","basePath","consoleUrl","segment","isSecureBaseURL","protocol","buildLoginCookiePath","value","httpOnly","sameSite","secure","path","maxAge"],"sources":["../../../../../../src/adapters/http/controllers/workflows/console-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 type { Session } from '@authup/core-kit';\nimport type { IClient } from '@authup/core-http-kit';\nimport { BadRequestError, InternalError } from '@authup/errors';\nimport { createNanoID, getURLBasePath } from '@authup/kit';\nimport type { Logger } from '@authup/server-kit';\nimport type { OAuth2TokenPayload } from '@authup/specs';\nimport {\n OAuth2ErrorCode,\n OAuth2SubKind,\n OAuth2TokenKind,\n serializeOAuth2Scope,\n} from '@authup/specs';\nimport { setResponseCookie, unsetResponseCookie, useRequestCookie } from '@routup/basic/cookie';\nimport { useRequestQuery } from '@routup/basic/query';\nimport type { IAppEvent } from 'routup';\nimport { sendRedirect } from 'routup';\nimport {\n CONSOLE_LOGIN_COOKIE,\n CONSOLE_LOGIN_TTL,\n SYSTEM_CLIENT_SCOPE_NAMES,\n createOAuth2PKCE,\n createSessionSecret,\n} from '../../../../../core/index.ts';\nimport type {\n IConsoleLoginStore,\n IOAuth2TokenRevoker,\n IOAuth2TokenVerifier,\n ISessionManager,\n ISessionRepository,\n} from '../../../../../core/index.ts';\nimport { setSessionCookie } from '../../../cookie/index.ts';\nimport { INTERNAL_HTTP_CLIENT_FACTORY_STORE_KEY } from '../../../middleware/index.ts';\nimport { isSameOriginRequest } from '../../../request/index.ts';\nimport type { ConsoleLoginContext, ConsoleLoginDefinition } from './types.ts';\n\n/**\n * The OAuth2 error codes the callback echoes back to the console. Closed on\n * purpose: everything else collapses into one generic marker, so nothing a\n * redirect carries reaches a rendered page as-is.\n *\n * `access_denied` is the one the consoles render specially (an accessPolicyId\n * on the console client); the other two land on the same generic notice but\n * say something true in a log or a bug report.\n */\nconst CALLBACK_ERROR_CODES : string[] = [\n OAuth2ErrorCode.ACCESS_DENIED,\n OAuth2ErrorCode.LOGIN_REQUIRED,\n OAuth2ErrorCode.CONSENT_REQUIRED,\n];\n\n/**\n * A console's server-side login (plan 088): the kick and the code redemption.\n * Both exist so no OAuth2 token ever reaches the console's JavaScript. The\n * browser holds an opaque, `HttpOnly` credential naming its `auth_sessions`\n * row instead.\n *\n * One instance per console, parameterized by the client it authenticates\n * against and the path it is served under (`console/account`,\n * `console/admin`: the two pending-login cookies stay apart by RFC 6265 path\n * matching); the account and the admin console differ in nothing else here.\n */\nexport class ConsoleLogin {\n protected definition : ConsoleLoginDefinition;\n\n protected baseURL : string;\n\n protected loginStore : IConsoleLoginStore;\n\n protected sessionRepository : ISessionRepository;\n\n protected sessionManager : ISessionManager;\n\n protected tokenVerifier : IOAuth2TokenVerifier;\n\n protected tokenRevoker : IOAuth2TokenRevoker;\n\n protected logger? : Logger;\n\n constructor(definition: ConsoleLoginDefinition, ctx: ConsoleLoginContext) {\n this.definition = definition;\n this.baseURL = ctx.options.baseURL;\n this.loginStore = ctx.loginStore;\n this.sessionRepository = ctx.sessionRepository;\n this.sessionManager = ctx.sessionManager;\n this.tokenVerifier = ctx.tokenVerifier;\n this.tokenRevoker = ctx.tokenRevoker;\n this.logger = ctx.logger;\n }\n\n /**\n * Start a console login: mint PKCE + `state`, park them in the pending\n * login, and send the browser to `/authorize`.\n *\n * The verifier never reaches the browser, which is what moves the code\n * exchange server-side: the callback is the only party that can redeem the\n * code it comes back with.\n */\n async login(event: IAppEvent) : Promise<Response> {\n const realmId = useRequestQuery(event, 'realmId');\n if (typeof realmId !== 'string' || realmId.length === 0) {\n // The console client is identified by NAME, and a name needs a\n // realm hint at `/authorize` and at `/token` alike. The console\n // asks the visitor for a realm before it links here, so a missing\n // one is a broken caller rather than a user mistake.\n throw new BadRequestError('A realm is required to sign in.');\n }\n\n const pkce = await createOAuth2PKCE();\n const state = createNanoID();\n const redirectUri = this.buildCallbackURL();\n\n const id = await this.loginStore.save({\n state,\n codeVerifier: pkce.code_verifier,\n redirectUri,\n realmId,\n });\n\n this.setLoginCookie(event, id);\n\n const url = new URL(`${this.trimmedBaseURL()}/authorize`);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('client_id', this.definition.clientName);\n url.searchParams.set('realm_id', realmId);\n url.searchParams.set('scope', serializeOAuth2Scope(SYSTEM_CLIENT_SCOPE_NAMES));\n url.searchParams.set('redirect_uri', redirectUri);\n url.searchParams.set('state', state);\n url.searchParams.set('code_challenge', pkce.code_challenge);\n url.searchParams.set('code_challenge_method', pkce.code_challenge_method);\n // The default the consoles' client-side kick sends, so a lingering\n // session still offers \"continue as / use another account\".\n url.searchParams.set('prompt', 'select_account');\n\n event.response.headers.set('cache-control', 'no-store');\n\n return sendRedirect(event, url.href);\n }\n\n /**\n * Redeem the authorization code and hand the browser its session cookie.\n *\n * Nothing token-shaped leaves this method: the pair is verified, used to\n * find the session it belongs to, and revoked before the response is\n * built. What the browser gets back is the opaque `auth_sessions.secret`.\n */\n async callback(event: IAppEvent) : Promise<Response> {\n // Finding 4 of plan 088. Without this, an attacker who plants their\n // own login cookie in the victim's browser from a sibling subdomain\n // and then navigates them here logs the VICTIM into the ATTACKER's\n // account. Every real flow arrives from the same-origin `/authorize`\n // document, so nothing legitimate is refused.\n if (!isSameOriginRequest(event, this.baseURL, { logger: this.logger })) {\n throw new BadRequestError('The login request did not originate from this origin.');\n }\n\n const pendingId = useRequestCookie(event, CONSOLE_LOGIN_COOKIE);\n\n // Cleared whichever way this goes: it is single use, and a cookie\n // outliving its pending login only produces a confusing refusal on\n // some later page load.\n this.unsetLoginCookie(event);\n\n if (typeof pendingId !== 'string' || pendingId.length === 0) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);\n }\n\n const query = useRequestQuery(event);\n\n // Read before consuming: one browser holds one login cookie per\n // console, so a second tab's kick replaces the first tab's id. A stale\n // callback that consumed first would burn the live login of the tab\n // that is still waiting.\n const pending = await this.loginStore.find(pendingId);\n if (!pending) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);\n }\n\n if (typeof query.state !== 'string' || query.state !== pending.state) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);\n }\n\n const consumed = await this.loginStore.consume(pendingId);\n if (!consumed) {\n // Lost a race with another callback carrying the same state.\n return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);\n }\n\n if (typeof query.error === 'string' && query.error.length > 0) {\n return this.refuse(event, this.mapCallbackError(query.error));\n }\n\n if (typeof query.code !== 'string' || query.code.length === 0) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_REQUEST);\n }\n\n let payload : OAuth2TokenPayload;\n let session : Session | null;\n\n try {\n const client = this.resolveHttpClient(event);\n\n // RFC 6749 §4.1.3: the token request repeats the `redirect_uri`\n // the authorization request carried, and the verifier compares the\n // raw stored string, so it is replayed from the pending login,\n // never rebuilt from this URL.\n const grant = await client.token.createWithAuthorizationCode({\n code: query.code,\n redirect_uri: consumed.redirectUri,\n client_id: this.definition.clientName,\n realm_id: consumed.realmId,\n code_verifier: consumed.codeVerifier,\n });\n\n payload = await this.tokenVerifier.verify(grant.access_token);\n\n // Both tokens die here, not just the refresh token: an access\n // token stays a live bearer for its whole lifetime, and the point\n // of this flow is that no token outlives the redemption. The\n // session the pair belongs to is what the browser keeps.\n await this.revokeGrant(grant.access_token, grant.refresh_token);\n } catch (e) {\n this.logger?.warn(`The console login could not be completed: ${e}`);\n\n return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);\n }\n\n if (\n payload.kind !== OAuth2TokenKind.ACCESS ||\n payload.sub_kind !== OAuth2SubKind.USER ||\n !payload.sub ||\n !payload.session_id ||\n !payload.client_id ||\n !payload.scope\n ) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);\n }\n\n try {\n session = await this.sessionManager.findOneById(payload.session_id);\n } catch {\n session = null;\n }\n\n if (!session) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);\n }\n\n const ttl = new Date(session.expiresAt).getTime() - Date.now();\n if (ttl <= 0) {\n return this.refuse(event, OAuth2ErrorCode.INVALID_GRANT);\n }\n\n const secret = createSessionSecret();\n await this.sessionRepository.updateSecret(session.id, secret);\n\n setSessionCookie(event, this.baseURL, secret, ttl);\n\n event.response.headers.set('cache-control', 'no-store');\n\n return sendRedirect(event, this.buildConsoleURL());\n }\n\n // ---------------------------------------------------------\n\n protected resolveHttpClient(event: IAppEvent) : IClient {\n const factory = event.store[INTERNAL_HTTP_CLIENT_FACTORY_STORE_KEY] as (() => IClient) | undefined;\n if (!factory) {\n throw new InternalError('No http client is available to redeem the authorization code.');\n }\n\n return factory();\n }\n\n /**\n * Revoke what the exchange returned. Best effort per token: a revoke that\n * fails must not leave the visitor without a session, and both tokens are\n * unreachable to anyone but this process either way.\n */\n protected async revokeGrant(accessToken: string, refreshToken?: string) : Promise<void> {\n const tokens = refreshToken ? [accessToken, refreshToken] : [accessToken];\n\n for (const token of tokens) {\n try {\n const payload = await this.tokenVerifier.verify(token, { skipActiveCheck: true });\n\n await this.tokenRevoker.revoke(payload);\n } catch (e) {\n this.logger?.warn(`A console login token could not be revoked: ${e}`);\n }\n }\n }\n\n protected mapCallbackError(input: string) : `${OAuth2ErrorCode}` {\n if (CALLBACK_ERROR_CODES.includes(input)) {\n return input as `${OAuth2ErrorCode}`;\n }\n\n return OAuth2ErrorCode.INVALID_REQUEST;\n }\n\n /**\n * Land a refusal on the console rather than in a JSON body: this is a\n * top-level navigation at the end of a login, and the person behind it has\n * to be told something. The marker set is closed, so nothing\n * attacker-shaped is echoed.\n */\n protected refuse(event: IAppEvent, error: `${OAuth2ErrorCode}`) : Response {\n const params = new URLSearchParams({ error });\n\n event.response.headers.set('cache-control', 'no-store');\n\n const target = this.definition.refusalPath ?\n `${this.buildConsoleURL()}/${this.definition.refusalPath}` :\n this.buildConsoleURL();\n\n return sendRedirect(event, `${target}?${params.toString()}`);\n }\n\n // ---------------------------------------------------------\n\n protected trimmedBaseURL() : string {\n return this.baseURL.replace(/\\/+$/, '');\n }\n\n protected basePath() : string {\n return getURLBasePath(this.baseURL);\n }\n\n protected buildConsoleURL() : string {\n return getURLBasePath(this.definition.consoleUrl);\n }\n\n protected buildCallbackURL() : string {\n return `${this.trimmedBaseURL()}/${this.definition.segment}/callback`;\n }\n\n /**\n * Whether the cookies may carry the `Secure` flag. Read from the parsed\n * URL rather than the raw string: `publicUrl` is validated but never\n * canonicalized, so a configured `HTTPS://...` would leave a prefix test\n * false and silently drop the flag.\n */\n protected isSecureBaseURL() : boolean {\n try {\n return new URL(this.baseURL).protocol === 'https:';\n } catch {\n return false;\n }\n }\n\n /**\n * Scoped to the routes that read it, so it never rides an ordinary API\n * request and two consoles keep separate logins in flight, and\n * `SameSite=Lax` because the return leg is a top-level navigation that\n * may come back through an external identity provider, which a `Strict`\n * cookie would not accompany. It holds nothing but the id of a single-use\n * cache entry.\n */\n protected buildLoginCookiePath() : string {\n // The API's own path, not the console's: this cookie is set and read\n // by the two routes below, which stay on this origin.\n return `${this.basePath()}/${this.definition.segment}`;\n }\n\n protected setLoginCookie(event: IAppEvent, value: string) : void {\n setResponseCookie(event, CONSOLE_LOGIN_COOKIE, value, {\n httpOnly: true,\n sameSite: 'lax',\n secure: this.isSecureBaseURL(),\n path: this.buildLoginCookiePath(),\n maxAge: CONSOLE_LOGIN_TTL / 1000,\n });\n }\n\n protected unsetLoginCookie(event: IAppEvent) : void {\n unsetResponseCookie(event, CONSOLE_LOGIN_COOKIE, { path: this.buildLoginCookiePath() });\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Logger } from '@authup/server-kit';
|
|
2
|
+
import type { IConsoleLoginStore, IOAuth2TokenRevoker, IOAuth2TokenVerifier, ISessionManager, ISessionRepository } from '../../../../../core/index.ts';
|
|
3
|
+
export type ConsoleLoginDefinition = {
|
|
4
|
+
/**
|
|
5
|
+
* The per-realm OAuth2 client the console authenticates against, by
|
|
6
|
+
* NAME (`account-console`, `admin-console`). A name needs a realm hint at
|
|
7
|
+
* `/authorize` and at `/token` alike, which is why the kick requires one.
|
|
8
|
+
*/
|
|
9
|
+
clientName: string;
|
|
10
|
+
/**
|
|
11
|
+
* The path the console is served under, relative to the deployment base
|
|
12
|
+
* path (`console/account`, `console/admin`; it may carry a slash). It
|
|
13
|
+
* scopes the login cookie and builds the callback URL, both of which live
|
|
14
|
+
* on the API's own origin whatever the console url says.
|
|
15
|
+
*/
|
|
16
|
+
segment: string;
|
|
17
|
+
/**
|
|
18
|
+
* Where the console itself is served (`<name>Console.url`). The
|
|
19
|
+
* browser lands there once the credential is issued, so a console under a
|
|
20
|
+
* path of its own is landed on correctly.
|
|
21
|
+
*
|
|
22
|
+
* Only its PATH is read, which is exact rather than a shortcut: a console
|
|
23
|
+
* on a foreign origin could never present the `SameSite=Strict`
|
|
24
|
+
* credential this flow issues, and normalizeConfig refuses that shape at
|
|
25
|
+
* boot for exactly that reason.
|
|
26
|
+
*/
|
|
27
|
+
consoleUrl: string;
|
|
28
|
+
/**
|
|
29
|
+
* Where a refused callback lands, relative to the console root
|
|
30
|
+
* (`login` -> `<base>/<segment>/login?error=...`). Defaults to the root:
|
|
31
|
+
* the page that renders the error marker differs per console.
|
|
32
|
+
*/
|
|
33
|
+
refusalPath?: string;
|
|
34
|
+
};
|
|
35
|
+
export type ConsoleLoginContext = {
|
|
36
|
+
options: {
|
|
37
|
+
baseURL: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Holds the PKCE verifier and `state` while the browser is away at
|
|
41
|
+
* `/authorize` (plan 088).
|
|
42
|
+
*/
|
|
43
|
+
loginStore: IConsoleLoginStore;
|
|
44
|
+
/**
|
|
45
|
+
* Writes and clears the opaque credential on the session row. The session
|
|
46
|
+
* MANAGER cannot: the column is `select: false` and has a dedicated write.
|
|
47
|
+
*/
|
|
48
|
+
sessionRepository: ISessionRepository;
|
|
49
|
+
sessionManager: ISessionManager;
|
|
50
|
+
/**
|
|
51
|
+
* Reads the exchanged access token (session, subject) and the refresh
|
|
52
|
+
* token, so both can be revoked before either leaves the process.
|
|
53
|
+
*/
|
|
54
|
+
tokenVerifier: IOAuth2TokenVerifier;
|
|
55
|
+
tokenRevoker: IOAuth2TokenRevoker;
|
|
56
|
+
logger?: Logger;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/console-login/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EACR,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EACrB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,sBAAsB,GAAG;IACjC;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;;OASG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,OAAO,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;IACF;;;OAGG;IACH,UAAU,EAAE,kBAAkB,CAAC;IAC/B;;;OAGG;IACH,iBAAiB,EAAE,kBAAkB,CAAC;IACtC,cAAc,EAAE,eAAe,CAAC;IAChC;;;OAGG;IACH,aAAa,EAAE,oBAAoB,CAAC;IACpC,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './account/index.ts';
|
|
2
2
|
export * from './activate/index.ts';
|
|
3
|
+
export * from './admin/index.ts';
|
|
3
4
|
export * from './authenticator-challenge/index.ts';
|
|
4
5
|
export * from './authorize/index.ts';
|
|
6
|
+
export * from './console-login/index.ts';
|
|
5
7
|
export * from './jwks/index.ts';
|
|
6
8
|
export * from './logout/index.ts';
|
|
7
9
|
export * from './openid/index.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/http/controllers/workflows/index.ts"],"names":[],"mappings":"AAOA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oCAAoC,CAAC;AACnD,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/http/controllers/workflows/index.ts"],"names":[],"mappings":"AAOA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oCAAoC,CAAC;AACnD,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
+
import { ConsoleLogin } from "./console-login/module.mjs";
|
|
5
|
+
import "./console-login/index.mjs";
|
|
4
6
|
import { AccountController } from "./account/module.mjs";
|
|
5
7
|
import "./account/index.mjs";
|
|
6
8
|
import { ActivateController } from "./activate/module.mjs";
|
|
7
9
|
import "./activate/index.mjs";
|
|
10
|
+
import { AdminController } from "./admin/module.mjs";
|
|
11
|
+
import "./admin/index.mjs";
|
|
8
12
|
import { AuthenticatorChallengeController } from "./authenticator-challenge/module.mjs";
|
|
9
13
|
import "./authenticator-challenge/index.mjs";
|
|
10
14
|
import { AuthorizeController } from "./authorize/module.mjs";
|
|
@@ -28,4 +32,4 @@ import { TokenController } from "./token/module.mjs";
|
|
|
28
32
|
import "./token/index.mjs";
|
|
29
33
|
import { UserInfoController } from "./userinfo/module.mjs";
|
|
30
34
|
import "./userinfo/index.mjs";
|
|
31
|
-
export { AccountController, ActivateController, AuthenticatorChallengeController, AuthorizeController, JwkController, LogoutController, OpenIDController, PasswordForgotController, PasswordResetController, RegisterController, StatusController, TokenController, UserInfoController, getJwkRouteHandler, getJwksRouteHandler };
|
|
35
|
+
export { AccountController, ActivateController, AdminController, AuthenticatorChallengeController, AuthorizeController, ConsoleLogin, JwkController, LogoutController, OpenIDController, PasswordForgotController, PasswordResetController, RegisterController, StatusController, TokenController, UserInfoController, getJwkRouteHandler, getJwksRouteHandler };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EndSessionResponse } from '@authup/core-http-kit';
|
|
1
2
|
import type { IAppEvent } from 'routup';
|
|
2
3
|
import type { IOAuth2EndSessionService } from '../../../../../core/index.ts';
|
|
3
4
|
import { OAuth2EndSessionRequestValidator } from '../../../../../core/index.ts';
|
|
@@ -7,8 +8,36 @@ export declare class LogoutController {
|
|
|
7
8
|
protected endSessionService: IOAuth2EndSessionService;
|
|
8
9
|
protected validator: OAuth2EndSessionRequestValidator;
|
|
9
10
|
constructor(ctx: LogoutControllerContext);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* `end_session_endpoint` keeps both of its OIDC bindings, and both are
|
|
13
|
+
* BROWSER NAVIGATIONS: the RP either redirects the user here (GET) or
|
|
14
|
+
* auto-submits a form at it (form_post). Neither can consume a JSON
|
|
15
|
+
* answer, so both hand over to the console service, carrying the
|
|
16
|
+
* request's own parameters.
|
|
17
|
+
*
|
|
18
|
+
* The revoke moved to the JSON call the rendered page makes (plan 101
|
|
19
|
+
* D2). It could not stay here: the page needs `serverRevoked`,
|
|
20
|
+
* `hintSub` and `hintSubKind` to decide whether to tear its own local
|
|
21
|
+
* session down, and those must reach it as the answer to its OWN
|
|
22
|
+
* request. Putting them in the redirect URL would let anyone craft
|
|
23
|
+
* them, which is exactly the forced-logout CSRF the client-side gate
|
|
24
|
+
* exists to refuse.
|
|
25
|
+
*
|
|
26
|
+
* The consequence to know: a browser with JavaScript disabled no
|
|
27
|
+
* longer revokes. It also never returns to the RP, so both sides stay
|
|
28
|
+
* consistent rather than the RP believing a logout it did not get.
|
|
29
|
+
*/
|
|
30
|
+
serve(event: IAppEvent): Promise<Response>;
|
|
31
|
+
execute(event: IAppEvent): Promise<Response | EndSessionResponse>;
|
|
32
|
+
protected isJSONRequest(event: IAppEvent): boolean;
|
|
33
|
+
protected forward(event: IAppEvent): Promise<Response>;
|
|
34
|
+
/**
|
|
35
|
+
* The end-session work itself, unchanged from when it ran on the page
|
|
36
|
+
* GET: validate, verify the hint, revoke the session it references, and
|
|
37
|
+
* validate the post-logout redirect. Only the reply is different, and
|
|
38
|
+
* only because the caller is now the page rather than the browser's
|
|
39
|
+
* address bar.
|
|
40
|
+
*/
|
|
41
|
+
protected endSession(event: IAppEvent): Promise<EndSessionResponse>;
|
|
13
42
|
}
|
|
14
43
|
//# sourceMappingURL=module.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/logout/module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/logout/module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAQhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EAAE,wBAAwB,EAA2B,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AAGhF,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEnF,qBACa,gBAAgB;IACzB,SAAS,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAE3C,SAAS,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;IAEtD,SAAS,CAAC,SAAS,EAAE,gCAAgC,CAAC;gBAE1C,GAAG,EAAE,uBAAuB;IAMxC;;;;;;;;;;;;;;;;;;OAkBG;IAEG,KAAK,CAAa,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKtD,OAAO,CAAa,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,GAAG,kBAAkB,CAAC;IAWnF,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,GAAI,OAAO;cAWnC,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQ5D;;;;;;OAMG;cACa,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAyE5E"}
|
|
@@ -5,10 +5,9 @@ import { OAuth2EndSessionRequestValidator } from "../../../../../core/oauth2/end
|
|
|
5
5
|
import "../../../../../core/index.mjs";
|
|
6
6
|
import { readFromLocations } from "../../../request/helpers/locations.mjs";
|
|
7
7
|
import "../../../request/index.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import "../../../ui/index.mjs";
|
|
8
|
+
import { redirectToAuthConsole } from "../auth-console.mjs";
|
|
10
9
|
import { URL } from "node:url";
|
|
11
|
-
import {
|
|
10
|
+
import { getRequestHeader } from "routup";
|
|
12
11
|
import { DContext, DController, DGet, DPost } from "@routup/decorators";
|
|
13
12
|
//#region src/adapters/http/controllers/workflows/logout/module.ts
|
|
14
13
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -34,13 +33,46 @@ var LogoutController = class {
|
|
|
34
33
|
this.endSessionService = ctx.endSessionService;
|
|
35
34
|
this.validator = new OAuth2EndSessionRequestValidator();
|
|
36
35
|
}
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
/**
|
|
37
|
+
* `end_session_endpoint` keeps both of its OIDC bindings, and both are
|
|
38
|
+
* BROWSER NAVIGATIONS: the RP either redirects the user here (GET) or
|
|
39
|
+
* auto-submits a form at it (form_post). Neither can consume a JSON
|
|
40
|
+
* answer, so both hand over to the console service, carrying the
|
|
41
|
+
* request's own parameters.
|
|
42
|
+
*
|
|
43
|
+
* The revoke moved to the JSON call the rendered page makes (plan 101
|
|
44
|
+
* D2). It could not stay here: the page needs `serverRevoked`,
|
|
45
|
+
* `hintSub` and `hintSubKind` to decide whether to tear its own local
|
|
46
|
+
* session down, and those must reach it as the answer to its OWN
|
|
47
|
+
* request. Putting them in the redirect URL would let anyone craft
|
|
48
|
+
* them, which is exactly the forced-logout CSRF the client-side gate
|
|
49
|
+
* exists to refuse.
|
|
50
|
+
*
|
|
51
|
+
* The consequence to know: a browser with JavaScript disabled no
|
|
52
|
+
* longer revokes. It also never returns to the RP, so both sides stay
|
|
53
|
+
* consistent rather than the RP believing a logout it did not get.
|
|
54
|
+
*/ async serve(event) {
|
|
55
|
+
return this.forward(event);
|
|
39
56
|
}
|
|
40
57
|
async execute(event) {
|
|
41
|
-
return this.
|
|
58
|
+
if (this.isJSONRequest(event)) return this.endSession(event);
|
|
59
|
+
return this.forward(event);
|
|
42
60
|
}
|
|
43
|
-
|
|
61
|
+
isJSONRequest(event) {
|
|
62
|
+
const contentType = getRequestHeader(event, "content-type");
|
|
63
|
+
return typeof contentType === "string" && contentType.toLowerCase().includes("application/json");
|
|
64
|
+
}
|
|
65
|
+
async forward(event) {
|
|
66
|
+
const merged = await readFromLocations(event, ["body", "query"]);
|
|
67
|
+
return redirectToAuthConsole(event, this.options.authConsoleUrl, "/logout", merged);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The end-session work itself, unchanged from when it ran on the page
|
|
71
|
+
* GET: validate, verify the hint, revoke the session it references, and
|
|
72
|
+
* validate the post-logout redirect. Only the reply is different, and
|
|
73
|
+
* only because the caller is now the page rather than the browser's
|
|
74
|
+
* address bar.
|
|
75
|
+
*/ async endSession(event) {
|
|
44
76
|
const merged = await readFromLocations(event, ["body", "query"]);
|
|
45
77
|
let data;
|
|
46
78
|
try {
|
|
@@ -61,23 +93,15 @@ var LogoutController = class {
|
|
|
61
93
|
if (result.state) url.searchParams.set("state", result.state);
|
|
62
94
|
redirect = url.href;
|
|
63
95
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
hintSub: result.hintVerified ? result.sub : void 0,
|
|
74
|
-
hintSubKind: result.hintVerified ? result.subKind : void 0,
|
|
75
|
-
serverRevoked,
|
|
76
|
-
redirect,
|
|
77
|
-
requestPath: `${requestURL.pathname}${requestURL.search}`
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
96
|
+
event.response.headers.set("cache-control", "no-store");
|
|
97
|
+
return {
|
|
98
|
+
clientName: result.clientName,
|
|
99
|
+
hintVerified: result.hintVerified,
|
|
100
|
+
hintSub: result.hintVerified ? result.sub : void 0,
|
|
101
|
+
hintSubKind: result.hintVerified ? result.subKind : void 0,
|
|
102
|
+
serverRevoked,
|
|
103
|
+
redirect
|
|
104
|
+
};
|
|
81
105
|
}
|
|
82
106
|
};
|
|
83
107
|
_ts_decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["DContext","DController","DGet","DPost","URL","sendRedirect","OAuth2EndSessionRequestValidator","readFromLocations","renderAuthConsolePage","LogoutController","options","endSessionService","validator","ctx","serve","event","handle","execute","merged","data","run","id_token_hint","result","verify","serverRevoked","hintVerified","sessionId","sub","subKind","revoke","redirect","redirectUri","url","state","searchParams","set","href","requestURL","request","payload","config","baseURL","client","clientName","name","undefined","hintSub","hintSubKind","requestPath","pathname","search"],"sources":["../../../../../../src/adapters/http/controllers/workflows/logout/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 {\n DContext,\n DController,\n DGet,\n DPost,\n} from '@routup/decorators';\nimport { URL } from 'node:url';\nimport type { IAppEvent } from 'routup';\nimport { sendRedirect } from 'routup';\nimport type { IOAuth2EndSessionService, OAuth2EndSessionRequest } from '../../../../../core/index.ts';\nimport { OAuth2EndSessionRequestValidator } from '../../../../../core/index.ts';\nimport { readFromLocations } from '../../../request/index.ts';\nimport { renderAuthConsolePage } from '../../../ui/index.ts';\nimport type { LogoutControllerContext, LogoutControllerOptions } from './types.ts';\n\n@DController('/logout')\nexport class LogoutController {\n protected options: LogoutControllerOptions;\n\n protected endSessionService: IOAuth2EndSessionService;\n\n protected validator: OAuth2EndSessionRequestValidator;\n\n constructor(ctx: LogoutControllerContext) {\n this.options = ctx.options;\n this.endSessionService = ctx.endSessionService;\n this.validator = new OAuth2EndSessionRequestValidator();\n }\n\n @DGet('', [])\n async serve(@DContext() event: IAppEvent): Promise<string | Response> {\n return this.handle(event);\n }\n\n // OIDC RP-Initiated Logout allows form_post on the same endpoint.\n @DPost('', [])\n async execute(@DContext() event: IAppEvent): Promise<string | Response> {\n return this.handle(event);\n }\n\n protected async handle(event: IAppEvent): Promise<string | Response> {\n const merged = await readFromLocations(event, ['body', 'query']);\n\n // Malformed input (oversized / duplicated params) must never dead-end\n // the human behind the browser on a JSON error, nor discard a valid\n // id_token_hint: a bad *cosmetic* param (post_logout_redirect_uri /\n // state / client_id / realm hint) must NOT cancel the\n // security-critical revoke the hint authorizes. So on a full-request\n // validation failure, retry with the hint ALONE — the revoke needs\n // nothing else: its subject/session come from the verified hint's\n // claims, and client resolution degrades gracefully (the service\n // falls back to the hint's sole `aud`, scoped by the hint's own realm\n // claim — the dropped request params only affected the confirm page's\n // client name and the redirect, which is dropped anyway). Only a\n // malformed hint itself falls through to the parameter-less confirm\n // page.\n let data: OAuth2EndSessionRequest;\n try {\n data = await this.validator.run(merged);\n } catch {\n try {\n data = await this.validator.run({ id_token_hint: merged.id_token_hint });\n } catch {\n data = {};\n }\n }\n\n const result = await this.endSessionService.verify(data);\n\n // A signature-verified id_token_hint proves possession — revoke the\n // referenced session server-side immediately (only if it belongs to the\n // hint's subject). Without a hint we mutate nothing; the SSR page's\n // sign-out is a click-gated, bearer-authenticated action.\n let serverRevoked = false;\n if (result.hintVerified && result.sessionId && result.sub && result.subKind) {\n serverRevoked = await this.endSessionService.revoke(\n result.sessionId,\n result.sub,\n result.subKind,\n );\n }\n\n // Build the validated post-logout redirect (the open-redirect guard\n // lives in the service; `state` rides only alongside a validated uri).\n let redirect: string | undefined;\n if (result.redirectUri) {\n const url = new URL(result.redirectUri);\n if (result.state) {\n url.searchParams.set('state', result.state);\n }\n\n redirect = url.href;\n }\n\n // Bounce straight back to the RP ONLY when the logout was actually\n // performed server-side (a verified hint revoked the session). A\n // hint-less or forged request MUST NOT silently redirect without ending\n // the session — otherwise the RP treats a no-op round-trip as a\n // successful logout while the authup session survives. Instead render\n // the click-gated confirm page, which performs the bearer-authenticated\n // sign-out and then redirects.\n if (serverRevoked && redirect) {\n return sendRedirect(event, redirect);\n }\n\n const requestURL = new URL(event.request.url);\n\n return renderAuthConsolePage(event, {\n url: '/logout',\n payload: {\n config: { baseURL: this.options.baseURL },\n data: {\n client: result.clientName ? { name: result.clientName } : undefined,\n hintVerified: result.hintVerified,\n // never reflect an unverified hint's claims\n hintSub: result.hintVerified ? result.sub : undefined,\n hintSubKind: result.hintVerified ? result.subKind : undefined,\n serverRevoked,\n // the (already validated) uri to return to after a click-gated\n // sign-out; carries `state` when present\n redirect,\n requestPath: `${requestURL.pathname}${requestURL.search}`,\n },\n },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,IAAaS,mBAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEV,YAAYC,KAA8B;EACtC,KAAKH,UAAUG,IAAIH;EACnB,KAAKC,oBAAoBE,IAAIF;EAC7B,KAAKC,YAAY,IAAIN,iCAAAA;CACzB;CAEA,MACMQ,MAAM,OAA0D;EAClE,OAAO,KAAKE,OAAOD,KAAAA;CACvB;CAGA,MACME,QAAQ,OAA0D;EACpE,OAAO,KAAKD,OAAOD,KAAAA;CACvB;CAEA,MAAgBC,OAAOD,OAA8C;EACjE,MAAMG,SAAS,MAAMX,kBAAkBQ,OAAO,CAAC,QAAQ,OAAQ,CAAA;EAe/D,IAAII;EACJ,IAAI;GACAA,OAAO,MAAM,KAAKP,UAAUQ,IAAIF,MAAAA;EACpC,QAAQ;GACJ,IAAI;IACAC,OAAO,MAAM,KAAKP,UAAUQ,IAAI,EAAEC,eAAeH,OAAOG,cAAc,CAAA;GAC1E,QAAQ;IACJF,OAAO,CAAC;GACZ;EACJ;EAEA,MAAMG,SAAS,MAAM,KAAKX,kBAAkBY,OAAOJ,IAAAA;EAMnD,IAAIK,gBAAgB;EACpB,IAAIF,OAAOG,gBAAgBH,OAAOI,aAAaJ,OAAOK,OAAOL,OAAOM,SAChEJ,gBAAgB,MAAM,KAAKb,kBAAkBkB,OACzCP,OAAOI,WACPJ,OAAOK,KACPL,OAAOM,OAAO;EAMtB,IAAIE;EACJ,IAAIR,OAAOS,aAAa;GACpB,MAAMC,MAAM,IAAI5B,IAAIkB,OAAOS,WAAW;GACtC,IAAIT,OAAOW,OACPD,IAAIE,aAAaC,IAAI,SAASb,OAAOW,KAAK;GAG9CH,WAAWE,IAAII;EACnB;EASA,IAAIZ,iBAAiBM,UACjB,OAAOzB,aAAaU,OAAOe,QAAAA;EAG/B,MAAMO,aAAa,IAAIjC,IAAIW,MAAMuB,QAAQN,GAAG;EAE5C,OAAOxB,sBAAsBO,OAAO;GAChCiB,KAAK;GACLO,SAAS;IACLC,QAAQ,EAAEC,SAAS,KAAK/B,QAAQ+B,QAAQ;IACxCtB,MAAM;KACFuB,QAAQpB,OAAOqB,aAAa,EAAEC,MAAMtB,OAAOqB,WAAW,IAAIE,KAAAA;KAC1DpB,cAAcH,OAAOG;KAErBqB,SAASxB,OAAOG,eAAeH,OAAOK,MAAMkB,KAAAA;KAC5CE,aAAazB,OAAOG,eAAeH,OAAOM,UAAUiB,KAAAA;KACpDrB;KAGAM;KACAkB,aAAa,GAAGX,WAAWY,WAAWZ,WAAWa;IACrD;GACJ;EACJ,CAAA;CACJ;AACJ"}
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["DContext","DController","DGet","DPost","URL","getRequestHeader","OAuth2EndSessionRequestValidator","readFromLocations","redirectToAuthConsole","LogoutController","options","endSessionService","validator","ctx","serve","event","forward","execute","isJSONRequest","endSession","contentType","toLowerCase","includes","merged","authConsoleUrl","data","run","id_token_hint","result","verify","serverRevoked","hintVerified","sessionId","sub","subKind","revoke","redirect","redirectUri","url","state","searchParams","set","href","response","headers","clientName","hintSub","undefined","hintSubKind"],"sources":["../../../../../../src/adapters/http/controllers/workflows/logout/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 type { EndSessionResponse } from '@authup/core-http-kit';\nimport {\n DContext,\n DController,\n DGet,\n DPost,\n} from '@routup/decorators';\nimport { URL } from 'node:url';\nimport type { IAppEvent } from 'routup';\nimport { getRequestHeader } from 'routup';\nimport type { IOAuth2EndSessionService, OAuth2EndSessionRequest } from '../../../../../core/index.ts';\nimport { OAuth2EndSessionRequestValidator } from '../../../../../core/index.ts';\nimport { readFromLocations } from '../../../request/index.ts';\nimport { redirectToAuthConsole } from '../auth-console.ts';\nimport type { LogoutControllerContext, LogoutControllerOptions } from './types.ts';\n\n@DController('/logout')\nexport class LogoutController {\n protected options: LogoutControllerOptions;\n\n protected endSessionService: IOAuth2EndSessionService;\n\n protected validator: OAuth2EndSessionRequestValidator;\n\n constructor(ctx: LogoutControllerContext) {\n this.options = ctx.options;\n this.endSessionService = ctx.endSessionService;\n this.validator = new OAuth2EndSessionRequestValidator();\n }\n\n /**\n * `end_session_endpoint` keeps both of its OIDC bindings, and both are\n * BROWSER NAVIGATIONS: the RP either redirects the user here (GET) or\n * auto-submits a form at it (form_post). Neither can consume a JSON\n * answer, so both hand over to the console service, carrying the\n * request's own parameters.\n *\n * The revoke moved to the JSON call the rendered page makes (plan 101\n * D2). It could not stay here: the page needs `serverRevoked`,\n * `hintSub` and `hintSubKind` to decide whether to tear its own local\n * session down, and those must reach it as the answer to its OWN\n * request. Putting them in the redirect URL would let anyone craft\n * them, which is exactly the forced-logout CSRF the client-side gate\n * exists to refuse.\n *\n * The consequence to know: a browser with JavaScript disabled no\n * longer revokes. It also never returns to the RP, so both sides stay\n * consistent rather than the RP believing a logout it did not get.\n */\n @DGet('', [])\n async serve(@DContext() event: IAppEvent): Promise<Response> {\n return this.forward(event);\n }\n\n @DPost('', [])\n async execute(@DContext() event: IAppEvent): Promise<Response | EndSessionResponse> {\n // A JSON body is the console page asking us to end the session; a\n // form body is the OIDC form_post binding, i.e. a navigation. A\n // browser cannot navigate with a JSON body, so the two never blur.\n if (this.isJSONRequest(event)) {\n return this.endSession(event);\n }\n\n return this.forward(event);\n }\n\n protected isJSONRequest(event: IAppEvent) : boolean {\n const contentType = getRequestHeader(event, 'content-type');\n\n // Media types are case-insensitive (RFC 9110), and the header\n // routinely carries parameters (`; charset=UTF-8`). Reading it\n // literally would send an `Application/JSON` caller down the\n // navigation path and answer its XHR with a redirect.\n return typeof contentType === 'string' &&\n contentType.toLowerCase().includes('application/json');\n }\n\n protected async forward(event: IAppEvent): Promise<Response> {\n // Both bindings merge body and query, so the form_post parameters\n // survive the hop (a 302 turns the POST into a GET).\n const merged = await readFromLocations(event, ['body', 'query']);\n\n return redirectToAuthConsole(event, this.options.authConsoleUrl, '/logout', merged);\n }\n\n /**\n * The end-session work itself, unchanged from when it ran on the page\n * GET: validate, verify the hint, revoke the session it references, and\n * validate the post-logout redirect. Only the reply is different, and\n * only because the caller is now the page rather than the browser's\n * address bar.\n */\n protected async endSession(event: IAppEvent): Promise<EndSessionResponse> {\n const merged = await readFromLocations(event, ['body', 'query']);\n\n // Malformed input (oversized / duplicated params) must never dead-end\n // the human behind the browser on a JSON error, nor discard a valid\n // id_token_hint: a bad *cosmetic* param (post_logout_redirect_uri /\n // state / client_id / realm hint) must NOT cancel the\n // security-critical revoke the hint authorizes. So on a full-request\n // validation failure, retry with the hint ALONE — the revoke needs\n // nothing else: its subject/session come from the verified hint's\n // claims, and client resolution degrades gracefully (the service\n // falls back to the hint's sole `aud`, scoped by the hint's own realm\n // claim — the dropped request params only affected the confirm page's\n // client name and the redirect, which is dropped anyway). Only a\n // malformed hint itself falls through to the parameter-less answer.\n let data: OAuth2EndSessionRequest;\n try {\n data = await this.validator.run(merged);\n } catch {\n try {\n data = await this.validator.run({ id_token_hint: merged.id_token_hint });\n } catch {\n data = {};\n }\n }\n\n const result = await this.endSessionService.verify(data);\n\n // A signature-verified id_token_hint proves possession — revoke the\n // referenced session server-side immediately (only if it belongs to the\n // hint's subject). Without a hint we mutate nothing; the page's\n // sign-out is a click-gated, bearer-authenticated action.\n let serverRevoked = false;\n if (result.hintVerified && result.sessionId && result.sub && result.subKind) {\n serverRevoked = await this.endSessionService.revoke(\n result.sessionId,\n result.sub,\n result.subKind,\n );\n }\n\n // Build the validated post-logout redirect (the open-redirect guard\n // lives in the service; `state` rides only alongside a validated uri).\n let redirect: string | undefined;\n if (result.redirectUri) {\n const url = new URL(result.redirectUri);\n if (result.state) {\n url.searchParams.set('state', result.state);\n }\n\n redirect = url.href;\n }\n\n // `redirect` rides along whether or not the session was revoked\n // here, because the page navigates it only AFTER its own sign-out\n // has run. That is the same rule as before: what was gated on\n // `serverRevoked` was the server's automatic 302, so that a\n // hint-less round-trip could not make an RP believe a logout it\n // never got. A hint-less request still reaches the RP, but only\n // once a human has clicked and the local session is actually gone.\n event.response.headers.set('cache-control', 'no-store');\n\n return {\n clientName: result.clientName,\n hintVerified: result.hintVerified,\n // never reflect an unverified hint's claims: they are the\n // operands of the page's own auto-clear gate\n hintSub: result.hintVerified ? result.sub : undefined,\n hintSubKind: result.hintVerified ? result.subKind : undefined,\n serverRevoked,\n redirect,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;AAKC,SAAA,aAAA,YAAA,QAAA,KAAA,MAAA;;;;;;;;;;;;;;AAmBD,IAAaS,mBAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEV,YAAYC,KAA8B;EACtC,KAAKH,UAAUG,IAAIH;EACnB,KAAKC,oBAAoBE,IAAIF;EAC7B,KAAKC,YAAY,IAAIN,iCAAAA;CACzB;;;;;;;;;;;;;;;;;;;IAqBA,MACMQ,MAAM,OAAiD;EACzD,OAAO,KAAKE,QAAQD,KAAAA;CACxB;CAEA,MACME,QAAQ,OAAsE;EAIhF,IAAI,KAAKC,cAAcH,KAAAA,GACnB,OAAO,KAAKI,WAAWJ,KAAAA;EAG3B,OAAO,KAAKC,QAAQD,KAAAA;CACxB;CAEUG,cAAcH,OAA4B;EAChD,MAAMK,cAAcf,iBAAiBU,OAAO,cAAA;EAM5C,OAAO,OAAOK,gBAAgB,YAC1BA,YAAYC,YAAW,CAAA,CAAGC,SAAS,kBAAA;CAC3C;CAEA,MAAgBN,QAAQD,OAAqC;EAGzD,MAAMQ,SAAS,MAAMhB,kBAAkBQ,OAAO,CAAC,QAAQ,OAAQ,CAAA;EAE/D,OAAOP,sBAAsBO,OAAO,KAAKL,QAAQc,gBAAgB,WAAWD,MAAAA;CAChF;;;;;;;IASA,MAAgBJ,WAAWJ,OAA+C;EACtE,MAAMQ,SAAS,MAAMhB,kBAAkBQ,OAAO,CAAC,QAAQ,OAAQ,CAAA;EAc/D,IAAIU;EACJ,IAAI;GACAA,OAAO,MAAM,KAAKb,UAAUc,IAAIH,MAAAA;EACpC,QAAQ;GACJ,IAAI;IACAE,OAAO,MAAM,KAAKb,UAAUc,IAAI,EAAEC,eAAeJ,OAAOI,cAAc,CAAA;GAC1E,QAAQ;IACJF,OAAO,CAAC;GACZ;EACJ;EAEA,MAAMG,SAAS,MAAM,KAAKjB,kBAAkBkB,OAAOJ,IAAAA;EAMnD,IAAIK,gBAAgB;EACpB,IAAIF,OAAOG,gBAAgBH,OAAOI,aAAaJ,OAAOK,OAAOL,OAAOM,SAChEJ,gBAAgB,MAAM,KAAKnB,kBAAkBwB,OACzCP,OAAOI,WACPJ,OAAOK,KACPL,OAAOM,OAAO;EAMtB,IAAIE;EACJ,IAAIR,OAAOS,aAAa;GACpB,MAAMC,MAAM,IAAIlC,IAAIwB,OAAOS,WAAW;GACtC,IAAIT,OAAOW,OACPD,IAAIE,aAAaC,IAAI,SAASb,OAAOW,KAAK;GAG9CH,WAAWE,IAAII;EACnB;EASA3B,MAAM4B,SAASC,QAAQH,IAAI,iBAAiB,UAAA;EAE5C,OAAO;GACHI,YAAYjB,OAAOiB;GACnBd,cAAcH,OAAOG;GAGrBe,SAASlB,OAAOG,eAAeH,OAAOK,MAAMc,KAAAA;GAC5CC,aAAapB,OAAOG,eAAeH,OAAOM,UAAUa,KAAAA;GACpDjB;GACAM;EACJ;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/logout/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE7E,MAAM,MAAM,uBAAuB,GAAG;IAClC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/logout/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE7E,MAAM,MAAM,uBAAuB,GAAG;IAClC,cAAc,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IAClC,OAAO,EAAE,uBAAuB,CAAC;IACjC,iBAAiB,EAAE,wBAAwB,CAAC;CAC/C,CAAC"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { PasswordForgotPayload, PasswordForgotResponse
|
|
1
|
+
import type { PasswordForgotPayload, PasswordForgotResponse } from '@authup/core-http-kit';
|
|
2
2
|
import type { IAppEvent } from 'routup';
|
|
3
3
|
import type { IPasswordRecoveryService } from '../../../../../core/index.ts';
|
|
4
4
|
export type PasswordForgotControllerOptions = {
|
|
5
|
-
|
|
6
|
-
features: StatusResponseFeatures;
|
|
5
|
+
authConsoleUrl: string;
|
|
7
6
|
};
|
|
8
7
|
export type PasswordForgotControllerContext = {
|
|
9
8
|
options: PasswordForgotControllerOptions;
|
|
@@ -13,7 +12,12 @@ export declare class PasswordForgotController {
|
|
|
13
12
|
protected options: PasswordForgotControllerOptions;
|
|
14
13
|
protected service: IPasswordRecoveryService;
|
|
15
14
|
constructor(ctx: PasswordForgotControllerContext);
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The page renders in the auth console service; this hop carries the
|
|
17
|
+
* request's own parameters over to it. The POST below stays here:
|
|
18
|
+
* server-core keeps the protocol, the service keeps the render.
|
|
19
|
+
*/
|
|
20
|
+
serve(event: IAppEvent): Promise<Response>;
|
|
17
21
|
execute(data: PasswordForgotPayload, event: IAppEvent): Promise<PasswordForgotResponse>;
|
|
18
22
|
}
|
|
19
23
|
//# sourceMappingURL=module.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/password-forgot/module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/controllers/workflows/password-forgot/module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAQ3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAI7E,MAAM,MAAM,+BAA+B,GAAG;IAC1C,cAAc,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC1C,OAAO,EAAE,+BAA+B,CAAC;IACzC,OAAO,EAAE,wBAAwB,CAAC;CACrC,CAAC;AAEF,qBACa,wBAAwB;IACjC,SAAS,CAAC,OAAO,EAAE,+BAA+B,CAAC;IAEnD,SAAS,CAAC,OAAO,EAAE,wBAAwB,CAAC;gBAEhC,GAAG,EAAE,+BAA+B;IAKhD;;;;OAIG;IAEG,KAAK,CAAa,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKtD,OAAO,CACA,IAAI,EAAE,qBAAqB,EACxB,KAAK,EAAE,SAAS,GAC7B,OAAO,CAAC,sBAAsB,CAAC;CAOrC"}
|