@authup/server-core 1.0.0-beta.54 → 1.0.0-beta.55
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.mjs.map +1 -1
- package/dist/adapters/database/domains/client/entity.mjs +2 -2
- package/dist/adapters/database/domains/client/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/client/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/client/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/client-permission/entity.mjs +2 -2
- package/dist/adapters/database/domains/client-permission/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/client-permission/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/client-permission/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/client-role/entity.mjs +2 -2
- package/dist/adapters/database/domains/client-role/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/client-role/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/client-role/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/client-scope/entity.mjs +2 -2
- package/dist/adapters/database/domains/client-scope/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/client-scope/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/client-scope/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/consent/entity.mjs +2 -2
- package/dist/adapters/database/domains/consent/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/consent/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/consent/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/constants.mjs.map +1 -1
- package/dist/adapters/database/domains/event/entity.mjs +2 -2
- package/dist/adapters/database/domains/event/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider/entity.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-account/entity.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-account/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-account/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-account/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-attribute/entity.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-attribute/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-attribute-mapping/entity.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-attribute-mapping/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-permission-mapping/entity.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-permission-mapping/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-role-mapping/entity.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-role-mapping/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/identity-provider-role-mapping/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/identity-provider-role-mapping/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/key/entity.mjs +2 -2
- package/dist/adapters/database/domains/key/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/permission/entity.mjs +2 -2
- package/dist/adapters/database/domains/permission/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/permission/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/permission/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/permission-policy/entity.mjs +2 -2
- package/dist/adapters/database/domains/permission-policy/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/policy/entity.mjs +2 -2
- package/dist/adapters/database/domains/policy/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/policy/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/policy/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/policy-attribute/entity.mjs +2 -2
- package/dist/adapters/database/domains/policy-attribute/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/policy-attribute/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/policy-attribute/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/realm/entity.mjs +2 -2
- package/dist/adapters/database/domains/realm/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/realm/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/realm/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/role/entity.mjs +2 -2
- package/dist/adapters/database/domains/role/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/role/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/role/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/role-attribute/entity.mjs +2 -2
- package/dist/adapters/database/domains/role-attribute/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/role-attribute/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/role-attribute/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/role-permission/entity.mjs +2 -2
- package/dist/adapters/database/domains/role-permission/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/role-permission/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/role-permission/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/scope/entity.mjs +2 -2
- package/dist/adapters/database/domains/scope/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/scope/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/scope/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/session/entity.mjs +2 -2
- package/dist/adapters/database/domains/session/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/session-token/entity.mjs +2 -2
- package/dist/adapters/database/domains/session-token/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/trust-anchor/entity.mjs +2 -2
- package/dist/adapters/database/domains/trust-anchor/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user/entity.mjs +2 -2
- package/dist/adapters/database/domains/user/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/user/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/user-attribute/entity.mjs +2 -2
- package/dist/adapters/database/domains/user-attribute/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user-attribute/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/user-attribute/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/user-authenticator/entity.mjs +2 -2
- package/dist/adapters/database/domains/user-authenticator/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user-permission/entity.mjs +2 -2
- package/dist/adapters/database/domains/user-permission/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user-permission/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/user-permission/subscriber.mjs.map +1 -1
- package/dist/adapters/database/domains/user-role/entity.mjs +2 -2
- package/dist/adapters/database/domains/user-role/entity.mjs.map +1 -1
- package/dist/adapters/database/domains/user-role/subscriber.mjs +2 -2
- package/dist/adapters/database/domains/user-role/subscriber.mjs.map +1 -1
- package/dist/adapters/database/errors/driver.mjs.map +1 -1
- package/dist/adapters/database/extra-attribute-repository/adapter.mjs.map +1 -1
- package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs.map +1 -1
- package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs.map +1 -1
- package/dist/adapters/database/migrations/mysql/1779267068441-Default.mjs.map +1 -1
- package/dist/adapters/database/migrations/mysql/1779300000000-Default.mjs.map +1 -1
- package/dist/adapters/database/migrations/mysql/1784289540000-CamelCaseAttributes.mjs.map +1 -1
- package/dist/adapters/database/migrations/postgres/1779267068441-Default.mjs.map +1 -1
- package/dist/adapters/database/migrations/postgres/1779300000000-Default.mjs.map +1 -1
- package/dist/adapters/database/migrations/postgres/1784289540000-CamelCaseAttributes.mjs.map +1 -1
- package/dist/adapters/database/subscriber/module.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/authorization/module.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/realm.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/client/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client-permission/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/client-permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client-role/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/client-role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client-scope/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/client-scope/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/consent/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/consent/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/event/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/event/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/key/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/key/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/permission/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/permission-policy/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/permission-policy/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/policy/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/policy/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/role/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/role-attribute/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/role-attribute/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/role-permission/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/role-permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/scope/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/scope/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/session/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/user/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-attribute/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/user-attribute/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-permission/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/user-permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-role/module.mjs +2 -2
- package/dist/adapters/http/controllers/entities/user-role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/activate/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/authorize/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/jwks/handlers/read.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/jwks/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/jwks/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/logout/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/openid/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/password-reset/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/register/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/status/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/token/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/token/utils/extract.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/cors.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/logger.mjs.map +1 -1
- package/dist/adapters/http/request/constants.mjs.map +1 -1
- package/dist/adapters/http/request/helpers/param-id.mjs.map +1 -1
- package/dist/adapters/http/request/helpers/redirect.mjs.map +1 -1
- package/dist/app/factory.mjs.map +1 -1
- package/dist/app/modules/authentication/module.mjs.map +1 -1
- package/dist/app/modules/authentication/repositories/constants.mjs.map +1 -1
- package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
- package/dist/app/modules/cache/module.mjs.map +1 -1
- package/dist/app/modules/components/module.mjs.map +1 -1
- package/dist/app/modules/config/constants.mjs.map +1 -1
- package/dist/app/modules/config/origins.mjs.map +1 -1
- package/dist/app/modules/config/read/env.mjs.map +1 -1
- package/dist/app/modules/config/read/fs.mjs.map +1 -1
- package/dist/app/modules/config/validator.mjs.map +1 -1
- package/dist/app/modules/database/module.mjs.map +1 -1
- package/dist/app/modules/database/repositories/bindings.mjs.map +1 -1
- package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/helpers.mjs.map +1 -1
- package/dist/app/modules/database/repositories/permission-provider/module.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user-attribute/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user-authenticator/repository.mjs.map +1 -1
- package/dist/app/modules/http/module.mjs.map +1 -1
- package/dist/app/modules/http/modules/controller.mjs.map +1 -1
- package/dist/app/modules/identity/module.mjs.map +1 -1
- package/dist/app/modules/logger/module.mjs.map +1 -1
- package/dist/app/modules/mail/module.mjs.map +1 -1
- package/dist/app/modules/metrics/prom.mjs.map +1 -1
- package/dist/app/modules/oauth2/module.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
- package/dist/app/modules/provisioning/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/composite/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/file/module.mjs.map +1 -1
- package/dist/app/modules/runtime/module.mjs.map +1 -1
- package/dist/cli/commands/migration.mjs.map +1 -1
- package/dist/components/database/unique-entries/module.mjs.map +1 -1
- package/dist/core/authentication/entities/client/module.mjs.map +1 -1
- package/dist/core/authentication/session/module.mjs.map +1 -1
- package/dist/core/authentication/session/types.mjs.map +1 -1
- package/dist/core/client-certificate/module.mjs.map +1 -1
- package/dist/core/entities/client/schema.mjs.map +1 -1
- package/dist/core/entities/client/service.mjs.map +1 -1
- package/dist/core/entities/client-permission/schema.mjs.map +1 -1
- package/dist/core/entities/client-permission/service.mjs.map +1 -1
- package/dist/core/entities/client-role/schema.mjs.map +1 -1
- package/dist/core/entities/client-role/service.mjs.map +1 -1
- package/dist/core/entities/client-scope/schema.mjs.map +1 -1
- package/dist/core/entities/client-scope/service.mjs.map +1 -1
- package/dist/core/entities/consent/schema.mjs.map +1 -1
- package/dist/core/entities/consent/types.mjs.map +1 -1
- package/dist/core/entities/event/diff.mjs.map +1 -1
- package/dist/core/entities/event/sanitize.mjs.map +1 -1
- package/dist/core/entities/event/schema.mjs.map +1 -1
- package/dist/core/entities/event/service.mjs.map +1 -1
- package/dist/core/entities/identity-provider/schema.mjs.map +1 -1
- package/dist/core/entities/identity-provider-role-mapping/schema.mjs.map +1 -1
- package/dist/core/entities/identity-provider-role-mapping/service.mjs.map +1 -1
- package/dist/core/entities/key/schema.mjs.map +1 -1
- package/dist/core/entities/key/service.mjs.map +1 -1
- package/dist/core/entities/permission/schema.d.ts.map +1 -1
- package/dist/core/entities/permission/schema.mjs +12 -0
- package/dist/core/entities/permission/schema.mjs.map +1 -1
- package/dist/core/entities/permission/service.mjs.map +1 -1
- package/dist/core/entities/permission-policy/schema.mjs.map +1 -1
- package/dist/core/entities/permission-policy/service.mjs.map +1 -1
- package/dist/core/entities/policy/schema.mjs.map +1 -1
- package/dist/core/entities/policy/service.mjs.map +1 -1
- package/dist/core/entities/realm/schema.mjs.map +1 -1
- package/dist/core/entities/role/schema.mjs.map +1 -1
- package/dist/core/entities/role/service.mjs.map +1 -1
- package/dist/core/entities/role-attribute/schema.mjs.map +1 -1
- package/dist/core/entities/role-attribute/service.mjs.map +1 -1
- package/dist/core/entities/role-permission/schema.mjs.map +1 -1
- package/dist/core/entities/role-permission/service.mjs.map +1 -1
- package/dist/core/entities/scope/schema.mjs.map +1 -1
- package/dist/core/entities/scope/service.mjs.map +1 -1
- package/dist/core/entities/session/schema.mjs.map +1 -1
- package/dist/core/entities/session/service.mjs.map +1 -1
- package/dist/core/entities/trust-anchor/schema.mjs.map +1 -1
- package/dist/core/entities/trust-anchor/service.mjs.map +1 -1
- package/dist/core/entities/user/schema.mjs.map +1 -1
- package/dist/core/entities/user/service.mjs.map +1 -1
- package/dist/core/entities/user-attribute/schema.mjs.map +1 -1
- package/dist/core/entities/user-attribute/service.mjs.map +1 -1
- package/dist/core/entities/user-authenticator/schema.mjs.map +1 -1
- package/dist/core/entities/user-authenticator/service.mjs.map +1 -1
- package/dist/core/entities/user-authenticator/types.mjs.map +1 -1
- package/dist/core/entities/user-permission/schema.mjs.map +1 -1
- package/dist/core/entities/user-permission/service.mjs.map +1 -1
- package/dist/core/entities/user-role/schema.mjs.map +1 -1
- package/dist/core/entities/user-role/service.mjs.map +1 -1
- package/dist/core/identity/permission/junction-grant.mjs.map +1 -1
- package/dist/core/identity/permission/module.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/presets/facebook.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/presets/github.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/presets/google.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/presets/instagram.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/presets/paypal.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/protocols/ldap/module.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
- package/dist/core/identity/provider/authentication/protocols/open-id/module.mjs.map +1 -1
- package/dist/core/identity/provider/constants.mjs.map +1 -1
- package/dist/core/identity/provider/mapper/base.mjs.map +1 -1
- package/dist/core/identity/provider/mapper/constants.mjs.map +1 -1
- package/dist/core/identity/registration/service.mjs.map +1 -1
- package/dist/core/key/provisioner.mjs.map +1 -1
- package/dist/core/key/realm-cipher.mjs.map +1 -1
- package/dist/core/mail/template/templates/mfa-email-otp.mjs.map +1 -1
- package/dist/core/mail/template/templates/password-reset.mjs.map +1 -1
- package/dist/core/mail/template/templates/registration-activation.mjs.map +1 -1
- package/dist/core/mail/template/types.mjs.map +1 -1
- package/dist/core/oauth2/authorization/code/verifier/module.mjs.map +1 -1
- package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
- package/dist/core/oauth2/authorization/module.mjs.map +1 -1
- package/dist/core/oauth2/end-session/service.mjs.map +1 -1
- package/dist/core/oauth2/grant-types/refresh-token.mjs.map +1 -1
- package/dist/core/oauth2/mfa-login/module.mjs.map +1 -1
- package/dist/core/oauth2/openid/claims.mjs.map +1 -1
- package/dist/core/oauth2/scope/resolver.mjs.map +1 -1
- package/dist/core/oauth2/token/issuer/access/module.mjs.map +1 -1
- package/dist/core/oauth2/token/issuer/mfa/module.mjs.map +1 -1
- package/dist/core/oauth2/token/issuer/open-id/module.mjs.map +1 -1
- package/dist/core/oauth2/token/issuer/refresh/module.mjs.map +1 -1
- package/dist/core/oauth2/token/verifier/module.mjs.map +1 -1
- package/dist/core/provisioning/entities/policy/validator.mjs.map +1 -1
- package/dist/core/provisioning/entities/utils.mjs.map +1 -1
- package/dist/core/provisioning/strategy/constants.mjs.map +1 -1
- package/dist/core/provisioning/strategy/validator.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/client/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/role/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/user/module.mjs.map +1 -1
- package/dist/core/query/module.mjs.map +1 -1
- package/dist/core/query/relations.mjs.map +1 -1
- package/dist/core/security/policy/evaluator.mjs.map +1 -1
- package/dist/ui/client/.vite/ssr-manifest.json +218 -218
- package/dist/ui/client/assets/index-CiHrf73J.css +2 -0
- package/dist/ui/client/assets/{index-BmJ2X468.js → index-mtJngmng.js} +1 -1
- package/dist/ui/client/index.html +2 -2
- package/dist/ui/server/server.js +534 -79
- package/package.json +26 -26
- package/dist/ui/client/assets/index-DiOvW76Q.css +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"junction-grant.mjs","names":["RealmScope","minRealmScope","hasOwnProperty","applyJunctionCreateGrant","validated","grant","realmScope","OWN","ANY","policy","policyId","id","buildJunctionUpdateData","input","data","existingScope","actorScope","actorPolicyFree","actorPolicyId","updateData","touchesScope","touchesPolicy"],"sources":["../../../../src/core/identity/permission/junction-grant.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 { RealmScope, minRealmScope } from '@authup/access';\nimport { hasOwnProperty } from '@authup/kit';\nimport type { ResolveJunctionGrantResult } from './types.ts';\n\n/**\n * The privilege-escalation boundary for permission-binding junctions, shared verbatim by\n * role/user/client-permission. Kept in ONE place (rather than copied into each service)\n * so the fail-closed cap/inherit rule is audited and changed once — see #3160 / #3158 / #3159,\n * which each had to patch this rule across all four services.\n *\n * It depends on a server-core type (`ResolveJunctionGrantResult`) and so cannot live on the\n * generic `JunctionEntityService` in `@authup/server-kit` (that would invert the layering).\n */\n\n/**\n * Cap a junction CREATE to the actor's request-relative selected grant and inherit its policy.\n *\n * - `realmScope` is capped to the actor's selected reach (`min(requested, grant.realmScope)`).\n * - The policy follows the grant: only a genuinely unrestricted actor (an UNCAPPED `any` reach\n * AND no policy) may keep an explicitly-requested `policyId`; any restricted/policy-bound\n * actor inherits its own grant's policy (it can neither attach an unowned policy nor detach to\n * widen). The check reads `grant.realmScope` UNCAPPED precisely to distinguish that case — the\n * grant is returned uncapped by `resolveJunctionGrant` for exactly this reason.\n *\n * Mutates `validated` in place (mirrors the surrounding service style).\n */\nexport function applyJunctionCreateGrant(\n validated: Record<string, any>,\n grant: ResolveJunctionGrantResult,\n): void {\n validated.realmScope = minRealmScope([validated.realmScope ?? RealmScope.OWN, grant.realmScope]);\n\n if (grant.realmScope !== RealmScope.ANY || grant.policy) {\n validated.policyId = grant.policy ? grant.policy.id : null;\n }\n}\n\nexport type BuildJunctionUpdateDataInput = {\n /** The validated update payload (UPDATE group) — presence of a key signals caller intent. */\n data: Record<string, any>,\n /** The persisted junction's current reach (used to re-cap a policy-only edit). */\n existingScope: `${RealmScope}`,\n /** The actor's UNCAPPED selected reach for this permission (`any` for system context). */\n actorScope: `${RealmScope}`,\n /** Whether the actor's selected grant carries no policy. */\n actorPolicyFree: boolean,\n /** The id of the actor's selected grant policy (null when policy-free). */\n actorPolicyId: string | null,\n};\n\n/**\n * Build the `{ realmScope?, policyId? }` delta for a junction UPDATE, capped to the actor's\n * request-relative grant.\n *\n * - An unrestricted (`any`, policy-free) actor may set/clear `policyId` explicitly and is never\n * narrowed.\n * - A restricted/policy-bound actor that touches the binding inherits its own grant's policy AND\n * has the reach re-capped — including the EXISTING `realmScope` when the update omits it, so a\n * policy-only edit cannot leave a wider pre-existing reach standing (fail-OPEN otherwise: the\n * persisted binding must always be dominated by a grant the actor really holds — #3160).\n */\nexport function buildJunctionUpdateData(input: BuildJunctionUpdateDataInput): Record<string, any> {\n const {\n data, \n existingScope, \n actorScope, \n actorPolicyFree, \n actorPolicyId,\n } = input;\n\n const updateData: Record<string, any> = {};\n\n const touchesScope = hasOwnProperty(data, 'realmScope');\n const touchesPolicy = hasOwnProperty(data, 'policyId');\n\n // CAP to the actor's ceiling — a restricted actor may narrow but never widen.\n // (`data` is the validated UPDATE payload, so realmScope is already a valid enum value;\n // minRealmScope additionally normalizes any out-of-band input fail-closed to `own`.)\n if (touchesScope) {\n updateData.realmScope = minRealmScope([data.realmScope as `${RealmScope}`, actorScope]);\n }\n\n if (actorScope === RealmScope.ANY && actorPolicyFree) {\n if (touchesPolicy) {\n updateData.policyId = data.policyId;\n }\n } else if (touchesScope || touchesPolicy) {\n updateData.policyId = actorPolicyId;\n\n if (!touchesScope) {\n updateData.realmScope = minRealmScope([existingScope, actorScope]);\n }\n }\n\n return updateData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;GAiCA,SAAgBG,yBACZC,WACAC,OAAiC;CAEjCD,UAAUE,aAAaL,cAAc,CAACG,UAAUE,cAAcN,WAAWO,KAAKF,MAAMC,
|
|
1
|
+
{"version":3,"file":"junction-grant.mjs","names":["RealmScope","minRealmScope","hasOwnProperty","applyJunctionCreateGrant","validated","grant","realmScope","OWN","ANY","policy","policyId","id","buildJunctionUpdateData","input","data","existingScope","actorScope","actorPolicyFree","actorPolicyId","updateData","touchesScope","touchesPolicy"],"sources":["../../../../src/core/identity/permission/junction-grant.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 { RealmScope, minRealmScope } from '@authup/access';\nimport { hasOwnProperty } from '@authup/kit';\nimport type { ResolveJunctionGrantResult } from './types.ts';\n\n/**\n * The privilege-escalation boundary for permission-binding junctions, shared verbatim by\n * role/user/client-permission. Kept in ONE place (rather than copied into each service)\n * so the fail-closed cap/inherit rule is audited and changed once — see #3160 / #3158 / #3159,\n * which each had to patch this rule across all four services.\n *\n * It depends on a server-core type (`ResolveJunctionGrantResult`) and so cannot live on the\n * generic `JunctionEntityService` in `@authup/server-kit` (that would invert the layering).\n */\n\n/**\n * Cap a junction CREATE to the actor's request-relative selected grant and inherit its policy.\n *\n * - `realmScope` is capped to the actor's selected reach (`min(requested, grant.realmScope)`).\n * - The policy follows the grant: only a genuinely unrestricted actor (an UNCAPPED `any` reach\n * AND no policy) may keep an explicitly-requested `policyId`; any restricted/policy-bound\n * actor inherits its own grant's policy (it can neither attach an unowned policy nor detach to\n * widen). The check reads `grant.realmScope` UNCAPPED precisely to distinguish that case — the\n * grant is returned uncapped by `resolveJunctionGrant` for exactly this reason.\n *\n * Mutates `validated` in place (mirrors the surrounding service style).\n */\nexport function applyJunctionCreateGrant(\n validated: Record<string, any>,\n grant: ResolveJunctionGrantResult,\n): void {\n validated.realmScope = minRealmScope([validated.realmScope ?? RealmScope.OWN, grant.realmScope]);\n\n if (grant.realmScope !== RealmScope.ANY || grant.policy) {\n validated.policyId = grant.policy ? grant.policy.id : null;\n }\n}\n\nexport type BuildJunctionUpdateDataInput = {\n /** The validated update payload (UPDATE group) — presence of a key signals caller intent. */\n data: Record<string, any>,\n /** The persisted junction's current reach (used to re-cap a policy-only edit). */\n existingScope: `${RealmScope}`,\n /** The actor's UNCAPPED selected reach for this permission (`any` for system context). */\n actorScope: `${RealmScope}`,\n /** Whether the actor's selected grant carries no policy. */\n actorPolicyFree: boolean,\n /** The id of the actor's selected grant policy (null when policy-free). */\n actorPolicyId: string | null,\n};\n\n/**\n * Build the `{ realmScope?, policyId? }` delta for a junction UPDATE, capped to the actor's\n * request-relative grant.\n *\n * - An unrestricted (`any`, policy-free) actor may set/clear `policyId` explicitly and is never\n * narrowed.\n * - A restricted/policy-bound actor that touches the binding inherits its own grant's policy AND\n * has the reach re-capped — including the EXISTING `realmScope` when the update omits it, so a\n * policy-only edit cannot leave a wider pre-existing reach standing (fail-OPEN otherwise: the\n * persisted binding must always be dominated by a grant the actor really holds — #3160).\n */\nexport function buildJunctionUpdateData(input: BuildJunctionUpdateDataInput): Record<string, any> {\n const {\n data, \n existingScope, \n actorScope, \n actorPolicyFree, \n actorPolicyId,\n } = input;\n\n const updateData: Record<string, any> = {};\n\n const touchesScope = hasOwnProperty(data, 'realmScope');\n const touchesPolicy = hasOwnProperty(data, 'policyId');\n\n // CAP to the actor's ceiling — a restricted actor may narrow but never widen.\n // (`data` is the validated UPDATE payload, so realmScope is already a valid enum value;\n // minRealmScope additionally normalizes any out-of-band input fail-closed to `own`.)\n if (touchesScope) {\n updateData.realmScope = minRealmScope([data.realmScope as `${RealmScope}`, actorScope]);\n }\n\n if (actorScope === RealmScope.ANY && actorPolicyFree) {\n if (touchesPolicy) {\n updateData.policyId = data.policyId;\n }\n } else if (touchesScope || touchesPolicy) {\n updateData.policyId = actorPolicyId;\n\n if (!touchesScope) {\n updateData.realmScope = minRealmScope([existingScope, actorScope]);\n }\n }\n\n return updateData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;GAiCA,SAAgBG,yBACZC,WACAC,OAAiC;CAEjCD,UAAUE,aAAaL,cAAc,CAACG,UAAUE,cAAcN,WAAWO,KAAKF,MAAMC,UAAW,CAAA;CAE/F,IAAID,MAAMC,eAAeN,WAAWQ,OAAOH,MAAMI,QAC7CL,UAAUM,WAAWL,MAAMI,SAASJ,MAAMI,OAAOE,KAAK;AAE9D;;;;;;;;;;;GA0BA,SAAgBC,wBAAwBC,OAAmC;CACvE,MAAM,EACFC,MACAC,eACAC,YACAC,iBACAC,kBACAL;CAEJ,MAAMM,aAAkC,CAAC;CAEzC,MAAMC,eAAelB,eAAeY,MAAM,YAAA;CAC1C,MAAMO,gBAAgBnB,eAAeY,MAAM,UAAA;CAK3C,IAAIM,cACAD,WAAWb,aAAaL,cAAc,CAACa,KAAKR,YAA+BU,UAAW,CAAA;CAG1F,IAAIA,eAAehB,WAAWQ,OAAOS,iBAC7BI;MAAAA,eACAF,WAAWT,WAAWI,KAAKJ;CAAAA,OAE5B,IAAIU,gBAAgBC,eAAe;EACtCF,WAAWT,WAAWQ;EAEtB,IAAI,CAACE,cACDD,WAAWb,aAAaL,cAAc,CAACc,eAAeC,UAAW,CAAA;CAEzE;CAEA,OAAOG;AACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["RealmScope","aggregatePermissionPolicyBindings","compareRealmScope","grantDominates","isPermissionPolicyBindingEqual","minRealmScope","isPolicy","IdentityPermissionProvider","clientRepository","userRepository","roleRepository","roleProvider","ctx","isSuperset","parent","child","parentAggregated","getFor","childAggregated","childItem","parentItem","find","p","childGrant","grants","dominated","some","parentGrant","resolveJunctionGrant","identity","options","bindings","matching","filter","b","permission","name","realmId","clientId","length","realmScope","OWN","flatMap","item","requested","selected","selectGrantForRequest","policy","NONE","type","getForClient","getForUser","getForRole","combineWithRoleBindings","getBoundPermissions","id","then","data","reduceBindingsByIdentityClient","bindingsPromise","roles","Promise","all","getRolesFor","roleBindings","getBoundPermissionsForMany","binding","reduce","best","grant","isGrantPreferred","candidate","incumbent","byCapped","byUncapped","candidateId","undefined","incumbentId"],"sources":["../../../../src/core/identity/permission/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\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 {\n IdentityPolicyData,\n PermissionGrant,\n PermissionPolicyBinding,\n} from '@authup/access';\nimport {\n RealmScope,\n aggregatePermissionPolicyBindings,\n compareRealmScope,\n grantDominates,\n isPermissionPolicyBindingEqual,\n minRealmScope,\n} from '@authup/access';\nimport type { Policy } from '@authup/core-kit';\nimport { isPolicy } from '@authup/core-kit';\nimport type { IClientRepository } from '../../entities/client/types.ts';\nimport type { IRoleRepository } from '../../entities/role/types.ts';\nimport type { IUserRepository } from '../../entities/user/types.ts';\nimport type { IIdentityRoleProvider } from '../role/types.ts';\nimport type {\n IIdentityPermissionProvider,\n IdentityPermissionProviderContext,\n ResolveJunctionGrantResult,\n ResolveJunctionPolicyOptions,\n} from './types.ts';\n\nexport class IdentityPermissionProvider implements IIdentityPermissionProvider {\n protected clientRepository: IClientRepository;\n\n protected userRepository: IUserRepository;\n\n protected roleRepository: IRoleRepository;\n\n protected roleProvider: IIdentityRoleProvider;\n\n constructor(ctx: IdentityPermissionProviderContext) {\n this.clientRepository = ctx.clientRepository;\n this.userRepository = ctx.userRepository;\n this.roleRepository = ctx.roleRepository;\n this.roleProvider = ctx.roleProvider;\n }\n\n async isSuperset(parent: IdentityPolicyData, child: IdentityPolicyData) : Promise<boolean> {\n const parentAggregated = aggregatePermissionPolicyBindings(await this.getFor(parent));\n const childAggregated = aggregatePermissionPolicyBindings(await this.getFor(child));\n\n for (const childItem of childAggregated) {\n const parentItem = parentAggregated.find(\n (p) => isPermissionPolicyBindingEqual(p, childItem),\n );\n\n if (!parentItem) {\n return false;\n }\n\n // Disjunction-aware superset: EVERY child grant must be dominated by SOME parent\n // grant (reach >= AND the parent's policy provably covers the child's — see\n // grantDominates). A child grant the parent cannot match — an unconditional `any`\n // the parent only holds policy-gated, or a policy the parent does not itself hold\n // (#3159) — fails the check; the actor cannot assign more than it holds.\n for (const childGrant of childItem.grants) {\n const dominated = parentItem.grants.some(\n (parentGrant) => grantDominates(parentGrant, childGrant),\n );\n\n if (!dominated) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n async resolveJunctionGrant(\n identity: IdentityPolicyData,\n options: ResolveJunctionPolicyOptions,\n ): Promise<ResolveJunctionGrantResult> {\n const bindings = await this.getFor(identity);\n const matching = bindings.filter((b) => {\n if (b.permission.name !== options.name) {\n return false;\n }\n\n if (typeof options.realmId !== 'undefined') {\n if ((b.permission.realmId ?? null) !== (options.realmId ?? null)) {\n return false;\n }\n }\n\n if (typeof options.clientId !== 'undefined') {\n if ((b.permission.clientId ?? null) !== (options.clientId ?? null)) {\n return false;\n }\n }\n\n return true;\n });\n\n if (matching.length === 0) {\n return { realmScope: RealmScope.OWN };\n }\n\n // Consider EVERY matching grant (a caller omitting realmId/clientId may leave more\n // than one permission-key group); combined with the total ordering in\n // selectGrantForRequest, the selection never depends on grant/repository order.\n const grants = aggregatePermissionPolicyBindings(matching)\n .flatMap((item) => item.grants);\n if (grants.length === 0) {\n return { realmScope: RealmScope.OWN };\n }\n\n // Select the actor's grant RELATIVE to the requested reach (#3160): the grant that\n // confers the least-restrictive junction once capped to `realmScope` (highest capped\n // reach, policy-free preferred on a tie) — NOT a global \"ceiling\". A mixed-grant actor\n // (e.g. own+no-policy and any+policy) thus propagates its policy-free own grant for an\n // own request instead of inheriting the wider grant's policy. The selected grant is\n // returned UNCAPPED so the consumer's own cap (`min(requested, realmScope)`) and its\n // \"actor is unrestricted-any?\" check (which honours an explicit policyId) still hold.\n const requested = options.realmScope ?? RealmScope.OWN;\n const selected = selectGrantForRequest(grants, requested);\n\n let policy: Policy | undefined;\n if (selected.policy) {\n // The selected grant is policy-restricted but its policy is not a propagatable\n // Policy (e.g. a composite with no id). Fail CLOSED: a `none` reach blocks\n // propagation rather than silently dropping the restriction and widening to an\n // unrestricted grant.\n if (!isPolicy(selected.policy)) {\n return { realmScope: RealmScope.NONE };\n }\n\n policy = selected.policy;\n }\n\n return { policy, realmScope: selected.realmScope };\n }\n\n async getFor(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n switch (identity.type) {\n case 'client': {\n return this.getForClient(identity);\n }\n case 'user': {\n return this.getForUser(identity);\n }\n case 'role': {\n return this.getForRole(identity);\n }\n }\n\n return [];\n }\n\n async getForClient(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n return this.combineWithRoleBindings(\n this.clientRepository.getBoundPermissions(identity.id),\n identity,\n );\n }\n\n async getForUser(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n return this.combineWithRoleBindings(\n this.userRepository.getBoundPermissions(identity.id)\n .then((data) => this.reduceBindingsByIdentityClient(data, identity)),\n identity,\n );\n }\n\n async getForRole(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n return this.roleRepository.getBoundPermissions(identity.id)\n .then((data) => this.reduceBindingsByIdentityClient(data, identity));\n }\n\n private async combineWithRoleBindings(\n bindingsPromise: Promise<PermissionPolicyBinding[]>,\n identity: IdentityPolicyData,\n ): Promise<PermissionPolicyBinding[]> {\n const [bindings, roles] = await Promise.all([\n bindingsPromise,\n this.roleProvider.getRolesFor(identity),\n ]);\n const roleBindings = await this.roleRepository.getBoundPermissionsForMany(roles);\n if (roleBindings.length === 0) {\n return bindings;\n }\n\n return [\n ...bindings,\n ...roleBindings,\n ];\n }\n\n private reduceBindingsByIdentityClient(\n bindings: PermissionPolicyBinding[],\n identity: IdentityPolicyData,\n ): PermissionPolicyBinding[] {\n if (!identity.clientId) {\n return bindings;\n }\n\n return bindings.filter((binding) => binding.permission.clientId === identity.clientId);\n }\n}\n\n/**\n * Select the held grant that confers the least-restrictive junction for `requested` reach.\n *\n * Each grant is ranked by the reach it can actually confer for THIS request — its own\n * `realmScope` capped to `requested` — so a lower-scoped policy-free grant beats a\n * higher-scoped policy-bound grant when both cap to the same requested reach (the mixed-grant\n * fix, #3160). On equal capped reach, a policy-free grant wins (least restrictive). The\n * ORIGINAL (uncapped) grant is returned: the consumer applies the `min` cap itself, and its\n * uncapped `realmScope`/`policy` drive the \"actor is unrestricted-any?\" check that decides\n * whether an explicitly-requested `policyId` may stand.\n *\n * The ordering is TOTAL and deterministic (independent of grant/repository order): ties between\n * two policy-bound grants on equal capped reach are broken by higher uncapped reach, then a\n * propagatable policy (one with an id) over an id-less composite that would fail closed, then\n * lexicographic policy id.\n */\nfunction selectGrantForRequest(\n grants: PermissionGrant[],\n requested: `${RealmScope}`,\n): PermissionGrant {\n return grants.reduce((best, grant) => (isGrantPreferred(grant, best, requested) ? grant : best));\n}\n\n/** True when `candidate` is a strictly better propagation source than `incumbent` for `requested`. */\nfunction isGrantPreferred(\n candidate: PermissionGrant,\n incumbent: PermissionGrant,\n requested: `${RealmScope}`,\n): boolean {\n const byCapped = compareRealmScope(\n minRealmScope([candidate.realmScope, requested]),\n minRealmScope([incumbent.realmScope, requested]),\n );\n if (byCapped !== 0) {\n return byCapped > 0;\n }\n\n // Least restrictive: a policy-free grant beats a policy-bound one on equal capped reach.\n if (!candidate.policy !== !incumbent.policy) {\n return !candidate.policy;\n }\n\n // Deterministic tie-break for two policy-bound grants on equal capped reach.\n const byUncapped = compareRealmScope(candidate.realmScope, incumbent.realmScope);\n if (byUncapped !== 0) {\n return byUncapped > 0;\n }\n\n // Prefer a propagatable policy (has an id) over an id-less composite that would fail closed.\n const candidateId = candidate.policy && isPolicy(candidate.policy) ? candidate.policy.id : undefined;\n const incumbentId = incumbent.policy && isPolicy(incumbent.policy) ? incumbent.policy.id : undefined;\n if (candidateId !== incumbentId) {\n if (typeof candidateId === 'undefined') {\n return false;\n }\n if (typeof incumbentId === 'undefined') {\n return true;\n }\n return candidateId < incumbentId;\n }\n\n return false;\n}\n"],"mappings":";;;;;;AAiCA,IAAaO,6BAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAwC;EAChD,KAAKJ,mBAAmBI,IAAIJ;EAC5B,KAAKC,iBAAiBG,IAAIH;EAC1B,KAAKC,iBAAiBE,IAAIF;EAC1B,KAAKC,eAAeC,IAAID;CAC5B;CAEA,MAAME,WAAWC,QAA4BC,OAA8C;EACvF,MAAMC,mBAAmBf,kCAAkC,MAAM,KAAKgB,OAAOH,MAAAA,CAAAA;EAC7E,MAAMI,kBAAkBjB,kCAAkC,MAAM,KAAKgB,OAAOF,KAAAA,CAAAA;EAE5E,KAAK,MAAMI,aAAaD,iBAAiB;GACrC,MAAME,aAAaJ,iBAAiBK,MAC/BC,MAAMlB,+BAA+BkB,GAAGH,SAAAA,CAAAA;GAG7C,IAAI,CAACC,YACD,OAAO;GAQX,KAAK,MAAMG,cAAcJ,UAAUK,QAK/B,IAAI,CAJcJ,WAAWI,OAAOE,MAC/BC,gBAAgBxB,eAAewB,aAAaJ,UAAAA,CAG5CE,GACD,OAAO;EAGnB;EAEA,OAAO;CACX;CAEA,MAAMG,qBACFC,UACAC,SACmC;EAEnC,MAAME,YAAWD,MADM,KAAKd,OAAOY,QAAAA,EAAAA,CACTI,QAAQC,MAAAA;GAC9B,IAAIA,EAAEC,WAAWC,SAASN,QAAQM,MAC9B,OAAO;GAGX,IAAI,OAAON,QAAQO,YAAY;SACtBH,EAAEC,WAAWE,WAAW,WAAWP,QAAQO,WAAW,OACvD,OAAO;GAAA;GAIf,IAAI,OAAOP,QAAQQ,aAAa;SACvBJ,EAAEC,WAAWG,YAAY,WAAWR,QAAQQ,YAAY,OACzD,OAAO;GAAA;GAIf,OAAO;EACX,CAAA;EAEA,IAAIN,SAASO,WAAW,GACpB,OAAO,EAAEC,YAAYxC,WAAWyC,IAAI;EAMxC,MAAMjB,SAASvB,kCAAkC+B,QAAAA,CAAAA,CAC5CU,SAASC,SAASA,KAAKnB,MAAM;EAClC,IAAIA,OAAOe,WAAW,GAClB,OAAO,EAAEC,YAAYxC,WAAWyC,IAAI;EAWxC,MAAMI,WAAWC,sBAAsBtB,QADrBM,QAAQU,cAAcxC,WAAWyC,GACJG;EAE/C,IAAIG;EACJ,IAAIF,SAASE,QAAQ;GAKjB,IAAI,CAACzC,SAASuC,SAASE,MAAM,GACzB,OAAO,EAAEP,YAAYxC,WAAWgD,KAAK;GAGzCD,SAASF,SAASE;EACtB;EAEA,OAAO;GAAEA;GAAQP,YAAYK,SAASL;EAAW;CACrD;CAEA,MAAMvB,OAAOY,UAAmE;EAC5E,QAAQA,SAASoB,MAAjB;GACI,KAAK,UACD,OAAO,KAAKC,aAAarB,QAAAA;GAE7B,KAAK,QACD,OAAO,KAAKsB,WAAWtB,QAAAA;GAE3B,KAAK,QACD,OAAO,KAAKuB,WAAWvB,QAAAA;EAE/B;EAEA,OAAO,CAAA;CACX;CAEA,MAAMqB,aAAarB,UAAmE;EAClF,OAAO,KAAKwB,wBACR,KAAK7C,iBAAiB8C,oBAAoBzB,SAAS0B,EAAE,GACrD1B,QAAAA;CAER;CAEA,MAAMsB,WAAWtB,UAAmE;EAChF,OAAO,KAAKwB,wBACR,KAAK5C,eAAe6C,oBAAoBzB,SAAS0B,EAAE,CAAA,CAC9CC,MAAMC,SAAS,KAAKC,+BAA+BD,MAAM5B,QAAAA,CAAAA,GAC9DA,QAAAA;CAER;CAEA,MAAMuB,WAAWvB,UAAmE;EAChF,OAAO,KAAKnB,eAAe4C,oBAAoBzB,SAAS0B,EAAE,CAAA,CACrDC,MAAMC,SAAS,KAAKC,+BAA+BD,MAAM5B,QAAAA,CAAAA;CAClE;CAEA,MAAcwB,wBACVM,iBACA9B,UACkC;EAClC,MAAM,CAACE,UAAU6B,SAAS,MAAMC,QAAQC,IAAI,CACxCH,iBACA,KAAKhD,aAAaoD,YAAYlC,QAAAA,CAAAA,CACjC;EACD,MAAMmC,eAAe,MAAM,KAAKtD,eAAeuD,2BAA2BL,KAAAA;EAC1E,IAAII,aAAazB,WAAW,GACxB,OAAOR;EAGX,OAAO,CAAA,GACAA,UAAAA,GACAiC,YAAAA;CAEX;CAEQN,+BACJ3B,UACAF,UACyB;EACzB,IAAI,CAACA,SAASS,UACV,OAAOP;EAGX,OAAOA,SAASE,QAAQiC,YAAYA,QAAQ/B,WAAWG,aAAaT,SAASS,QAAQ;CACzF;AACJ;;;;;;;;;;;;;;;;GAkBA,SAASQ,sBACLtB,QACAoB,WAA0B;CAE1B,OAAOpB,OAAO2C,QAAQC,MAAMC,UAAWC,iBAAiBD,OAAOD,MAAMxB,SAAAA,IAAayB,QAAQD,IAAAA;AAC9F;uGAGA,SAASE,iBACLC,WACAC,WACA5B,WAA0B;CAE1B,MAAM6B,WAAWvE,kBACbG,cAAc,CAACkE,UAAU/B,YAAYI,SAAAA,CAAU,GAC/CvC,cAAc,CAACmE,UAAUhC,YAAYI,SAAAA,CAAU,CAAA;CAEnD,IAAI6B,aAAa,GACb,OAAOA,WAAW;CAItB,IAAI,CAACF,UAAUxB,WAAW,CAACyB,UAAUzB,QACjC,OAAO,CAACwB,UAAUxB;CAItB,MAAM2B,aAAaxE,kBAAkBqE,UAAU/B,YAAYgC,UAAUhC,UAAU;CAC/E,IAAIkC,eAAe,GACf,OAAOA,aAAa;CAIxB,MAAMC,cAAcJ,UAAUxB,UAAUzC,SAASiE,UAAUxB,MAAM,IAAIwB,UAAUxB,OAAOQ,KAAKqB,KAAAA;CAC3F,MAAMC,cAAcL,UAAUzB,UAAUzC,SAASkE,UAAUzB,MAAM,IAAIyB,UAAUzB,OAAOQ,KAAKqB,KAAAA;CAC3F,IAAID,gBAAgBE,aAAa;EAC7B,IAAI,OAAOF,gBAAgB,aACvB,OAAO;EAEX,IAAI,OAAOE,gBAAgB,aACvB,OAAO;EAEX,OAAOF,cAAcE;CACzB;CAEA,OAAO;AACX"}
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["RealmScope","aggregatePermissionPolicyBindings","compareRealmScope","grantDominates","isPermissionPolicyBindingEqual","minRealmScope","isPolicy","IdentityPermissionProvider","clientRepository","userRepository","roleRepository","roleProvider","ctx","isSuperset","parent","child","parentAggregated","getFor","childAggregated","childItem","parentItem","find","p","childGrant","grants","dominated","some","parentGrant","resolveJunctionGrant","identity","options","bindings","matching","filter","b","permission","name","realmId","clientId","length","realmScope","OWN","flatMap","item","requested","selected","selectGrantForRequest","policy","NONE","type","getForClient","getForUser","getForRole","combineWithRoleBindings","getBoundPermissions","id","then","data","reduceBindingsByIdentityClient","bindingsPromise","roles","Promise","all","getRolesFor","roleBindings","getBoundPermissionsForMany","binding","reduce","best","grant","isGrantPreferred","candidate","incumbent","byCapped","byUncapped","candidateId","undefined","incumbentId"],"sources":["../../../../src/core/identity/permission/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\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 {\n IdentityPolicyData,\n PermissionGrant,\n PermissionPolicyBinding,\n} from '@authup/access';\nimport {\n RealmScope,\n aggregatePermissionPolicyBindings,\n compareRealmScope,\n grantDominates,\n isPermissionPolicyBindingEqual,\n minRealmScope,\n} from '@authup/access';\nimport type { Policy } from '@authup/core-kit';\nimport { isPolicy } from '@authup/core-kit';\nimport type { IClientRepository } from '../../entities/client/types.ts';\nimport type { IRoleRepository } from '../../entities/role/types.ts';\nimport type { IUserRepository } from '../../entities/user/types.ts';\nimport type { IIdentityRoleProvider } from '../role/types.ts';\nimport type {\n IIdentityPermissionProvider,\n IdentityPermissionProviderContext,\n ResolveJunctionGrantResult,\n ResolveJunctionPolicyOptions,\n} from './types.ts';\n\nexport class IdentityPermissionProvider implements IIdentityPermissionProvider {\n protected clientRepository: IClientRepository;\n\n protected userRepository: IUserRepository;\n\n protected roleRepository: IRoleRepository;\n\n protected roleProvider: IIdentityRoleProvider;\n\n constructor(ctx: IdentityPermissionProviderContext) {\n this.clientRepository = ctx.clientRepository;\n this.userRepository = ctx.userRepository;\n this.roleRepository = ctx.roleRepository;\n this.roleProvider = ctx.roleProvider;\n }\n\n async isSuperset(parent: IdentityPolicyData, child: IdentityPolicyData) : Promise<boolean> {\n const parentAggregated = aggregatePermissionPolicyBindings(await this.getFor(parent));\n const childAggregated = aggregatePermissionPolicyBindings(await this.getFor(child));\n\n for (const childItem of childAggregated) {\n const parentItem = parentAggregated.find(\n (p) => isPermissionPolicyBindingEqual(p, childItem),\n );\n\n if (!parentItem) {\n return false;\n }\n\n // Disjunction-aware superset: EVERY child grant must be dominated by SOME parent\n // grant (reach >= AND the parent's policy provably covers the child's — see\n // grantDominates). A child grant the parent cannot match — an unconditional `any`\n // the parent only holds policy-gated, or a policy the parent does not itself hold\n // (#3159) — fails the check; the actor cannot assign more than it holds.\n for (const childGrant of childItem.grants) {\n const dominated = parentItem.grants.some(\n (parentGrant) => grantDominates(parentGrant, childGrant),\n );\n\n if (!dominated) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n async resolveJunctionGrant(\n identity: IdentityPolicyData,\n options: ResolveJunctionPolicyOptions,\n ): Promise<ResolveJunctionGrantResult> {\n const bindings = await this.getFor(identity);\n const matching = bindings.filter((b) => {\n if (b.permission.name !== options.name) {\n return false;\n }\n\n if (typeof options.realmId !== 'undefined') {\n if ((b.permission.realmId ?? null) !== (options.realmId ?? null)) {\n return false;\n }\n }\n\n if (typeof options.clientId !== 'undefined') {\n if ((b.permission.clientId ?? null) !== (options.clientId ?? null)) {\n return false;\n }\n }\n\n return true;\n });\n\n if (matching.length === 0) {\n return { realmScope: RealmScope.OWN };\n }\n\n // Consider EVERY matching grant (a caller omitting realmId/clientId may leave more\n // than one permission-key group); combined with the total ordering in\n // selectGrantForRequest, the selection never depends on grant/repository order.\n const grants = aggregatePermissionPolicyBindings(matching)\n .flatMap((item) => item.grants);\n if (grants.length === 0) {\n return { realmScope: RealmScope.OWN };\n }\n\n // Select the actor's grant RELATIVE to the requested reach (#3160): the grant that\n // confers the least-restrictive junction once capped to `realmScope` (highest capped\n // reach, policy-free preferred on a tie) — NOT a global \"ceiling\". A mixed-grant actor\n // (e.g. own+no-policy and any+policy) thus propagates its policy-free own grant for an\n // own request instead of inheriting the wider grant's policy. The selected grant is\n // returned UNCAPPED so the consumer's own cap (`min(requested, realmScope)`) and its\n // \"actor is unrestricted-any?\" check (which honours an explicit policyId) still hold.\n const requested = options.realmScope ?? RealmScope.OWN;\n const selected = selectGrantForRequest(grants, requested);\n\n let policy: Policy | undefined;\n if (selected.policy) {\n // The selected grant is policy-restricted but its policy is not a propagatable\n // Policy (e.g. a composite with no id). Fail CLOSED: a `none` reach blocks\n // propagation rather than silently dropping the restriction and widening to an\n // unrestricted grant.\n if (!isPolicy(selected.policy)) {\n return { realmScope: RealmScope.NONE };\n }\n\n policy = selected.policy;\n }\n\n return { policy, realmScope: selected.realmScope };\n }\n\n async getFor(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n switch (identity.type) {\n case 'client': {\n return this.getForClient(identity);\n }\n case 'user': {\n return this.getForUser(identity);\n }\n case 'role': {\n return this.getForRole(identity);\n }\n }\n\n return [];\n }\n\n async getForClient(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n return this.combineWithRoleBindings(\n this.clientRepository.getBoundPermissions(identity.id),\n identity,\n );\n }\n\n async getForUser(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n return this.combineWithRoleBindings(\n this.userRepository.getBoundPermissions(identity.id)\n .then((data) => this.reduceBindingsByIdentityClient(data, identity)),\n identity,\n );\n }\n\n async getForRole(identity: IdentityPolicyData) : Promise<PermissionPolicyBinding[]> {\n return this.roleRepository.getBoundPermissions(identity.id)\n .then((data) => this.reduceBindingsByIdentityClient(data, identity));\n }\n\n private async combineWithRoleBindings(\n bindingsPromise: Promise<PermissionPolicyBinding[]>,\n identity: IdentityPolicyData,\n ): Promise<PermissionPolicyBinding[]> {\n const [bindings, roles] = await Promise.all([\n bindingsPromise,\n this.roleProvider.getRolesFor(identity),\n ]);\n const roleBindings = await this.roleRepository.getBoundPermissionsForMany(roles);\n if (roleBindings.length === 0) {\n return bindings;\n }\n\n return [\n ...bindings,\n ...roleBindings,\n ];\n }\n\n private reduceBindingsByIdentityClient(\n bindings: PermissionPolicyBinding[],\n identity: IdentityPolicyData,\n ): PermissionPolicyBinding[] {\n if (!identity.clientId) {\n return bindings;\n }\n\n return bindings.filter((binding) => binding.permission.clientId === identity.clientId);\n }\n}\n\n/**\n * Select the held grant that confers the least-restrictive junction for `requested` reach.\n *\n * Each grant is ranked by the reach it can actually confer for THIS request — its own\n * `realmScope` capped to `requested` — so a lower-scoped policy-free grant beats a\n * higher-scoped policy-bound grant when both cap to the same requested reach (the mixed-grant\n * fix, #3160). On equal capped reach, a policy-free grant wins (least restrictive). The\n * ORIGINAL (uncapped) grant is returned: the consumer applies the `min` cap itself, and its\n * uncapped `realmScope`/`policy` drive the \"actor is unrestricted-any?\" check that decides\n * whether an explicitly-requested `policyId` may stand.\n *\n * The ordering is TOTAL and deterministic (independent of grant/repository order): ties between\n * two policy-bound grants on equal capped reach are broken by higher uncapped reach, then a\n * propagatable policy (one with an id) over an id-less composite that would fail closed, then\n * lexicographic policy id.\n */\nfunction selectGrantForRequest(\n grants: PermissionGrant[],\n requested: `${RealmScope}`,\n): PermissionGrant {\n return grants.reduce((best, grant) => (isGrantPreferred(grant, best, requested) ? grant : best));\n}\n\n/** True when `candidate` is a strictly better propagation source than `incumbent` for `requested`. */\nfunction isGrantPreferred(\n candidate: PermissionGrant,\n incumbent: PermissionGrant,\n requested: `${RealmScope}`,\n): boolean {\n const byCapped = compareRealmScope(\n minRealmScope([candidate.realmScope, requested]),\n minRealmScope([incumbent.realmScope, requested]),\n );\n if (byCapped !== 0) {\n return byCapped > 0;\n }\n\n // Least restrictive: a policy-free grant beats a policy-bound one on equal capped reach.\n if (!candidate.policy !== !incumbent.policy) {\n return !candidate.policy;\n }\n\n // Deterministic tie-break for two policy-bound grants on equal capped reach.\n const byUncapped = compareRealmScope(candidate.realmScope, incumbent.realmScope);\n if (byUncapped !== 0) {\n return byUncapped > 0;\n }\n\n // Prefer a propagatable policy (has an id) over an id-less composite that would fail closed.\n const candidateId = candidate.policy && isPolicy(candidate.policy) ? candidate.policy.id : undefined;\n const incumbentId = incumbent.policy && isPolicy(incumbent.policy) ? incumbent.policy.id : undefined;\n if (candidateId !== incumbentId) {\n if (typeof candidateId === 'undefined') {\n return false;\n }\n if (typeof incumbentId === 'undefined') {\n return true;\n }\n return candidateId < incumbentId;\n }\n\n return false;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderFacebookAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","attributeCandidates","name","username","email","firstName","first_name","lastName","last_name","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/facebook.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderFacebookAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://graph.facebook.com/oauth/authorize';\n ctx.provider.tokenUrl = 'https://graph.facebook.com/oauth/access_token';\n ctx.provider.userInfoUrl = 'https://graph.facebook.com/me?fields=id,name,email,first_name,last_name';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.id,\n attributeCandidates: {\n name: [\n userInfo.username,\n userInfo.id,\n ],\n email: [\n userInfo.email,\n ],\n firstName: [\n userInfo.first_name,\n ],\n lastName: [\n userInfo.last_name,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,wCAAb,cAA2DD,oCAAAA;CACvD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,SAASG,IAAIC,SAASC,KAAK;EAClEF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASO;GACbC,qBAAqB;IACjBC,MAAM,CACFT,SAASU,UACTV,SAASO,
|
|
1
|
+
{"version":3,"file":"facebook.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderFacebookAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","attributeCandidates","name","username","email","firstName","first_name","lastName","last_name","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/facebook.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderFacebookAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://graph.facebook.com/oauth/authorize';\n ctx.provider.tokenUrl = 'https://graph.facebook.com/oauth/access_token';\n ctx.provider.userInfoUrl = 'https://graph.facebook.com/me?fields=id,name,email,first_name,last_name';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.id,\n attributeCandidates: {\n name: [\n userInfo.username,\n userInfo.id,\n ],\n email: [\n userInfo.email,\n ],\n firstName: [\n userInfo.first_name,\n ],\n lastName: [\n userInfo.last_name,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,wCAAb,cAA2DD,oCAAAA;CACvD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,SAASG,IAAIC,SAASC,KAAK;EAClEF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASO;GACbC,qBAAqB;IACjBC,MAAM,CACFT,SAASU,UACTV,SAASO,EACZ;IACDI,OAAO,CACHX,SAASW,KACZ;IACDC,WAAW,CACPZ,SAASa,UACZ;IACDC,UAAU,CACNd,SAASe,SACZ;GACL;GACAC,MAAMV;GACNb,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderGithubAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","attributeCandidates","name","login","email","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/github.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderGithubAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('user:email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://github.com/login/oauth/authorize';\n ctx.provider.tokenUrl = 'https://github.com/login/oauth/access_token';\n ctx.provider.userInfoUrl = 'https://api.github.com/user';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.id,\n attributeCandidates: {\n name: [\n userInfo.login,\n userInfo.name,\n userInfo.id,\n ],\n email: [\n userInfo.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,cAAcG,IAAIC,SAASC,KAAK;EACvEF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASO;GACbC,qBAAqB;IACjBC,MAAM;KACFT,SAASU;KACTV,SAASS;KACTT,SAASO
|
|
1
|
+
{"version":3,"file":"github.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderGithubAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","attributeCandidates","name","login","email","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/github.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderGithubAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('user:email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://github.com/login/oauth/authorize';\n ctx.provider.tokenUrl = 'https://github.com/login/oauth/access_token';\n ctx.provider.userInfoUrl = 'https://api.github.com/user';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.id,\n attributeCandidates: {\n name: [\n userInfo.login,\n userInfo.name,\n userInfo.id,\n ],\n email: [\n userInfo.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,cAAcG,IAAIC,SAASC,KAAK;EACvEF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASO;GACbC,qBAAqB;IACjBC,MAAM;KACFT,SAASU;KACTV,SAASS;KACTT,SAASO;IACZ;IACDI,OAAO,CACHX,SAASW,KACZ;GACL;GACAC,MAAMN;GACNb,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderGoogleAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","payload","access_token","attributeCandidates","id_token","idTokenPayload","name","email","firstName","given_name","lastName","family_name","id","sub","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/google.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { User } from '@authup/core-kit';\nimport { extractTokenPayload } from '@authup/server-kit';\nimport type { OpenIDTokenPayload } from '@authup/specs';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderGoogleAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('openid profile email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://accounts.google.com/o/oauth2/v2/auth';\n ctx.provider.tokenUrl = 'https://oauth2.googleapis.com/token';\n ctx.provider.userInfoUrl = 'https://openidconnect.googleapis.com/v1/userinfo';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const payload = extractTokenPayload(input.access_token);\n\n const attributeCandidates : Record<keyof User, unknown[]> = {};\n\n /**\n * @see https://developers.google.com/identity/openid-connect/openid-connect?hl=de#server-flow\n */\n if (input.id_token) {\n const idTokenPayload = extractTokenPayload(input.id_token) as OpenIDTokenPayload;\n\n attributeCandidates.name = [\n idTokenPayload.name,\n ];\n\n attributeCandidates.email = [\n idTokenPayload.email,\n ];\n\n attributeCandidates.firstName = [\n idTokenPayload.given_name,\n ];\n attributeCandidates.lastName = [\n idTokenPayload.family_name,\n ];\n }\n\n return {\n id: payload.sub!,\n attributeCandidates,\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,wBAAwBG,IAAIC,SAASC,KAAK;EACjFF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,UAAUZ,oBAAoBW,MAAME,YAAY;EAEtD,MAAMC,sBAAsD,CAAC;;;KAK7D,IAAIH,MAAMI,UAAU;GAChB,MAAMC,iBAAiBhB,oBAAoBW,MAAMI,QAAQ;GAEzDD,oBAAoBG,OAAO,CACvBD,eAAeC,
|
|
1
|
+
{"version":3,"file":"google.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderGoogleAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","payload","access_token","attributeCandidates","id_token","idTokenPayload","name","email","firstName","given_name","lastName","family_name","id","sub","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/google.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { User } from '@authup/core-kit';\nimport { extractTokenPayload } from '@authup/server-kit';\nimport type { OpenIDTokenPayload } from '@authup/specs';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderGoogleAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('openid profile email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://accounts.google.com/o/oauth2/v2/auth';\n ctx.provider.tokenUrl = 'https://oauth2.googleapis.com/token';\n ctx.provider.userInfoUrl = 'https://openidconnect.googleapis.com/v1/userinfo';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const payload = extractTokenPayload(input.access_token);\n\n const attributeCandidates : Record<keyof User, unknown[]> = {};\n\n /**\n * @see https://developers.google.com/identity/openid-connect/openid-connect?hl=de#server-flow\n */\n if (input.id_token) {\n const idTokenPayload = extractTokenPayload(input.id_token) as OpenIDTokenPayload;\n\n attributeCandidates.name = [\n idTokenPayload.name,\n ];\n\n attributeCandidates.email = [\n idTokenPayload.email,\n ];\n\n attributeCandidates.firstName = [\n idTokenPayload.given_name,\n ];\n attributeCandidates.lastName = [\n idTokenPayload.family_name,\n ];\n }\n\n return {\n id: payload.sub!,\n attributeCandidates,\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,wBAAwBG,IAAIC,SAASC,KAAK;EACjFF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,UAAUZ,oBAAoBW,MAAME,YAAY;EAEtD,MAAMC,sBAAsD,CAAC;;;KAK7D,IAAIH,MAAMI,UAAU;GAChB,MAAMC,iBAAiBhB,oBAAoBW,MAAMI,QAAQ;GAEzDD,oBAAoBG,OAAO,CACvBD,eAAeC,IAClB;GAEDH,oBAAoBI,QAAQ,CACxBF,eAAeE,KAClB;GAEDJ,oBAAoBK,YAAY,CAC5BH,eAAeI,UAClB;GACDN,oBAAoBO,WAAW,CAC3BL,eAAeM,WAClB;EACL;EAEA,OAAO;GACHC,IAAIX,QAAQY;GACZV;GACAW,MAAMb;GACNP,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instagram.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderInstagramAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","attributeCandidates","name","username","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/instagram.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderInstagramAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('user_profile', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://api.instagram.com/oauth/authorize';\n ctx.provider.tokenUrl = 'https://api.instagram.com/oauth/access_token';\n ctx.provider.userInfoUrl = 'https://graph.instagram.com/me?fields=id,username';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.id,\n attributeCandidates: {\n name: [\n userInfo.username,\n userInfo.id,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,yCAAb,cAA4DD,oCAAAA;CACxD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,gBAAgBG,IAAIC,SAASC,KAAK;EACzEF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASO;GACbC,qBAAqB,EACjBC,MAAM,CACFT,SAASU,UACTV,SAASO,
|
|
1
|
+
{"version":3,"file":"instagram.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderInstagramAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","attributeCandidates","name","username","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/instagram.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderInstagramAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('user_profile', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://api.instagram.com/oauth/authorize';\n ctx.provider.tokenUrl = 'https://api.instagram.com/oauth/access_token';\n ctx.provider.userInfoUrl = 'https://graph.instagram.com/me?fields=id,username';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.id,\n attributeCandidates: {\n name: [\n userInfo.username,\n userInfo.id,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,yCAAb,cAA4DD,oCAAAA;CACxD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,gBAAgBG,IAAIC,SAASC,KAAK;EACzEF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASO;GACbC,qBAAqB,EACjBC,MAAM,CACFT,SAASU,UACTV,SAASO,EACZ,EACL;GACAI,MAAML;GACNb,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paypal.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderPaypalAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","user_id","attributeCandidates","name","email","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/paypal.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderPaypalAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('openid profile email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://www.paypal.com/signin/authorize';\n ctx.provider.tokenUrl = 'https://api.paypal.com/v1/identity/openidconnect/tokenservice';\n ctx.provider.userInfoUrl = 'https://api.paypal.com/v1/oauth2/token/userinfo?schema=openid';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.user_id,\n attributeCandidates: {\n name: [\n userInfo.name,\n userInfo.user_id,\n ],\n email: [\n userInfo.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,wBAAwBG,IAAIC,SAASC,KAAK;EACjFF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASQ;GACbC,qBAAqB;IACjBC,MAAM,CACFV,SAASU,MACTV,SAASQ,
|
|
1
|
+
{"version":3,"file":"paypal.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderPaypalAuthenticator","ctx","provider","scope","authorizeUrl","tokenUrl","userInfoUrl","buildIdentityWithTokenGrantResponse","input","userInfo","client","get","type","token","access_token","payload","id","user_id","attributeCandidates","name","email","data"],"sources":["../../../../../../src/core/identity/provider/authentication/presets/paypal.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../protocols/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../protocols/index.ts';\n\nexport class IdentityProviderPaypalAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n ctx.provider.scope = mergeOAuth2Scopes('openid profile email', ctx.provider.scope);\n ctx.provider.authorizeUrl = 'https://www.paypal.com/signin/authorize';\n ctx.provider.tokenUrl = 'https://api.paypal.com/v1/identity/openidconnect/tokenservice';\n ctx.provider.userInfoUrl = 'https://api.paypal.com/v1/oauth2/token/userinfo?schema=openid';\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const userInfo = await this.client.userInfo.get({\n type: 'Bearer',\n token: input.access_token,\n });\n\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: userInfo.user_id,\n attributeCandidates: {\n name: [\n userInfo.name,\n userInfo.user_id,\n ],\n email: [\n userInfo.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EACzDA,IAAIC,SAASC,QAAQL,kBAAkB,wBAAwBG,IAAIC,SAASC,KAAK;EACjFF,IAAIC,SAASE,eAAe;EAC5BH,IAAIC,SAASG,WAAW;EACxBJ,IAAIC,SAASI,cAAc;EAE3B,MAAML,GAAAA;CACV;CAEA,MAAgBM,oCAAoCC,OAA8D;EAC9G,MAAMC,WAAW,MAAM,KAAKC,OAAOD,SAASE,IAAI;GAC5CC,MAAM;GACNC,OAAOL,MAAMM;EACjB,CAAA;EAEA,MAAMC,UAAUlB,oBAAoBW,MAAMM,YAAY;EAEtD,OAAO;GACHE,IAAIP,SAASQ;GACbC,qBAAqB;IACjBC,MAAM,CACFV,SAASU,MACTV,SAASQ,OACZ;IACDG,OAAO,CACHX,SAASW,KACZ;GACL;GACAC,MAAMN;GACNb,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["EntityCredentialsInvalidError","template","ldap","BaseCredentialsAuthenticator","IdentityProviderLdapAuthenticator","provider","accountManager","client","ctx","clientFactory","create","url","tls","startTLS","startTls","baseDn","user","password","userNameAttribute","authenticate","name","bind","safeBind","success","safeUnbind","entity","findOneByName","identity","id","dn","attributeCandidates","extractCnFromDn","email","userMailAttribute","data","roles","findUserGroups","account","save","isDn","nameAttribute","resolveDn","userBaseDn","e","error","unbind","input","filter","userFilter","name_attribute","mail_attribute","display_name_attribute","userDisplayNameAttribute","EqualityFilter","attribute","value","OrFilter","filters","entities","search","scope","length","match","exec","trim","undefined","groupNameAttribute","memberAttribute","groupMemberAttribute","groupFilter","member_attribute","AndFilter","groupClass","groupMemberUserAttribute","groupBaseDn","attributeKey","names","push","Array","isArray","el"],"sources":["../../../../../../../src/core/identity/provider/authentication/protocols/ldap/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2024-2025.\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 { LdapIdentityProvider, User } from '@authup/core-kit';\nimport { EntityCredentialsInvalidError } from '@authup/errors';\nimport type { Result } from '@authup/kit';\nimport { template } from '@authup/kit';\nimport ldap from 'ldapjs';\nimport type { Filter } from 'ldapjs';\nimport { BaseCredentialsAuthenticator } from '../../../../../authentication/index.ts';\nimport type { ILdapClient } from '../../../../../ldap/index.ts';\nimport type { IIdentityProviderAccountManager } from '../../../account/index.ts';\nimport type { IdentityProviderIdentity } from '../../../types.ts';\nimport type { IdentityProviderLdapAuthenticatorContext } from './types.ts';\n\nexport class IdentityProviderLdapAuthenticator extends BaseCredentialsAuthenticator<User> {\n protected provider : LdapIdentityProvider;\n\n protected accountManager: IIdentityProviderAccountManager;\n\n protected client: ILdapClient;\n\n constructor(ctx: IdentityProviderLdapAuthenticatorContext) {\n super();\n\n this.accountManager = ctx.accountManager;\n this.provider = ctx.provider;\n this.client = ctx.clientFactory.create({\n url: ctx.provider.url,\n tls: ctx.provider.tls,\n startTLS: ctx.provider.startTls,\n baseDn: ctx.provider.baseDn,\n user: ctx.provider.user,\n password: ctx.provider.password,\n userNameAttribute: ctx.provider.userNameAttribute,\n });\n }\n\n async authenticate(name: string, password: string) : Promise<User> {\n let bind = await this.safeBind();\n if (!bind.success) {\n await this.safeUnbind();\n\n throw new EntityCredentialsInvalidError({ entity: 'user' });\n }\n\n const entity = await this.findOneByName(name);\n if (!entity) {\n await this.safeUnbind();\n throw new EntityCredentialsInvalidError({ entity: 'user' });\n }\n\n const identity : IdentityProviderIdentity = {\n id: entity.dn,\n attributeCandidates: {\n name: [\n entity[this.provider.userNameAttribute || 'cn'],\n this.extractCnFromDn(entity.dn),\n ],\n email: [\n entity[this.provider.userMailAttribute || 'mail'],\n ],\n },\n data: entity,\n provider: this.provider,\n };\n\n try {\n identity.roles = await this.findUserGroups(entity);\n } catch {\n // todo: log event\n }\n\n bind = await this.safeBind(identity.id, password);\n await this.safeUnbind();\n\n if (!bind.success) {\n throw new EntityCredentialsInvalidError({ entity: 'user' });\n }\n\n const account = await this.accountManager.save(identity);\n\n return account.user;\n }\n\n protected async bind(user?: string, password?: string) : Promise<void> {\n if (!user) {\n return this.client.bind();\n }\n\n if (!this.client.isDn(user)) {\n const nameAttribute = this.provider.userNameAttribute || 'cn';\n user = `${nameAttribute}=${user},${this.client.resolveDn(this.provider.userBaseDn, this.provider.baseDn)}`;\n }\n\n return this.client.bind(user, password);\n }\n\n protected async safeBind(user?: string, password?: string) : Promise<Result<null>> {\n try {\n await this.bind(user, password);\n\n return {\n success: true,\n data: null, \n };\n } catch (e) {\n return {\n success: false,\n error: e as Error, \n };\n }\n }\n\n protected async unbind() : Promise<void> {\n return this.client.unbind();\n }\n\n protected async safeUnbind() : Promise<Result<null>> {\n try {\n await this.unbind();\n\n return {\n success: true,\n data: null, \n };\n } catch (e) {\n return {\n success: false,\n error: e as Error, \n };\n }\n }\n\n protected async findOneByName(input: string) : Promise<Record<string, any> | null> {\n let filter : Filter | string;\n\n if (this.provider.userFilter) {\n filter = template(this.provider.userFilter, {\n input,\n name_attribute: this.provider.userNameAttribute || 'cn',\n mail_attribute: this.provider.userMailAttribute || 'mail',\n display_name_attribute: this.provider.userDisplayNameAttribute || 'cn',\n });\n } else if (this.provider.userNameAttribute) {\n filter = new ldap.EqualityFilter({\n attribute: this.provider.userNameAttribute,\n value: input,\n });\n } else {\n filter = new ldap.OrFilter({\n filters: [\n new ldap.EqualityFilter({\n attribute: 'cn',\n value: input,\n }),\n new ldap.EqualityFilter({\n attribute: 'sAMAccountName',\n value: input,\n }),\n ],\n });\n }\n\n const entities = await this.client.search({\n filter,\n scope: 'sub',\n }, this.client.resolveDn(this.provider.userBaseDn, this.provider.baseDn));\n\n if (entities.length === 0) {\n return null;\n }\n\n return entities[0];\n }\n\n protected extractCnFromDn(dn: string) : string | undefined {\n const match = /^cn=([^,]+)/i.exec(dn);\n return match ? match[1].trim() : undefined;\n }\n\n public async findUserGroups(user: Record<string, any>) : Promise<string[]> {\n const nameAttribute = this.provider.groupNameAttribute || 'cn';\n const memberAttribute = this.provider.groupMemberAttribute || 'member';\n\n let filter : Filter | string;\n if (this.provider.groupFilter) {\n filter = template(this.provider.groupFilter, {\n ...user,\n name_attribute: nameAttribute,\n member_attribute: memberAttribute,\n });\n } else {\n filter = new ldap.AndFilter({\n filters: [\n new ldap.EqualityFilter({\n attribute: 'objectClass',\n value: this.provider.groupClass || 'group',\n }),\n new ldap.EqualityFilter({\n attribute: memberAttribute,\n value: user[this.provider.groupMemberUserAttribute || 'dn'],\n }),\n ],\n });\n }\n\n const entities = await this.client.search({\n filter,\n scope: 'sub',\n }, this.client.resolveDn(this.provider.groupBaseDn, this.provider.baseDn));\n\n if (entities.length === 0) {\n return [];\n }\n\n const attributeKey = this.provider.groupNameAttribute || 'cn';\n const names : string[] = [];\n for (const entity of entities) {\n const attribute = entity[attributeKey];\n if (typeof attribute === 'undefined') {\n continue;\n }\n\n if (typeof attribute === 'string') {\n names.push(attribute);\n continue;\n }\n\n if (Array.isArray(attribute)) {\n names.push(...attribute.filter((el) => typeof el === 'string'));\n }\n }\n\n return names;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["EntityCredentialsInvalidError","template","ldap","BaseCredentialsAuthenticator","IdentityProviderLdapAuthenticator","provider","accountManager","client","ctx","clientFactory","create","url","tls","startTLS","startTls","baseDn","user","password","userNameAttribute","authenticate","name","bind","safeBind","success","safeUnbind","entity","findOneByName","identity","id","dn","attributeCandidates","extractCnFromDn","email","userMailAttribute","data","roles","findUserGroups","account","save","isDn","nameAttribute","resolveDn","userBaseDn","e","error","unbind","input","filter","userFilter","name_attribute","mail_attribute","display_name_attribute","userDisplayNameAttribute","EqualityFilter","attribute","value","OrFilter","filters","entities","search","scope","length","match","exec","trim","undefined","groupNameAttribute","memberAttribute","groupMemberAttribute","groupFilter","member_attribute","AndFilter","groupClass","groupMemberUserAttribute","groupBaseDn","attributeKey","names","push","Array","isArray","el"],"sources":["../../../../../../../src/core/identity/provider/authentication/protocols/ldap/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2024-2025.\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 { LdapIdentityProvider, User } from '@authup/core-kit';\nimport { EntityCredentialsInvalidError } from '@authup/errors';\nimport type { Result } from '@authup/kit';\nimport { template } from '@authup/kit';\nimport ldap from 'ldapjs';\nimport type { Filter } from 'ldapjs';\nimport { BaseCredentialsAuthenticator } from '../../../../../authentication/index.ts';\nimport type { ILdapClient } from '../../../../../ldap/index.ts';\nimport type { IIdentityProviderAccountManager } from '../../../account/index.ts';\nimport type { IdentityProviderIdentity } from '../../../types.ts';\nimport type { IdentityProviderLdapAuthenticatorContext } from './types.ts';\n\nexport class IdentityProviderLdapAuthenticator extends BaseCredentialsAuthenticator<User> {\n protected provider : LdapIdentityProvider;\n\n protected accountManager: IIdentityProviderAccountManager;\n\n protected client: ILdapClient;\n\n constructor(ctx: IdentityProviderLdapAuthenticatorContext) {\n super();\n\n this.accountManager = ctx.accountManager;\n this.provider = ctx.provider;\n this.client = ctx.clientFactory.create({\n url: ctx.provider.url,\n tls: ctx.provider.tls,\n startTLS: ctx.provider.startTls,\n baseDn: ctx.provider.baseDn,\n user: ctx.provider.user,\n password: ctx.provider.password,\n userNameAttribute: ctx.provider.userNameAttribute,\n });\n }\n\n async authenticate(name: string, password: string) : Promise<User> {\n let bind = await this.safeBind();\n if (!bind.success) {\n await this.safeUnbind();\n\n throw new EntityCredentialsInvalidError({ entity: 'user' });\n }\n\n const entity = await this.findOneByName(name);\n if (!entity) {\n await this.safeUnbind();\n throw new EntityCredentialsInvalidError({ entity: 'user' });\n }\n\n const identity : IdentityProviderIdentity = {\n id: entity.dn,\n attributeCandidates: {\n name: [\n entity[this.provider.userNameAttribute || 'cn'],\n this.extractCnFromDn(entity.dn),\n ],\n email: [\n entity[this.provider.userMailAttribute || 'mail'],\n ],\n },\n data: entity,\n provider: this.provider,\n };\n\n try {\n identity.roles = await this.findUserGroups(entity);\n } catch {\n // todo: log event\n }\n\n bind = await this.safeBind(identity.id, password);\n await this.safeUnbind();\n\n if (!bind.success) {\n throw new EntityCredentialsInvalidError({ entity: 'user' });\n }\n\n const account = await this.accountManager.save(identity);\n\n return account.user;\n }\n\n protected async bind(user?: string, password?: string) : Promise<void> {\n if (!user) {\n return this.client.bind();\n }\n\n if (!this.client.isDn(user)) {\n const nameAttribute = this.provider.userNameAttribute || 'cn';\n user = `${nameAttribute}=${user},${this.client.resolveDn(this.provider.userBaseDn, this.provider.baseDn)}`;\n }\n\n return this.client.bind(user, password);\n }\n\n protected async safeBind(user?: string, password?: string) : Promise<Result<null>> {\n try {\n await this.bind(user, password);\n\n return {\n success: true,\n data: null, \n };\n } catch (e) {\n return {\n success: false,\n error: e as Error, \n };\n }\n }\n\n protected async unbind() : Promise<void> {\n return this.client.unbind();\n }\n\n protected async safeUnbind() : Promise<Result<null>> {\n try {\n await this.unbind();\n\n return {\n success: true,\n data: null, \n };\n } catch (e) {\n return {\n success: false,\n error: e as Error, \n };\n }\n }\n\n protected async findOneByName(input: string) : Promise<Record<string, any> | null> {\n let filter : Filter | string;\n\n if (this.provider.userFilter) {\n filter = template(this.provider.userFilter, {\n input,\n name_attribute: this.provider.userNameAttribute || 'cn',\n mail_attribute: this.provider.userMailAttribute || 'mail',\n display_name_attribute: this.provider.userDisplayNameAttribute || 'cn',\n });\n } else if (this.provider.userNameAttribute) {\n filter = new ldap.EqualityFilter({\n attribute: this.provider.userNameAttribute,\n value: input,\n });\n } else {\n filter = new ldap.OrFilter({\n filters: [\n new ldap.EqualityFilter({\n attribute: 'cn',\n value: input,\n }),\n new ldap.EqualityFilter({\n attribute: 'sAMAccountName',\n value: input,\n }),\n ],\n });\n }\n\n const entities = await this.client.search({\n filter,\n scope: 'sub',\n }, this.client.resolveDn(this.provider.userBaseDn, this.provider.baseDn));\n\n if (entities.length === 0) {\n return null;\n }\n\n return entities[0];\n }\n\n protected extractCnFromDn(dn: string) : string | undefined {\n const match = /^cn=([^,]+)/i.exec(dn);\n return match ? match[1].trim() : undefined;\n }\n\n public async findUserGroups(user: Record<string, any>) : Promise<string[]> {\n const nameAttribute = this.provider.groupNameAttribute || 'cn';\n const memberAttribute = this.provider.groupMemberAttribute || 'member';\n\n let filter : Filter | string;\n if (this.provider.groupFilter) {\n filter = template(this.provider.groupFilter, {\n ...user,\n name_attribute: nameAttribute,\n member_attribute: memberAttribute,\n });\n } else {\n filter = new ldap.AndFilter({\n filters: [\n new ldap.EqualityFilter({\n attribute: 'objectClass',\n value: this.provider.groupClass || 'group',\n }),\n new ldap.EqualityFilter({\n attribute: memberAttribute,\n value: user[this.provider.groupMemberUserAttribute || 'dn'],\n }),\n ],\n });\n }\n\n const entities = await this.client.search({\n filter,\n scope: 'sub',\n }, this.client.resolveDn(this.provider.groupBaseDn, this.provider.baseDn));\n\n if (entities.length === 0) {\n return [];\n }\n\n const attributeKey = this.provider.groupNameAttribute || 'cn';\n const names : string[] = [];\n for (const entity of entities) {\n const attribute = entity[attributeKey];\n if (typeof attribute === 'undefined') {\n continue;\n }\n\n if (typeof attribute === 'string') {\n names.push(attribute);\n continue;\n }\n\n if (Array.isArray(attribute)) {\n names.push(...attribute.filter((el) => typeof el === 'string'));\n }\n }\n\n return names;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["buildIdentityProviderAuthorizeCallbackPath","ValidationError","extractTokenPayload","OAuth2Client","IdentityProviderOAuth2Authenticator","client","options","accountManager","provider","ctx","clientId","clientSecret","redirectUri","baseURL","id","scope","undefined","authorizationEndpoint","authorizeUrl","tokenEndpoint","tokenUrl","userinfoEndpoint","userInfoUrl","buildRedirectURL","parameters","authorize","buildURL","authenticate","params","token","createWithAuthorizationCode","identity","buildIdentityWithTokenGrantResponse","account","save","user","safeAuthenticate","data","success","e","error","input","payload","access_token","sub","attributeCandidates","name","email"],"sources":["../../../../../../../src/core/identity/provider/authentication/protocols/oauth2/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { OAuth2IdentityProvider, OpenIDIdentityProvider, User } from '@authup/core-kit';\nimport { buildIdentityProviderAuthorizeCallbackPath } from '@authup/core-kit';\nimport { ValidationError } from '@authup/errors';\nimport type { Result } from '@authup/kit';\nimport { extractTokenPayload } from '@authup/server-kit';\nimport type { AuthorizeParameters, TokenGrantResponse } from '@hapic/oauth2';\nimport { OAuth2Client } from '@hapic/oauth2';\nimport type { IIdentityProviderAccountManager } from '../../../account/index.ts';\nimport type { IdentityProviderIdentity } from '../../../types.ts';\nimport type {\n IOAuth2Authenticator,\n IdentityProviderOAuth2AuthenticatorContext,\n IdentityProviderOAuth2AuthenticatorOptions,\n OAuth2AuthorizationCodeGrantPayload,\n} from './types.ts';\n\nexport class IdentityProviderOAuth2Authenticator implements IOAuth2Authenticator<User> {\n protected client : OAuth2Client;\n\n protected options : IdentityProviderOAuth2AuthenticatorOptions;\n\n protected accountManager: IIdentityProviderAccountManager;\n\n protected provider : OAuth2IdentityProvider | OpenIDIdentityProvider;\n\n //----------------------------------------------------------------------\n\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n this.options = ctx.options;\n this.accountManager = ctx.accountManager;\n this.provider = ctx.provider;\n\n this.client = new OAuth2Client({\n options: {\n clientId: ctx.provider.clientId,\n clientSecret: ctx.provider.clientSecret,\n redirectUri: `${ctx.options.baseURL}${buildIdentityProviderAuthorizeCallbackPath(ctx.provider.id)}`,\n scope: ctx.provider.scope || undefined,\n authorizationEndpoint: ctx.provider.authorizeUrl,\n tokenEndpoint: ctx.provider.tokenUrl,\n userinfoEndpoint: ctx.provider.userInfoUrl || undefined,\n },\n });\n }\n\n //----------------------------------------------------------------------\n\n buildRedirectURL(parameters: Partial<AuthorizeParameters> = {}) : string {\n try {\n return this.client.authorize.buildURL(parameters);\n } catch {\n throw new ValidationError(\n 'The identity provider is misconfigured and has an invalid or missing authorize URL.',\n );\n }\n }\n\n //----------------------------------------------------------------------\n\n async authenticate(params: OAuth2AuthorizationCodeGrantPayload): Promise<User> {\n const token = await this.client.token.createWithAuthorizationCode(params);\n\n const identity = await this.buildIdentityWithTokenGrantResponse(token);\n if (this.options.clientId) {\n identity.clientId = this.options.clientId;\n }\n\n const account = await this.accountManager.save(identity);\n\n return account.user;\n }\n\n async safeAuthenticate(params: OAuth2AuthorizationCodeGrantPayload): Promise<Result<User>> {\n try {\n const data = await this.authenticate(params);\n return {\n success: true,\n data, \n };\n } catch (e) {\n return {\n success: false,\n error: e as Error, \n };\n }\n }\n\n //----------------------------------------------------------------------\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse) : Promise<IdentityProviderIdentity> {\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: payload.sub!,\n attributeCandidates: {\n name: [\n payload.sub,\n ],\n email: [\n payload.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAuBA,IAAaI,sCAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAIV,YAAYC,KAAiD;EACzD,KAAKH,UAAUG,IAAIH;EACnB,KAAKC,iBAAiBE,IAAIF;EAC1B,KAAKC,WAAWC,IAAID;EAEpB,KAAKH,SAAS,IAAIF,aAAa,EAC3BG,SAAS;GACLI,UAAUD,IAAID,SAASE;GACvBC,cAAcF,IAAID,SAASG;GAC3BC,aAAa,GAAGH,IAAIH,QAAQO,UAAUb,2CAA2CS,IAAID,SAASM,EAAE;GAChGC,OAAON,IAAID,SAASO,SAASC,KAAAA;GAC7BC,uBAAuBR,IAAID,SAASU;GACpCC,eAAeV,IAAID,SAASY;GAC5BC,kBAAkBZ,IAAID,SAASc,eAAeN,KAAAA;EAClD,EACJ,CAAA;CACJ;CAIAO,iBAAiBC,aAA2C,CAAC,GAAY;EACrE,IAAI;GACA,OAAO,KAAKnB,OAAOoB,UAAUC,SAASF,UAAAA;EAC1C,QAAQ;GACJ,MAAM,IAAIvB,gBACN,qFAAA;EAER;CACJ;CAIA,MAAM0B,aAAaC,QAA4D;EAC3E,MAAMC,QAAQ,MAAM,KAAKxB,OAAOwB,MAAMC,4BAA4BF,MAAAA;EAElE,MAAMG,WAAW,MAAM,KAAKC,oCAAoCH,KAAAA;EAChE,IAAI,KAAKvB,QAAQI,UACbqB,SAASrB,WAAW,KAAKJ,QAAQI;EAKrC,QAAOuB,MAFe,KAAK1B,eAAe2B,KAAKH,QAAAA,EAAAA,CAEhCI;CACnB;CAEA,MAAMC,iBAAiBR,QAAoE;EACvF,IAAI;GAEA,OAAO;IACHU,SAAS;IACTD,MAAAA,MAHe,KAAKV,aAAaC,MAAAA;GAIrC;EACJ,SAASW,GAAG;GACR,OAAO;IACHD,SAAS;IACTE,OAAOD;GACX;EACJ;CACJ;CAIA,MAAgBP,oCAAoCS,OAA+D;EAC/G,MAAMC,UAAUxC,oBAAoBuC,MAAME,YAAY;EAEtD,OAAO;GACH7B,IAAI4B,QAAQE;GACZC,qBAAqB;IACjBC,MAAM,CACFJ,QAAQE,
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["buildIdentityProviderAuthorizeCallbackPath","ValidationError","extractTokenPayload","OAuth2Client","IdentityProviderOAuth2Authenticator","client","options","accountManager","provider","ctx","clientId","clientSecret","redirectUri","baseURL","id","scope","undefined","authorizationEndpoint","authorizeUrl","tokenEndpoint","tokenUrl","userinfoEndpoint","userInfoUrl","buildRedirectURL","parameters","authorize","buildURL","authenticate","params","token","createWithAuthorizationCode","identity","buildIdentityWithTokenGrantResponse","account","save","user","safeAuthenticate","data","success","e","error","input","payload","access_token","sub","attributeCandidates","name","email"],"sources":["../../../../../../../src/core/identity/provider/authentication/protocols/oauth2/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2023.\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 { OAuth2IdentityProvider, OpenIDIdentityProvider, User } from '@authup/core-kit';\nimport { buildIdentityProviderAuthorizeCallbackPath } from '@authup/core-kit';\nimport { ValidationError } from '@authup/errors';\nimport type { Result } from '@authup/kit';\nimport { extractTokenPayload } from '@authup/server-kit';\nimport type { AuthorizeParameters, TokenGrantResponse } from '@hapic/oauth2';\nimport { OAuth2Client } from '@hapic/oauth2';\nimport type { IIdentityProviderAccountManager } from '../../../account/index.ts';\nimport type { IdentityProviderIdentity } from '../../../types.ts';\nimport type {\n IOAuth2Authenticator,\n IdentityProviderOAuth2AuthenticatorContext,\n IdentityProviderOAuth2AuthenticatorOptions,\n OAuth2AuthorizationCodeGrantPayload,\n} from './types.ts';\n\nexport class IdentityProviderOAuth2Authenticator implements IOAuth2Authenticator<User> {\n protected client : OAuth2Client;\n\n protected options : IdentityProviderOAuth2AuthenticatorOptions;\n\n protected accountManager: IIdentityProviderAccountManager;\n\n protected provider : OAuth2IdentityProvider | OpenIDIdentityProvider;\n\n //----------------------------------------------------------------------\n\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n this.options = ctx.options;\n this.accountManager = ctx.accountManager;\n this.provider = ctx.provider;\n\n this.client = new OAuth2Client({\n options: {\n clientId: ctx.provider.clientId,\n clientSecret: ctx.provider.clientSecret,\n redirectUri: `${ctx.options.baseURL}${buildIdentityProviderAuthorizeCallbackPath(ctx.provider.id)}`,\n scope: ctx.provider.scope || undefined,\n authorizationEndpoint: ctx.provider.authorizeUrl,\n tokenEndpoint: ctx.provider.tokenUrl,\n userinfoEndpoint: ctx.provider.userInfoUrl || undefined,\n },\n });\n }\n\n //----------------------------------------------------------------------\n\n buildRedirectURL(parameters: Partial<AuthorizeParameters> = {}) : string {\n try {\n return this.client.authorize.buildURL(parameters);\n } catch {\n throw new ValidationError(\n 'The identity provider is misconfigured and has an invalid or missing authorize URL.',\n );\n }\n }\n\n //----------------------------------------------------------------------\n\n async authenticate(params: OAuth2AuthorizationCodeGrantPayload): Promise<User> {\n const token = await this.client.token.createWithAuthorizationCode(params);\n\n const identity = await this.buildIdentityWithTokenGrantResponse(token);\n if (this.options.clientId) {\n identity.clientId = this.options.clientId;\n }\n\n const account = await this.accountManager.save(identity);\n\n return account.user;\n }\n\n async safeAuthenticate(params: OAuth2AuthorizationCodeGrantPayload): Promise<Result<User>> {\n try {\n const data = await this.authenticate(params);\n return {\n success: true,\n data, \n };\n } catch (e) {\n return {\n success: false,\n error: e as Error, \n };\n }\n }\n\n //----------------------------------------------------------------------\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse) : Promise<IdentityProviderIdentity> {\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: payload.sub!,\n attributeCandidates: {\n name: [\n payload.sub,\n ],\n email: [\n payload.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAuBA,IAAaI,sCAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAIV,YAAYC,KAAiD;EACzD,KAAKH,UAAUG,IAAIH;EACnB,KAAKC,iBAAiBE,IAAIF;EAC1B,KAAKC,WAAWC,IAAID;EAEpB,KAAKH,SAAS,IAAIF,aAAa,EAC3BG,SAAS;GACLI,UAAUD,IAAID,SAASE;GACvBC,cAAcF,IAAID,SAASG;GAC3BC,aAAa,GAAGH,IAAIH,QAAQO,UAAUb,2CAA2CS,IAAID,SAASM,EAAE;GAChGC,OAAON,IAAID,SAASO,SAASC,KAAAA;GAC7BC,uBAAuBR,IAAID,SAASU;GACpCC,eAAeV,IAAID,SAASY;GAC5BC,kBAAkBZ,IAAID,SAASc,eAAeN,KAAAA;EAClD,EACJ,CAAA;CACJ;CAIAO,iBAAiBC,aAA2C,CAAC,GAAY;EACrE,IAAI;GACA,OAAO,KAAKnB,OAAOoB,UAAUC,SAASF,UAAAA;EAC1C,QAAQ;GACJ,MAAM,IAAIvB,gBACN,qFAAA;EAER;CACJ;CAIA,MAAM0B,aAAaC,QAA4D;EAC3E,MAAMC,QAAQ,MAAM,KAAKxB,OAAOwB,MAAMC,4BAA4BF,MAAAA;EAElE,MAAMG,WAAW,MAAM,KAAKC,oCAAoCH,KAAAA;EAChE,IAAI,KAAKvB,QAAQI,UACbqB,SAASrB,WAAW,KAAKJ,QAAQI;EAKrC,QAAOuB,MAFe,KAAK1B,eAAe2B,KAAKH,QAAAA,EAAAA,CAEhCI;CACnB;CAEA,MAAMC,iBAAiBR,QAAoE;EACvF,IAAI;GAEA,OAAO;IACHU,SAAS;IACTD,MAAAA,MAHe,KAAKV,aAAaC,MAAAA;GAIrC;EACJ,SAASW,GAAG;GACR,OAAO;IACHD,SAAS;IACTE,OAAOD;GACX;EACJ;CACJ;CAIA,MAAgBP,oCAAoCS,OAA+D;EAC/G,MAAMC,UAAUxC,oBAAoBuC,MAAME,YAAY;EAEtD,OAAO;GACH7B,IAAI4B,QAAQE;GACZC,qBAAqB;IACjBC,MAAM,CACFJ,QAAQE,GACX;IACDG,OAAO,CACHL,QAAQK,KACX;GACL;GACAV,MAAMK;GACNlC,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderOpenIDAuthenticator","ctx","provider","scope","buildIdentityWithTokenGrantResponse","input","payload","access_token","id","sub","attributeCandidates","name","preferred_username","nickname","email","data"],"sources":["../../../../../../../src/core/identity/provider/authentication/protocols/open-id/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2025.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../oauth2/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../oauth2/index.ts';\n\nexport class IdentityProviderOpenIDAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n // OIDC requires the openid scope (Core §3.1.2.1)\n ctx.provider.scope = mergeOAuth2Scopes(\n 'openid',\n ctx.provider.scope || 'openid profile email',\n );\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: payload.sub!,\n attributeCandidates: {\n name: [\n payload.preferred_username,\n payload.nickname,\n payload.sub,\n ],\n email: [\n payload.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EAEzDA,IAAIC,SAASC,QAAQL,kBACjB,UACAG,IAAIC,SAASC,SAAS,sBAAA;EAG1B,MAAMF,GAAAA;CACV;CAEA,MAAgBG,oCAAoCC,OAA8D;EAC9G,MAAMC,UAAUT,oBAAoBQ,MAAME,YAAY;EAEtD,OAAO;GACHC,IAAIF,QAAQG;GACZC,qBAAqB;IACjBC,MAAM;KACFL,QAAQM;KACRN,QAAQO;KACRP,QAAQG
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["extractTokenPayload","mergeOAuth2Scopes","IdentityProviderOAuth2Authenticator","IdentityProviderOpenIDAuthenticator","ctx","provider","scope","buildIdentityWithTokenGrantResponse","input","payload","access_token","id","sub","attributeCandidates","name","preferred_username","nickname","email","data"],"sources":["../../../../../../../src/core/identity/provider/authentication/protocols/open-id/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2025.\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 { extractTokenPayload } from '@authup/server-kit';\nimport { mergeOAuth2Scopes } from '@authup/specs';\nimport type { TokenGrantResponse } from '@hapic/oauth2';\nimport type { IdentityProviderIdentity } from '../../../types.ts';\nimport type { IdentityProviderOAuth2AuthenticatorContext } from '../oauth2/index.ts';\nimport { IdentityProviderOAuth2Authenticator } from '../oauth2/index.ts';\n\nexport class IdentityProviderOpenIDAuthenticator extends IdentityProviderOAuth2Authenticator {\n constructor(ctx: IdentityProviderOAuth2AuthenticatorContext) {\n // OIDC requires the openid scope (Core §3.1.2.1)\n ctx.provider.scope = mergeOAuth2Scopes(\n 'openid',\n ctx.provider.scope || 'openid profile email',\n );\n\n super(ctx);\n }\n\n protected async buildIdentityWithTokenGrantResponse(input: TokenGrantResponse): Promise<IdentityProviderIdentity> {\n const payload = extractTokenPayload(input.access_token);\n\n return {\n id: payload.sub!,\n attributeCandidates: {\n name: [\n payload.preferred_username,\n payload.nickname,\n payload.sub,\n ],\n email: [\n payload.email,\n ],\n },\n data: payload,\n provider: this.provider,\n };\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAaG,sCAAb,cAAyDD,oCAAAA;CACrD,YAAYE,KAAiD;EAEzDA,IAAIC,SAASC,QAAQL,kBACjB,UACAG,IAAIC,SAASC,SAAS,sBAAA;EAG1B,MAAMF,GAAAA;CACV;CAEA,MAAgBG,oCAAoCC,OAA8D;EAC9G,MAAMC,UAAUT,oBAAoBQ,MAAME,YAAY;EAEtD,OAAO;GACHC,IAAIF,QAAQG;GACZC,qBAAqB;IACjBC,MAAM;KACFL,QAAQM;KACRN,QAAQO;KACRP,QAAQG;IACX;IACDK,OAAO,CACHR,QAAQQ,KACX;GACL;GACAC,MAAMT;GACNJ,UAAU,KAAKA;EACnB;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","names":["IdentityProviderIdentityOperation"],"sources":["../../../../src/core/identity/provider/constants.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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\nexport enum IdentityProviderIdentityOperation {\n CREATE = 'create',\n UPDATE = 'update',\n}\n"],"mappings":";;;;AAOA,IAAO,oCAAKA,uBAAAA,mCAAAA;;;
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":["IdentityProviderIdentityOperation"],"sources":["../../../../src/core/identity/provider/constants.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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\nexport enum IdentityProviderIdentityOperation {\n CREATE = 'create',\n UPDATE = 'update',\n}\n"],"mappings":";;;;AAOA,IAAO,oCAAKA,uBAAAA,mCAAAA;;;CAAAA,OAAAA;AAGX,EAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.mjs","names":["IdentityProviderMappingSyncMode","getJWTClaimByPattern","IdentityProviderIdentityOperation","IdentityProviderMapperOperation","IdentityProviderAccountBaseMapper","resolve","identity","mapping","operation","synchronizationMode","ONCE","UPDATE","NONE","name","value","CREATE","data","valueIsRegex","length","DELETE"],"sources":["../../../../../src/core/identity/provider/mapper/base.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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 { IdentityProviderBaseMapping } from '@authup/core-kit';\nimport { IdentityProviderMappingSyncMode } from '@authup/core-kit';\nimport { getJWTClaimByPattern } from '@authup/specs';\nimport { IdentityProviderIdentityOperation } from '../constants.ts';\nimport type { IdentityProviderIdentity } from '../types.ts';\nimport { IdentityProviderMapperOperation } from './constants.ts';\nimport type { IIdentityProviderMapper, IdentityProviderMapperElement } from './types.ts';\n\nexport abstract class IdentityProviderAccountBaseMapper implements IIdentityProviderMapper {\n protected resolve(\n identity: IdentityProviderIdentity,\n mapping: IdentityProviderBaseMapping,\n ) : [IdentityProviderMapperOperation, unknown] | [IdentityProviderMapperOperation] {\n let operation : IdentityProviderMapperOperation;\n if (\n mapping.synchronizationMode === IdentityProviderMappingSyncMode.ONCE &&\n identity.operation === IdentityProviderIdentityOperation.UPDATE\n ) {\n operation = IdentityProviderMapperOperation.NONE;\n\n return [operation];\n }\n\n if (!mapping.name || !mapping.value) {\n operation = IdentityProviderMapperOperation.CREATE;\n\n return [operation];\n }\n\n const value = getJWTClaimByPattern(\n identity.data,\n mapping.name,\n mapping.value,\n mapping.valueIsRegex,\n );\n\n if (value.length === 0) {\n operation = IdentityProviderMapperOperation.DELETE;\n } else {\n operation = IdentityProviderMapperOperation.CREATE;\n }\n\n return [operation, value];\n }\n\n abstract execute(\n identity: IdentityProviderIdentity\n ): Promise<IdentityProviderMapperElement[]>;\n}\n"],"mappings":";;;;;;;;AAeA,IAAsBI,oCAAtB,MAAsBA;CACRC,QACNC,UACAC,SAC+E;EAC/E,IAAIC;EACJ,IACID,QAAQE,wBAAwBT,gCAAgCU,QAChEJ,SAASE,cAAcN,kCAAkCS,QAC3D;GACEH,YAAYL,gCAAgCS;GAE5C,OAAO,CAACJ,
|
|
1
|
+
{"version":3,"file":"base.mjs","names":["IdentityProviderMappingSyncMode","getJWTClaimByPattern","IdentityProviderIdentityOperation","IdentityProviderMapperOperation","IdentityProviderAccountBaseMapper","resolve","identity","mapping","operation","synchronizationMode","ONCE","UPDATE","NONE","name","value","CREATE","data","valueIsRegex","length","DELETE"],"sources":["../../../../../src/core/identity/provider/mapper/base.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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 { IdentityProviderBaseMapping } from '@authup/core-kit';\nimport { IdentityProviderMappingSyncMode } from '@authup/core-kit';\nimport { getJWTClaimByPattern } from '@authup/specs';\nimport { IdentityProviderIdentityOperation } from '../constants.ts';\nimport type { IdentityProviderIdentity } from '../types.ts';\nimport { IdentityProviderMapperOperation } from './constants.ts';\nimport type { IIdentityProviderMapper, IdentityProviderMapperElement } from './types.ts';\n\nexport abstract class IdentityProviderAccountBaseMapper implements IIdentityProviderMapper {\n protected resolve(\n identity: IdentityProviderIdentity,\n mapping: IdentityProviderBaseMapping,\n ) : [IdentityProviderMapperOperation, unknown] | [IdentityProviderMapperOperation] {\n let operation : IdentityProviderMapperOperation;\n if (\n mapping.synchronizationMode === IdentityProviderMappingSyncMode.ONCE &&\n identity.operation === IdentityProviderIdentityOperation.UPDATE\n ) {\n operation = IdentityProviderMapperOperation.NONE;\n\n return [operation];\n }\n\n if (!mapping.name || !mapping.value) {\n operation = IdentityProviderMapperOperation.CREATE;\n\n return [operation];\n }\n\n const value = getJWTClaimByPattern(\n identity.data,\n mapping.name,\n mapping.value,\n mapping.valueIsRegex,\n );\n\n if (value.length === 0) {\n operation = IdentityProviderMapperOperation.DELETE;\n } else {\n operation = IdentityProviderMapperOperation.CREATE;\n }\n\n return [operation, value];\n }\n\n abstract execute(\n identity: IdentityProviderIdentity\n ): Promise<IdentityProviderMapperElement[]>;\n}\n"],"mappings":";;;;;;;;AAeA,IAAsBI,oCAAtB,MAAsBA;CACRC,QACNC,UACAC,SAC+E;EAC/E,IAAIC;EACJ,IACID,QAAQE,wBAAwBT,gCAAgCU,QAChEJ,SAASE,cAAcN,kCAAkCS,QAC3D;GACEH,YAAYL,gCAAgCS;GAE5C,OAAO,CAACJ,SAAU;EACtB;EAEA,IAAI,CAACD,QAAQM,QAAQ,CAACN,QAAQO,OAAO;GACjCN,YAAYL,gCAAgCY;GAE5C,OAAO,CAACP,SAAU;EACtB;EAEA,MAAMM,QAAQb,qBACVK,SAASU,MACTT,QAAQM,MACRN,QAAQO,OACRP,QAAQU,YAAY;EAGxB,IAAIH,MAAMI,WAAW,GACjBV,YAAYL,gCAAgCgB;OAE5CX,YAAYL,gCAAgCY;EAGhD,OAAO,CAACP,WAAWM,KAAM;CAC7B;AAKJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","names":["IdentityProviderMapperOperation"],"sources":["../../../../../src/core/identity/provider/mapper/constants.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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\nexport enum IdentityProviderMapperOperation {\n NONE = 'none',\n DELETE = 'delete',\n CREATE = 'create',\n}\n"],"mappings":";;;;AAOA,IAAO,kCAAKA,uBAAAA,iCAAAA;;;;
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":["IdentityProviderMapperOperation"],"sources":["../../../../../src/core/identity/provider/mapper/constants.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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\nexport enum IdentityProviderMapperOperation {\n NONE = 'none',\n DELETE = 'delete',\n CREATE = 'create',\n}\n"],"mappings":";;;;AAOA,IAAO,kCAAKA,uBAAAA,iCAAAA;;;;CAAAA,OAAAA;AAIX,EAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["EventName","EventRefType","EventScope","IdentityType","UserValidator","createNanoID","EntityNotFoundError","ValidationError","RegistrationDisabledError","randomBytes","Container","UserCredentialsService","MailTemplateName","RegistrationService","options","mailClient","mailTemplateRenderer","repository","realmRepository","eventService","ctx","register","data","context","registrationEnabled","validator","mount","pathsToInclude","passwordMinLength","validated","run","group","validateJoinColumns","emailVerificationEnabled","active","activateHash","toString","entity","create","credentialsService","password","protect","realm","resolve","realmId","id","save","activateUrl","publicUrl","replace","undefined","mail","render","template","REGISTRATION_ACTIVATION","params","code","url","locale","send","to","email","remove","record","scope","IDENTITY","name","REGISTER","refType","USER","refId","actorType","actorId","actorName","activate","findOneBy","token","merged","merge","ACCOUNT_ACTIVATED"],"sources":["../../../../src/core/identity/registration/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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 EventName,\n EventRefType,\n EventScope,\n IdentityType,\n UserValidator,\n} from '@authup/core-kit';\nimport { createNanoID } from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport { RegistrationDisabledError } from './error.ts';\nimport { randomBytes } from 'node:crypto';\nimport { Container } from 'validup';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type {\n IRegistrationService,\n RegistrationResult,\n RegistrationServiceContext,\n RegistrationServiceOptions,\n} from './types.ts';\nimport type { IMailClient, IMailTemplateRenderer } from '../../mail/types.ts';\nimport { MailTemplateName } from '../../mail/index.ts';\nimport type { IEventService, IRealmRepository, IUserRepository } from '../../entities/index.ts';\nimport type { IdentityWorkflowContext } from '../types.ts';\n\nexport class RegistrationService implements IRegistrationService {\n protected options: RegistrationServiceOptions;\n\n protected mailClient: IMailClient;\n\n protected mailTemplateRenderer: IMailTemplateRenderer;\n\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected eventService?: IEventService;\n\n constructor(ctx: RegistrationServiceContext) {\n this.options = ctx.options;\n this.mailClient = ctx.mailClient;\n this.mailTemplateRenderer = ctx.mailTemplateRenderer;\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.eventService = ctx.eventService;\n }\n\n async register(data: Record<string, any>, context?: IdentityWorkflowContext): Promise<RegistrationResult> {\n if (!this.options.registrationEnabled) {\n throw new RegistrationDisabledError();\n }\n\n const validator = new Container({});\n validator.mount(new UserValidator({\n pathsToInclude: ['email', 'name', 'password', 'realmId'],\n passwordMinLength: this.options.passwordMinLength,\n }));\n const validated = await validator.run(data, { group: 'create' });\n\n await this.repository.validateJoinColumns(validated);\n\n if (this.options.emailVerificationEnabled) {\n validated.active = false;\n validated.activateHash = randomBytes(32).toString('hex');\n } else {\n validated.active = true;\n }\n\n const entity = this.repository.create(validated);\n\n const credentialsService = new UserCredentialsService();\n entity.password = entity.password || createNanoID(64);\n entity.password = await credentialsService.protect(entity.password);\n\n const realm = await this.realmRepository.resolve(entity.realmId, true);\n entity.realmId = realm.id;\n\n await this.repository.save(entity);\n\n if (this.options.emailVerificationEnabled) {\n try {\n const activateUrl = this.options.publicUrl ?\n `${this.options.publicUrl.replace(/\\/+$/, '')}/activate?token=${entity.activateHash}` :\n undefined;\n\n const mail = await this.mailTemplateRenderer.render({\n template: MailTemplateName.REGISTRATION_ACTIVATION,\n params: { code: entity.activateHash!, url: activateUrl },\n locale: context?.locale,\n });\n\n await this.mailClient.send({\n to: entity.email,\n ...mail,\n });\n } catch {\n await this.repository.remove(entity);\n throw new ValidationError('Registration failed. Could not send activation email.');\n }\n }\n\n await this.eventService?.record({\n scope: EventScope.IDENTITY,\n name: EventName.REGISTER,\n refType: EventRefType.USER,\n refId: entity.id,\n actorType: IdentityType.USER,\n actorId: entity.id,\n actorName: entity.name,\n realmId: entity.realmId,\n });\n\n return { active: entity.active };\n }\n\n async activate(data: { token: string }): Promise<void> {\n const entity = await this.repository.findOneBy({ activateHash: data.token });\n\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const merged = this.repository.merge(entity, {\n active: true,\n activateHash: null,\n });\n\n await this.repository.save(merged);\n\n await this.eventService?.record({\n scope: EventScope.IDENTITY,\n name: EventName.ACCOUNT_ACTIVATED,\n refType: EventRefType.USER,\n refId: merged.id,\n actorType: IdentityType.USER,\n actorId: merged.id,\n actorName: merged.name,\n realmId: merged.realmId,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AA+BA,IAAaa,sBAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAiC;EACzC,KAAKN,UAAUM,IAAIN;EACnB,KAAKC,aAAaK,IAAIL;EACtB,KAAKC,uBAAuBI,IAAIJ;EAChC,KAAKC,aAAaG,IAAIH;EACtB,KAAKC,kBAAkBE,IAAIF;EAC3B,KAAKC,eAAeC,IAAID;CAC5B;CAEA,MAAME,SAASC,MAA2BC,SAAgE;EACtG,IAAI,CAAC,KAAKT,QAAQU,qBACd,MAAM,IAAIhB,0BAAAA;EAGd,MAAMiB,YAAY,IAAIf,UAAU,CAAC,CAAA;EACjCe,UAAUC,MAAM,IAAItB,cAAc;GAC9BuB,gBAAgB;IAAC;IAAS;IAAQ;IAAY
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["EventName","EventRefType","EventScope","IdentityType","UserValidator","createNanoID","EntityNotFoundError","ValidationError","RegistrationDisabledError","randomBytes","Container","UserCredentialsService","MailTemplateName","RegistrationService","options","mailClient","mailTemplateRenderer","repository","realmRepository","eventService","ctx","register","data","context","registrationEnabled","validator","mount","pathsToInclude","passwordMinLength","validated","run","group","validateJoinColumns","emailVerificationEnabled","active","activateHash","toString","entity","create","credentialsService","password","protect","realm","resolve","realmId","id","save","activateUrl","publicUrl","replace","undefined","mail","render","template","REGISTRATION_ACTIVATION","params","code","url","locale","send","to","email","remove","record","scope","IDENTITY","name","REGISTER","refType","USER","refId","actorType","actorId","actorName","activate","findOneBy","token","merged","merge","ACCOUNT_ACTIVATED"],"sources":["../../../../src/core/identity/registration/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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 EventName,\n EventRefType,\n EventScope,\n IdentityType,\n UserValidator,\n} from '@authup/core-kit';\nimport { createNanoID } from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport { RegistrationDisabledError } from './error.ts';\nimport { randomBytes } from 'node:crypto';\nimport { Container } from 'validup';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type {\n IRegistrationService,\n RegistrationResult,\n RegistrationServiceContext,\n RegistrationServiceOptions,\n} from './types.ts';\nimport type { IMailClient, IMailTemplateRenderer } from '../../mail/types.ts';\nimport { MailTemplateName } from '../../mail/index.ts';\nimport type { IEventService, IRealmRepository, IUserRepository } from '../../entities/index.ts';\nimport type { IdentityWorkflowContext } from '../types.ts';\n\nexport class RegistrationService implements IRegistrationService {\n protected options: RegistrationServiceOptions;\n\n protected mailClient: IMailClient;\n\n protected mailTemplateRenderer: IMailTemplateRenderer;\n\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected eventService?: IEventService;\n\n constructor(ctx: RegistrationServiceContext) {\n this.options = ctx.options;\n this.mailClient = ctx.mailClient;\n this.mailTemplateRenderer = ctx.mailTemplateRenderer;\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.eventService = ctx.eventService;\n }\n\n async register(data: Record<string, any>, context?: IdentityWorkflowContext): Promise<RegistrationResult> {\n if (!this.options.registrationEnabled) {\n throw new RegistrationDisabledError();\n }\n\n const validator = new Container({});\n validator.mount(new UserValidator({\n pathsToInclude: ['email', 'name', 'password', 'realmId'],\n passwordMinLength: this.options.passwordMinLength,\n }));\n const validated = await validator.run(data, { group: 'create' });\n\n await this.repository.validateJoinColumns(validated);\n\n if (this.options.emailVerificationEnabled) {\n validated.active = false;\n validated.activateHash = randomBytes(32).toString('hex');\n } else {\n validated.active = true;\n }\n\n const entity = this.repository.create(validated);\n\n const credentialsService = new UserCredentialsService();\n entity.password = entity.password || createNanoID(64);\n entity.password = await credentialsService.protect(entity.password);\n\n const realm = await this.realmRepository.resolve(entity.realmId, true);\n entity.realmId = realm.id;\n\n await this.repository.save(entity);\n\n if (this.options.emailVerificationEnabled) {\n try {\n const activateUrl = this.options.publicUrl ?\n `${this.options.publicUrl.replace(/\\/+$/, '')}/activate?token=${entity.activateHash}` :\n undefined;\n\n const mail = await this.mailTemplateRenderer.render({\n template: MailTemplateName.REGISTRATION_ACTIVATION,\n params: { code: entity.activateHash!, url: activateUrl },\n locale: context?.locale,\n });\n\n await this.mailClient.send({\n to: entity.email,\n ...mail,\n });\n } catch {\n await this.repository.remove(entity);\n throw new ValidationError('Registration failed. Could not send activation email.');\n }\n }\n\n await this.eventService?.record({\n scope: EventScope.IDENTITY,\n name: EventName.REGISTER,\n refType: EventRefType.USER,\n refId: entity.id,\n actorType: IdentityType.USER,\n actorId: entity.id,\n actorName: entity.name,\n realmId: entity.realmId,\n });\n\n return { active: entity.active };\n }\n\n async activate(data: { token: string }): Promise<void> {\n const entity = await this.repository.findOneBy({ activateHash: data.token });\n\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const merged = this.repository.merge(entity, {\n active: true,\n activateHash: null,\n });\n\n await this.repository.save(merged);\n\n await this.eventService?.record({\n scope: EventScope.IDENTITY,\n name: EventName.ACCOUNT_ACTIVATED,\n refType: EventRefType.USER,\n refId: merged.id,\n actorType: IdentityType.USER,\n actorId: merged.id,\n actorName: merged.name,\n realmId: merged.realmId,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisioner.mjs","names":["JWKUse","KeyProvisioner","keyStore","logger","ctx","ensureForRealm","realm","uses","SIGNATURE","ENCRYPTION","use","resolveOrCreate","id","e","warn","Error","message","String"],"sources":["../../../src/core/key/provisioner.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 { Realm } from '@authup/core-kit';\nimport type { Logger } from '@authup/server-kit';\nimport { JWKUse } from '@authup/specs';\nimport type { IKeyProvisioner, IKeyStore } from './types.ts';\n\nexport type KeyProvisionerContext = {\n keyStore: IKeyStore,\n logger?: Logger,\n};\n\n/**\n * Eagerly mints a realm's sig + enc keys (plan 071 hybrid model): run at\n * realm creation and as a startup backfill, so keys are visible in the\n * management API from the moment a realm exists instead of appearing on\n * first use. resolveOrCreate stays as the zero-rows self-healing backstop.\n */\nexport class KeyProvisioner implements IKeyProvisioner {\n protected keyStore: IKeyStore;\n\n protected logger?: Logger;\n\n constructor(ctx: KeyProvisionerContext) {\n this.keyStore = ctx.keyStore;\n this.logger = ctx.logger;\n }\n\n async ensureForRealm(realm: Realm | { id: string }): Promise<void> {\n const uses : `${JWKUse}`[] = [JWKUse.SIGNATURE, JWKUse.ENCRYPTION];\n\n for (const use of uses) {\n try {\n await this.keyStore.resolveOrCreate(realm.id, use);\n } catch (e) {\n // rows-exist-but-none-active throws by design (a deliberate\n // admin kill switch) — the provisioning guarantee is only\n // \"at least one row exists\", so log and continue.\n if (this.logger) {\n this.logger.warn(\n `Failed to provision ${use} key for realm ${realm.id}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;GAuBA,IAAaC,iBAAb,MAAaA;CACCC;CAEAC;CAEV,YAAYC,KAA4B;EACpC,KAAKF,WAAWE,IAAIF;EACpB,KAAKC,SAASC,IAAID;CACtB;CAEA,MAAME,eAAeC,OAA8C;EAC/D,MAAMC,OAAuB,CAACP,OAAOQ,WAAWR,OAAOS,
|
|
1
|
+
{"version":3,"file":"provisioner.mjs","names":["JWKUse","KeyProvisioner","keyStore","logger","ctx","ensureForRealm","realm","uses","SIGNATURE","ENCRYPTION","use","resolveOrCreate","id","e","warn","Error","message","String"],"sources":["../../../src/core/key/provisioner.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 { Realm } from '@authup/core-kit';\nimport type { Logger } from '@authup/server-kit';\nimport { JWKUse } from '@authup/specs';\nimport type { IKeyProvisioner, IKeyStore } from './types.ts';\n\nexport type KeyProvisionerContext = {\n keyStore: IKeyStore,\n logger?: Logger,\n};\n\n/**\n * Eagerly mints a realm's sig + enc keys (plan 071 hybrid model): run at\n * realm creation and as a startup backfill, so keys are visible in the\n * management API from the moment a realm exists instead of appearing on\n * first use. resolveOrCreate stays as the zero-rows self-healing backstop.\n */\nexport class KeyProvisioner implements IKeyProvisioner {\n protected keyStore: IKeyStore;\n\n protected logger?: Logger;\n\n constructor(ctx: KeyProvisionerContext) {\n this.keyStore = ctx.keyStore;\n this.logger = ctx.logger;\n }\n\n async ensureForRealm(realm: Realm | { id: string }): Promise<void> {\n const uses : `${JWKUse}`[] = [JWKUse.SIGNATURE, JWKUse.ENCRYPTION];\n\n for (const use of uses) {\n try {\n await this.keyStore.resolveOrCreate(realm.id, use);\n } catch (e) {\n // rows-exist-but-none-active throws by design (a deliberate\n // admin kill switch) — the provisioning guarantee is only\n // \"at least one row exists\", so log and continue.\n if (this.logger) {\n this.logger.warn(\n `Failed to provision ${use} key for realm ${realm.id}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;GAuBA,IAAaC,iBAAb,MAAaA;CACCC;CAEAC;CAEV,YAAYC,KAA4B;EACpC,KAAKF,WAAWE,IAAIF;EACpB,KAAKC,SAASC,IAAID;CACtB;CAEA,MAAME,eAAeC,OAA8C;EAC/D,MAAMC,OAAuB,CAACP,OAAOQ,WAAWR,OAAOS,UAAW;EAElE,KAAK,MAAMC,OAAOH,MACd,IAAI;GACA,MAAM,KAAKL,SAASS,gBAAgBL,MAAMM,IAAIF,GAAAA;EAClD,SAASG,GAAG;GAIR,IAAI,KAAKV,QACL,KAAKA,OAAOW,KACR,uBAAuBJ,IAAI,iBAAiBJ,MAAMM,GAAG,IAAIC,aAAaE,QAAQF,EAAEG,UAAUC,OAAOJ,CAAAA,GAAI;EAGjH;CAER;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realm-cipher.mjs","names":["AuthupError","KeyStatus","SymmetricCipher","JWKUse","REALM_CIPHER_BLOB_VERSION","RealmCipherBlobError","RealmCipher","keyStore","ciphers","ctx","Map","encrypt","plain","realmId","key","resolveOrCreate","ENCRYPTION","decryptionKey","cipher","resolveCipher","id","join","decrypt","blob","parts","split","length","keyId","payload","resolveById","use","status","DISABLED","material","get","set"],"sources":["../../../src/core/key/realm-cipher.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 { AuthupError } from '@authup/errors';\nimport { KeyStatus } from '@authup/core-kit';\nimport type { ISymmetricCipher } from '@authup/server-kit';\nimport { SymmetricCipher } from '@authup/server-kit';\nimport { JWKUse } from '@authup/specs';\nimport { REALM_CIPHER_BLOB_VERSION } from './constants.ts';\nimport { RealmCipherBlobError } from './error.ts';\nimport type { IKeyStore, IRealmCipher } from './types.ts';\n\nexport type RealmCipherContext = {\n keyStore: IKeyStore,\n};\n\nexport class RealmCipher implements IRealmCipher {\n protected keyStore : IKeyStore;\n\n /**\n * Imported ciphers by key id — key MATERIAL is immutable, so entries\n * never invalidate. Status and realm binding are deliberately NOT\n * cached: decrypt re-resolves the key row every call so disabling a\n * key acts as an immediate, reversible kill switch.\n */\n protected ciphers : Map<string, ISymmetricCipher>;\n\n constructor(ctx: RealmCipherContext) {\n this.keyStore = ctx.keyStore;\n this.ciphers = new Map();\n }\n\n async encrypt(plain: string, realmId: string) : Promise<string> {\n const key = await this.keyStore.resolveOrCreate(realmId, JWKUse.ENCRYPTION);\n if (!key.decryptionKey) {\n throw new AuthupError(`An encryption key could not be resolved for realm ${realmId}.`);\n }\n\n const cipher = this.resolveCipher(key.id, key.decryptionKey);\n\n return [\n REALM_CIPHER_BLOB_VERSION,\n key.id,\n await cipher.encrypt(plain),\n ].join('.');\n }\n\n async decrypt(blob: string, realmId: string) : Promise<string> {\n const parts = blob.split('.');\n if (parts.length !== 3 || parts[0] !== REALM_CIPHER_BLOB_VERSION) {\n throw new RealmCipherBlobError('The cipher blob is malformed.');\n }\n\n const [, keyId, payload] = parts;\n\n const key = await this.keyStore.resolveById(keyId);\n if (\n !key ||\n key.use !== JWKUse.ENCRYPTION ||\n !key.decryptionKey\n ) {\n throw new RealmCipherBlobError(`The cipher blob references an unknown encryption key (${keyId}).`);\n }\n\n if (key.status === KeyStatus.DISABLED) {\n throw new RealmCipherBlobError(`The cipher blob references a disabled encryption key (${keyId}).`);\n }\n\n if (key.realmId !== realmId) {\n throw new RealmCipherBlobError(`The cipher blob references a foreign realm's encryption key (${keyId}).`);\n }\n\n const cipher = this.resolveCipher(key.id, key.decryptionKey);\n\n try {\n return await cipher.decrypt(payload);\n } catch {\n // failed GCM authentication / corrupt payload — blob semantics,\n // not infrastructure.\n throw new RealmCipherBlobError(`The cipher blob could not be decrypted (${keyId}).`);\n }\n }\n\n protected resolveCipher(\n keyId: string,\n material: string,\n ) : ISymmetricCipher {\n let cipher = this.ciphers.get(keyId);\n if (!cipher) {\n cipher = new SymmetricCipher(material);\n this.ciphers.set(keyId, cipher);\n }\n\n return cipher;\n }\n}\n"],"mappings":";;;;;;;;;;AAoBA,IAAaM,cAAb,MAAaA;CACCC;;;;;;IAQV;CAEA,YAAYE,KAAyB;EACjC,KAAKF,WAAWE,IAAIF;EACpB,KAAKC,0BAAU,IAAIE,IAAAA;CACvB;CAEA,MAAMC,QAAQC,OAAeC,SAAmC;EAC5D,MAAMC,MAAM,MAAM,KAAKP,SAASQ,gBAAgBF,SAASV,OAAOa,UAAU;EAC1E,IAAI,CAACF,IAAIG,eACL,MAAM,IAAIjB,YAAY,qDAAqDa,QAAQ,EAAE;EAGzF,MAAMK,SAAS,KAAKC,cAAcL,IAAIM,IAAIN,IAAIG,aAAa;EAE3D,OAAO;;GAEHH,IAAIM;GACJ,MAAMF,OAAOP,QAAQC,KAAAA;
|
|
1
|
+
{"version":3,"file":"realm-cipher.mjs","names":["AuthupError","KeyStatus","SymmetricCipher","JWKUse","REALM_CIPHER_BLOB_VERSION","RealmCipherBlobError","RealmCipher","keyStore","ciphers","ctx","Map","encrypt","plain","realmId","key","resolveOrCreate","ENCRYPTION","decryptionKey","cipher","resolveCipher","id","join","decrypt","blob","parts","split","length","keyId","payload","resolveById","use","status","DISABLED","material","get","set"],"sources":["../../../src/core/key/realm-cipher.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 { AuthupError } from '@authup/errors';\nimport { KeyStatus } from '@authup/core-kit';\nimport type { ISymmetricCipher } from '@authup/server-kit';\nimport { SymmetricCipher } from '@authup/server-kit';\nimport { JWKUse } from '@authup/specs';\nimport { REALM_CIPHER_BLOB_VERSION } from './constants.ts';\nimport { RealmCipherBlobError } from './error.ts';\nimport type { IKeyStore, IRealmCipher } from './types.ts';\n\nexport type RealmCipherContext = {\n keyStore: IKeyStore,\n};\n\nexport class RealmCipher implements IRealmCipher {\n protected keyStore : IKeyStore;\n\n /**\n * Imported ciphers by key id — key MATERIAL is immutable, so entries\n * never invalidate. Status and realm binding are deliberately NOT\n * cached: decrypt re-resolves the key row every call so disabling a\n * key acts as an immediate, reversible kill switch.\n */\n protected ciphers : Map<string, ISymmetricCipher>;\n\n constructor(ctx: RealmCipherContext) {\n this.keyStore = ctx.keyStore;\n this.ciphers = new Map();\n }\n\n async encrypt(plain: string, realmId: string) : Promise<string> {\n const key = await this.keyStore.resolveOrCreate(realmId, JWKUse.ENCRYPTION);\n if (!key.decryptionKey) {\n throw new AuthupError(`An encryption key could not be resolved for realm ${realmId}.`);\n }\n\n const cipher = this.resolveCipher(key.id, key.decryptionKey);\n\n return [\n REALM_CIPHER_BLOB_VERSION,\n key.id,\n await cipher.encrypt(plain),\n ].join('.');\n }\n\n async decrypt(blob: string, realmId: string) : Promise<string> {\n const parts = blob.split('.');\n if (parts.length !== 3 || parts[0] !== REALM_CIPHER_BLOB_VERSION) {\n throw new RealmCipherBlobError('The cipher blob is malformed.');\n }\n\n const [, keyId, payload] = parts;\n\n const key = await this.keyStore.resolveById(keyId);\n if (\n !key ||\n key.use !== JWKUse.ENCRYPTION ||\n !key.decryptionKey\n ) {\n throw new RealmCipherBlobError(`The cipher blob references an unknown encryption key (${keyId}).`);\n }\n\n if (key.status === KeyStatus.DISABLED) {\n throw new RealmCipherBlobError(`The cipher blob references a disabled encryption key (${keyId}).`);\n }\n\n if (key.realmId !== realmId) {\n throw new RealmCipherBlobError(`The cipher blob references a foreign realm's encryption key (${keyId}).`);\n }\n\n const cipher = this.resolveCipher(key.id, key.decryptionKey);\n\n try {\n return await cipher.decrypt(payload);\n } catch {\n // failed GCM authentication / corrupt payload — blob semantics,\n // not infrastructure.\n throw new RealmCipherBlobError(`The cipher blob could not be decrypted (${keyId}).`);\n }\n }\n\n protected resolveCipher(\n keyId: string,\n material: string,\n ) : ISymmetricCipher {\n let cipher = this.ciphers.get(keyId);\n if (!cipher) {\n cipher = new SymmetricCipher(material);\n this.ciphers.set(keyId, cipher);\n }\n\n return cipher;\n }\n}\n"],"mappings":";;;;;;;;;;AAoBA,IAAaM,cAAb,MAAaA;CACCC;;;;;;IAQV;CAEA,YAAYE,KAAyB;EACjC,KAAKF,WAAWE,IAAIF;EACpB,KAAKC,0BAAU,IAAIE,IAAAA;CACvB;CAEA,MAAMC,QAAQC,OAAeC,SAAmC;EAC5D,MAAMC,MAAM,MAAM,KAAKP,SAASQ,gBAAgBF,SAASV,OAAOa,UAAU;EAC1E,IAAI,CAACF,IAAIG,eACL,MAAM,IAAIjB,YAAY,qDAAqDa,QAAQ,EAAE;EAGzF,MAAMK,SAAS,KAAKC,cAAcL,IAAIM,IAAIN,IAAIG,aAAa;EAE3D,OAAO;;GAEHH,IAAIM;GACJ,MAAMF,OAAOP,QAAQC,KAAAA;EACxB,CAAA,CAACS,KAAK,GAAA;CACX;CAEA,MAAMC,QAAQC,MAAcV,SAAmC;EAC3D,MAAMW,QAAQD,KAAKE,MAAM,GAAA;EACzB,IAAID,MAAME,WAAW,KAAKF,MAAM,OAAA,MAC5B,MAAM,IAAInB,qBAAqB,+BAAA;EAGnC,MAAM,GAAGsB,OAAOC,WAAWJ;EAE3B,MAAMV,MAAM,MAAM,KAAKP,SAASsB,YAAYF,KAAAA;EAC5C,IACI,CAACb,OACDA,IAAIgB,QAAQ3B,OAAOa,cACnB,CAACF,IAAIG,eAEL,MAAM,IAAIZ,qBAAqB,yDAAyDsB,MAAM,GAAG;EAGrG,IAAIb,IAAIiB,WAAW9B,UAAU+B,UACzB,MAAM,IAAI3B,qBAAqB,yDAAyDsB,MAAM,GAAG;EAGrG,IAAIb,IAAID,YAAYA,SAChB,MAAM,IAAIR,qBAAqB,gEAAgEsB,MAAM,GAAG;EAG5G,MAAMT,SAAS,KAAKC,cAAcL,IAAIM,IAAIN,IAAIG,aAAa;EAE3D,IAAI;GACA,OAAO,MAAMC,OAAOI,QAAQM,OAAAA;EAChC,QAAQ;GAGJ,MAAM,IAAIvB,qBAAqB,2CAA2CsB,MAAM,GAAG;EACvF;CACJ;CAEUR,cACNQ,OACAM,UACiB;EACjB,IAAIf,SAAS,KAAKV,QAAQ0B,IAAIP,KAAAA;EAC9B,IAAI,CAACT,QAAQ;GACTA,SAAS,IAAIhB,gBAAgB+B,QAAAA;GAC7B,KAAKzB,QAAQ2B,IAAIR,OAAOT,MAAAA;EAC5B;EAEA,OAAOA;CACX;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mfa-email-otp.mjs","names":["TranslatorTranslationMailKey","code","note","paragraph","defineMailTemplate","MailTemplateName","mfaEmailOtpMailTemplate","name","MFA_EMAIL_OTP","build","params","t","subject","intro","codeLabel","hint","Promise","all","MFA_EMAIL_OTP_SUBJECT","MFA_EMAIL_OTP_INTRO","CODE","MFA_EMAIL_OTP_HINT","expiry","expiresInMinutes","MFA_EMAIL_OTP_EXPIRY","minutes","undefined","preview","blocks"],"sources":["../../../../../src/core/mail/template/templates/mfa-email-otp.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport { code, note, paragraph } from '../../format/blocks.ts';\nimport { defineMailTemplate } from '../define.ts';\nimport { MailTemplateName } from '../types.ts';\n\nexport const mfaEmailOtpMailTemplate = defineMailTemplate({\n name: MailTemplateName.MFA_EMAIL_OTP,\n build: async (params, t) => {\n const [subject, intro, codeLabel, hint] = await Promise.all([\n t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_SUBJECT),\n t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_INTRO),\n t(TranslatorTranslationMailKey.CODE),\n t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_HINT),\n ]);\n\n const expiry = params.expiresInMinutes ?\n await t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_EXPIRY, { minutes: params.expiresInMinutes }) :\n undefined;\n\n return {\n subject,\n preview: intro,\n blocks: [\n paragraph(intro),\n code(codeLabel, params.code),\n ...(expiry ? [note(expiry)] : []),\n note(hint),\n ],\n };\n },\n});\n"],"mappings":";;;;;;;;AAYA,MAAaM,0BAA0BF,mBAAmB;CACtDG,MAAMF,iBAAiBG;CACvBC,OAAO,OAAOC,QAAQC,MAAAA;EAClB,MAAM,CAACC,SAASC,OAAOC,WAAWC,QAAQ,MAAMC,QAAQC,IAAI;GACxDN,EAAEX,6BAA6BkB,qBAAqB;GACpDP,EAAEX,6BAA6BmB,mBAAmB;GAClDR,EAAEX,6BAA6BoB,IAAI;GACnCT,EAAEX,6BAA6BqB,kBAAkB;
|
|
1
|
+
{"version":3,"file":"mfa-email-otp.mjs","names":["TranslatorTranslationMailKey","code","note","paragraph","defineMailTemplate","MailTemplateName","mfaEmailOtpMailTemplate","name","MFA_EMAIL_OTP","build","params","t","subject","intro","codeLabel","hint","Promise","all","MFA_EMAIL_OTP_SUBJECT","MFA_EMAIL_OTP_INTRO","CODE","MFA_EMAIL_OTP_HINT","expiry","expiresInMinutes","MFA_EMAIL_OTP_EXPIRY","minutes","undefined","preview","blocks"],"sources":["../../../../../src/core/mail/template/templates/mfa-email-otp.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport { code, note, paragraph } from '../../format/blocks.ts';\nimport { defineMailTemplate } from '../define.ts';\nimport { MailTemplateName } from '../types.ts';\n\nexport const mfaEmailOtpMailTemplate = defineMailTemplate({\n name: MailTemplateName.MFA_EMAIL_OTP,\n build: async (params, t) => {\n const [subject, intro, codeLabel, hint] = await Promise.all([\n t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_SUBJECT),\n t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_INTRO),\n t(TranslatorTranslationMailKey.CODE),\n t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_HINT),\n ]);\n\n const expiry = params.expiresInMinutes ?\n await t(TranslatorTranslationMailKey.MFA_EMAIL_OTP_EXPIRY, { minutes: params.expiresInMinutes }) :\n undefined;\n\n return {\n subject,\n preview: intro,\n blocks: [\n paragraph(intro),\n code(codeLabel, params.code),\n ...(expiry ? [note(expiry)] : []),\n note(hint),\n ],\n };\n },\n});\n"],"mappings":";;;;;;;;AAYA,MAAaM,0BAA0BF,mBAAmB;CACtDG,MAAMF,iBAAiBG;CACvBC,OAAO,OAAOC,QAAQC,MAAAA;EAClB,MAAM,CAACC,SAASC,OAAOC,WAAWC,QAAQ,MAAMC,QAAQC,IAAI;GACxDN,EAAEX,6BAA6BkB,qBAAqB;GACpDP,EAAEX,6BAA6BmB,mBAAmB;GAClDR,EAAEX,6BAA6BoB,IAAI;GACnCT,EAAEX,6BAA6BqB,kBAAkB;EACpD,CAAA;EAED,MAAMC,SAASZ,OAAOa,mBAClB,MAAMZ,EAAEX,6BAA6BwB,sBAAsB,EAAEC,SAASf,OAAOa,iBAAiB,CAAA,IAC9FG,KAAAA;EAEJ,OAAO;GACHd;GACAe,SAASd;GACTe,QAAQ;IACJzB,UAAUU,KAAAA;IACVZ,KAAKa,WAAWJ,OAAOT,IAAI;IACvBqB,GAAAA,SAAS,CAACpB,KAAKoB,MAAAA,CAAQ,IAAG,CAAA;IAC9BpB,KAAKa,IAAAA;GACR;EACL;CACJ;AACJ,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-reset.mjs","names":["TranslatorTranslationMailKey","action","code","note","paragraph","defineMailTemplate","MailTemplateName","passwordResetMailTemplate","name","PASSWORD_RESET","build","params","t","subject","intro","codeLabel","actionLabel","hint","Promise","all","PASSWORD_RESET_SUBJECT","PASSWORD_RESET_INTRO","CODE","PASSWORD_RESET_ACTION","PASSWORD_RESET_HINT","expiry","expiresInMinutes","PASSWORD_RESET_EXPIRY","minutes","undefined","preview","blocks","url"],"sources":["../../../../../src/core/mail/template/templates/password-reset.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport { \n action, \n code, \n note, \n paragraph, \n} from '../../format/blocks.ts';\nimport { defineMailTemplate } from '../define.ts';\nimport { MailTemplateName } from '../types.ts';\n\nexport const passwordResetMailTemplate = defineMailTemplate({\n name: MailTemplateName.PASSWORD_RESET,\n build: async (params, t) => {\n const [subject, intro, codeLabel, actionLabel, hint] = await Promise.all([\n t(TranslatorTranslationMailKey.PASSWORD_RESET_SUBJECT),\n t(TranslatorTranslationMailKey.PASSWORD_RESET_INTRO),\n t(TranslatorTranslationMailKey.CODE),\n t(TranslatorTranslationMailKey.PASSWORD_RESET_ACTION),\n t(TranslatorTranslationMailKey.PASSWORD_RESET_HINT),\n ]);\n\n const expiry = params.expiresInMinutes ?\n await t(TranslatorTranslationMailKey.PASSWORD_RESET_EXPIRY, { minutes: params.expiresInMinutes }) :\n undefined;\n\n return {\n subject,\n preview: intro,\n blocks: [\n paragraph(intro),\n code(codeLabel, params.code),\n ...(params.url ? [action(actionLabel, params.url)] : []),\n ...(expiry ? [note(expiry)] : []),\n note(hint),\n ],\n };\n },\n});\n"],"mappings":";;;;;;;;AAiBA,MAAaO,4BAA4BF,mBAAmB;CACxDG,MAAMF,iBAAiBG;CACvBC,OAAO,OAAOC,QAAQC,MAAAA;EAClB,MAAM,CAACC,SAASC,OAAOC,WAAWC,aAAaC,QAAQ,MAAMC,QAAQC,IAAI;GACrEP,EAAEZ,6BAA6BoB,sBAAsB;GACrDR,EAAEZ,6BAA6BqB,oBAAoB;GACnDT,EAAEZ,6BAA6BsB,IAAI;GACnCV,EAAEZ,6BAA6BuB,qBAAqB;GACpDX,EAAEZ,6BAA6BwB,mBAAmB;
|
|
1
|
+
{"version":3,"file":"password-reset.mjs","names":["TranslatorTranslationMailKey","action","code","note","paragraph","defineMailTemplate","MailTemplateName","passwordResetMailTemplate","name","PASSWORD_RESET","build","params","t","subject","intro","codeLabel","actionLabel","hint","Promise","all","PASSWORD_RESET_SUBJECT","PASSWORD_RESET_INTRO","CODE","PASSWORD_RESET_ACTION","PASSWORD_RESET_HINT","expiry","expiresInMinutes","PASSWORD_RESET_EXPIRY","minutes","undefined","preview","blocks","url"],"sources":["../../../../../src/core/mail/template/templates/password-reset.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport { \n action, \n code, \n note, \n paragraph, \n} from '../../format/blocks.ts';\nimport { defineMailTemplate } from '../define.ts';\nimport { MailTemplateName } from '../types.ts';\n\nexport const passwordResetMailTemplate = defineMailTemplate({\n name: MailTemplateName.PASSWORD_RESET,\n build: async (params, t) => {\n const [subject, intro, codeLabel, actionLabel, hint] = await Promise.all([\n t(TranslatorTranslationMailKey.PASSWORD_RESET_SUBJECT),\n t(TranslatorTranslationMailKey.PASSWORD_RESET_INTRO),\n t(TranslatorTranslationMailKey.CODE),\n t(TranslatorTranslationMailKey.PASSWORD_RESET_ACTION),\n t(TranslatorTranslationMailKey.PASSWORD_RESET_HINT),\n ]);\n\n const expiry = params.expiresInMinutes ?\n await t(TranslatorTranslationMailKey.PASSWORD_RESET_EXPIRY, { minutes: params.expiresInMinutes }) :\n undefined;\n\n return {\n subject,\n preview: intro,\n blocks: [\n paragraph(intro),\n code(codeLabel, params.code),\n ...(params.url ? [action(actionLabel, params.url)] : []),\n ...(expiry ? [note(expiry)] : []),\n note(hint),\n ],\n };\n },\n});\n"],"mappings":";;;;;;;;AAiBA,MAAaO,4BAA4BF,mBAAmB;CACxDG,MAAMF,iBAAiBG;CACvBC,OAAO,OAAOC,QAAQC,MAAAA;EAClB,MAAM,CAACC,SAASC,OAAOC,WAAWC,aAAaC,QAAQ,MAAMC,QAAQC,IAAI;GACrEP,EAAEZ,6BAA6BoB,sBAAsB;GACrDR,EAAEZ,6BAA6BqB,oBAAoB;GACnDT,EAAEZ,6BAA6BsB,IAAI;GACnCV,EAAEZ,6BAA6BuB,qBAAqB;GACpDX,EAAEZ,6BAA6BwB,mBAAmB;EACrD,CAAA;EAED,MAAMC,SAASd,OAAOe,mBAClB,MAAMd,EAAEZ,6BAA6B2B,uBAAuB,EAAEC,SAASjB,OAAOe,iBAAiB,CAAA,IAC/FG,KAAAA;EAEJ,OAAO;GACHhB;GACAiB,SAAShB;GACTiB,QAAQ;IACJ3B,UAAUU,KAAAA;IACVZ,KAAKa,WAAWJ,OAAOT,IAAI;IACvBS,GAAAA,OAAOqB,MAAM,CAAC/B,OAAOe,aAAaL,OAAOqB,GAAG,CAAE,IAAG,CAAA;IACjDP,GAAAA,SAAS,CAACtB,KAAKsB,MAAAA,CAAQ,IAAG,CAAA;IAC9BtB,KAAKc,IAAAA;GACR;EACL;CACJ;AACJ,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-activation.mjs","names":["TranslatorTranslationMailKey","action","code","note","paragraph","defineMailTemplate","MailTemplateName","registrationActivationMailTemplate","name","REGISTRATION_ACTIVATION","build","params","t","subject","intro","codeLabel","actionLabel","hint","Promise","all","REGISTRATION_ACTIVATION_SUBJECT","REGISTRATION_ACTIVATION_INTRO","CODE","REGISTRATION_ACTIVATION_ACTION","REGISTRATION_ACTIVATION_HINT","preview","blocks","url"],"sources":["../../../../../src/core/mail/template/templates/registration-activation.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport { \n action, \n code, \n note, \n paragraph, \n} from '../../format/blocks.ts';\nimport { defineMailTemplate } from '../define.ts';\nimport { MailTemplateName } from '../types.ts';\n\nexport const registrationActivationMailTemplate = defineMailTemplate({\n name: MailTemplateName.REGISTRATION_ACTIVATION,\n build: async (params, t) => {\n const [subject, intro, codeLabel, actionLabel, hint] = await Promise.all([\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_SUBJECT),\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_INTRO),\n t(TranslatorTranslationMailKey.CODE),\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_ACTION),\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_HINT),\n ]);\n\n return {\n subject,\n preview: intro,\n blocks: [\n paragraph(intro),\n code(codeLabel, params.code),\n ...(params.url ? [action(actionLabel, params.url)] : []),\n note(hint),\n ],\n };\n },\n});\n"],"mappings":";;;;;;;;AAiBA,MAAaO,qCAAqCF,mBAAmB;CACjEG,MAAMF,iBAAiBG;CACvBC,OAAO,OAAOC,QAAQC,MAAAA;EAClB,MAAM,CAACC,SAASC,OAAOC,WAAWC,aAAaC,QAAQ,MAAMC,QAAQC,IAAI;GACrEP,EAAEZ,6BAA6BoB,+BAA+B;GAC9DR,EAAEZ,6BAA6BqB,6BAA6B;GAC5DT,EAAEZ,6BAA6BsB,IAAI;GACnCV,EAAEZ,6BAA6BuB,8BAA8B;GAC7DX,EAAEZ,6BAA6BwB,4BAA4B;
|
|
1
|
+
{"version":3,"file":"registration-activation.mjs","names":["TranslatorTranslationMailKey","action","code","note","paragraph","defineMailTemplate","MailTemplateName","registrationActivationMailTemplate","name","REGISTRATION_ACTIVATION","build","params","t","subject","intro","codeLabel","actionLabel","hint","Promise","all","REGISTRATION_ACTIVATION_SUBJECT","REGISTRATION_ACTIVATION_INTRO","CODE","REGISTRATION_ACTIVATION_ACTION","REGISTRATION_ACTIVATION_HINT","preview","blocks","url"],"sources":["../../../../../src/core/mail/template/templates/registration-activation.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport { \n action, \n code, \n note, \n paragraph, \n} from '../../format/blocks.ts';\nimport { defineMailTemplate } from '../define.ts';\nimport { MailTemplateName } from '../types.ts';\n\nexport const registrationActivationMailTemplate = defineMailTemplate({\n name: MailTemplateName.REGISTRATION_ACTIVATION,\n build: async (params, t) => {\n const [subject, intro, codeLabel, actionLabel, hint] = await Promise.all([\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_SUBJECT),\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_INTRO),\n t(TranslatorTranslationMailKey.CODE),\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_ACTION),\n t(TranslatorTranslationMailKey.REGISTRATION_ACTIVATION_HINT),\n ]);\n\n return {\n subject,\n preview: intro,\n blocks: [\n paragraph(intro),\n code(codeLabel, params.code),\n ...(params.url ? [action(actionLabel, params.url)] : []),\n note(hint),\n ],\n };\n },\n});\n"],"mappings":";;;;;;;;AAiBA,MAAaO,qCAAqCF,mBAAmB;CACjEG,MAAMF,iBAAiBG;CACvBC,OAAO,OAAOC,QAAQC,MAAAA;EAClB,MAAM,CAACC,SAASC,OAAOC,WAAWC,aAAaC,QAAQ,MAAMC,QAAQC,IAAI;GACrEP,EAAEZ,6BAA6BoB,+BAA+B;GAC9DR,EAAEZ,6BAA6BqB,6BAA6B;GAC5DT,EAAEZ,6BAA6BsB,IAAI;GACnCV,EAAEZ,6BAA6BuB,8BAA8B;GAC7DX,EAAEZ,6BAA6BwB,4BAA4B;EAC9D,CAAA;EAED,OAAO;GACHX;GACAY,SAASX;GACTY,QAAQ;IACJtB,UAAUU,KAAAA;IACVZ,KAAKa,WAAWJ,OAAOT,IAAI;IACvBS,GAAAA,OAAOgB,MAAM,CAAC1B,OAAOe,aAAaL,OAAOgB,GAAG,CAAE,IAAG,CAAA;IACrDxB,KAAKc,IAAAA;GACR;EACL;CACJ;AACJ,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","names":["MailTemplateName"],"sources":["../../../../src/core/mail/template/types.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport type { MailBlock } from '../format/types.ts';\n\nexport enum MailTemplateName {\n REGISTRATION_ACTIVATION = 'registration-activation',\n PASSWORD_RESET = 'password-reset',\n MFA_EMAIL_OTP = 'mfa-email-otp',\n}\n\nexport type MailTemplateParamsMap = {\n [MailTemplateName.REGISTRATION_ACTIVATION]: {\n code: string,\n url?: string,\n },\n [MailTemplateName.PASSWORD_RESET]: {\n code: string,\n url?: string,\n expiresInMinutes?: number,\n },\n [MailTemplateName.MFA_EMAIL_OTP]: {\n code: string,\n expiresInMinutes?: number,\n },\n};\n\n/**\n * Locale-bound translator handed to a template's `build`. Resolves a key\n * of the `authupMail` namespace (`@authup/i18n`) through ilingo — `data`\n * feeds `{{var}}` interpolation. Async so file- or remote-backed override\n * stores can slot in behind the same contract.\n */\nexport type MailTemplateTranslator = (\n key: `${TranslatorTranslationMailKey}`,\n data?: Record<string, any>,\n) => Promise<string>;\n\nexport type MailTemplateBuildOutput = {\n subject: string,\n // Hidden preheader shown by mail clients as the preview line.\n preview?: string,\n blocks: MailBlock[],\n};\n\n/**\n * A mail template composes its body from blocks; subject, html and text\n * all derive from the same build output. Copy is not embedded — it is\n * resolved per locale through the supplied translator.\n */\nexport type MailTemplate<N extends MailTemplateName = MailTemplateName> = {\n name: N,\n build(\n params: MailTemplateParamsMap[N],\n t: MailTemplateTranslator,\n ): Promise<MailTemplateBuildOutput>,\n};\n"],"mappings":";;;;AAUA,IAAO,mBAAKA,uBAAAA,kBAAAA;;;;
|
|
1
|
+
{"version":3,"file":"types.mjs","names":["MailTemplateName"],"sources":["../../../../src/core/mail/template/types.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 { TranslatorTranslationMailKey } from '@authup/i18n';\nimport type { MailBlock } from '../format/types.ts';\n\nexport enum MailTemplateName {\n REGISTRATION_ACTIVATION = 'registration-activation',\n PASSWORD_RESET = 'password-reset',\n MFA_EMAIL_OTP = 'mfa-email-otp',\n}\n\nexport type MailTemplateParamsMap = {\n [MailTemplateName.REGISTRATION_ACTIVATION]: {\n code: string,\n url?: string,\n },\n [MailTemplateName.PASSWORD_RESET]: {\n code: string,\n url?: string,\n expiresInMinutes?: number,\n },\n [MailTemplateName.MFA_EMAIL_OTP]: {\n code: string,\n expiresInMinutes?: number,\n },\n};\n\n/**\n * Locale-bound translator handed to a template's `build`. Resolves a key\n * of the `authupMail` namespace (`@authup/i18n`) through ilingo — `data`\n * feeds `{{var}}` interpolation. Async so file- or remote-backed override\n * stores can slot in behind the same contract.\n */\nexport type MailTemplateTranslator = (\n key: `${TranslatorTranslationMailKey}`,\n data?: Record<string, any>,\n) => Promise<string>;\n\nexport type MailTemplateBuildOutput = {\n subject: string,\n // Hidden preheader shown by mail clients as the preview line.\n preview?: string,\n blocks: MailBlock[],\n};\n\n/**\n * A mail template composes its body from blocks; subject, html and text\n * all derive from the same build output. Copy is not embedded — it is\n * resolved per locale through the supplied translator.\n */\nexport type MailTemplate<N extends MailTemplateName = MailTemplateName> = {\n name: N,\n build(\n params: MailTemplateParamsMap[N],\n t: MailTemplateTranslator,\n ): Promise<MailTemplateBuildOutput>,\n};\n"],"mappings":";;;;AAUA,IAAO,mBAAKA,uBAAAA,kBAAAA;;;;CAAAA,OAAAA;AAIX,EAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.mjs","names":["OAuth2AuthorizationCodeChallengeMethod","OAuth2GrantError","buildOAuth2CodeChallenge","OAuth2AuthorizationCodeVerifier","repository","verify","code","options","entity","popOneById","invalid","client_id","clientId","realmId","realm_id","redirect_uri","redirectUri","redirectUriMismatch","clientIsPublic","code_challenge","codeVerifier","code_challenge_method","SHA_256","codeVerifierHash"],"sources":["../../../../../../src/core/oauth2/authorization/code/verifier/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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 { OAuth2AuthorizationCode } from '@authup/core-kit';\nimport { OAuth2AuthorizationCodeChallengeMethod, OAuth2GrantError } from '@authup/specs';\nimport { buildOAuth2CodeChallenge } from '../../helpers.ts';\n\nimport type { IOAuth2AuthorizationCodeRepository } from '../repository/index.ts';\nimport type { IOAuth2AuthorizationCodeVerifier, IOAuth2AuthorizationCodeVerifyOptions } from './types.ts';\n\nexport class OAuth2AuthorizationCodeVerifier implements IOAuth2AuthorizationCodeVerifier {\n protected repository : IOAuth2AuthorizationCodeRepository;\n\n constructor(repository: IOAuth2AuthorizationCodeRepository) {\n this.repository = repository;\n }\n\n async verify(code: string, options: IOAuth2AuthorizationCodeVerifyOptions) : Promise<OAuth2AuthorizationCode> {\n const entity = await this.repository.popOneById(code);\n if (!entity) {\n throw OAuth2GrantError.invalid();\n }\n\n // RFC 6749 §4.1.3: if the client was issued a client_id, verify the\n // authorization code was issued to the authenticated client. Always\n // require a clientId to be supplied so a malformed token request can't\n // bypass the binding by omitting it.\n if (entity.client_id) {\n if (!options.clientId || options.clientId !== entity.client_id) {\n throw OAuth2GrantError.invalid();\n }\n }\n\n // Realm binding (defense in depth): the code's realm (the authorizing\n // identity's realm) must match the authenticated client's realm. Blocks\n // redeeming a realm-A identity's code against a realm-B client — covers\n // codes minted outside OAuth2Authorization.authorize() (identity-provider\n // callback) and any in-flight codes issued before the authorize-side gate.\n if (options.realmId && entity.realm_id && entity.realm_id !== options.realmId) {\n throw OAuth2GrantError.invalid();\n }\n\n if (entity.redirect_uri) {\n if (!options.redirectUri || entity.redirect_uri !== options.redirectUri) {\n throw OAuth2GrantError.redirectUriMismatch();\n }\n }\n\n // Public clients MUST use PKCE (RFC 7636). Defense in depth in case\n // the authorize-side check was bypassed or the client's\n // auth_method changed between authorize and token.\n if (options.clientIsPublic && !entity.code_challenge) {\n throw OAuth2GrantError.invalid('PKCE is required for public clients.');\n }\n\n if (entity.code_challenge) {\n if (!options.codeVerifier) {\n throw OAuth2GrantError.invalid('Code verifier invalid.');\n }\n\n // RFC 7636 §4.3: code_challenge_method defaults to \"plain\" when\n // absent. Only treat the challenge as S256 when the client\n // explicitly sent code_challenge_method=S256.\n if (entity.code_challenge_method === OAuth2AuthorizationCodeChallengeMethod.SHA_256) {\n const codeVerifierHash = await buildOAuth2CodeChallenge(options.codeVerifier);\n if (codeVerifierHash !== entity.code_challenge) {\n throw OAuth2GrantError.invalid('PKCE code_verifier mismatch.');\n }\n } else if (options.codeVerifier !== entity.code_challenge) {\n throw OAuth2GrantError.invalid('PKCE code_verifier mismatch.');\n }\n }\n\n return entity;\n }\n}\n"],"mappings":";;;;;;AAcA,IAAaG,kCAAb,MAAaA;CACCC;CAEV,YAAYA,YAAgD;EACxD,KAAKA,aAAaA;CACtB;CAEA,MAAMC,OAAOC,MAAcC,SAAmF;EAC1G,MAAMC,SAAS,MAAM,KAAKJ,WAAWK,WAAWH,IAAAA;EAChD,IAAI,CAACE,QACD,MAAMP,iBAAiBS,QAAO;EAOlC,IAAIF,OAAOG;
|
|
1
|
+
{"version":3,"file":"module.mjs","names":["OAuth2AuthorizationCodeChallengeMethod","OAuth2GrantError","buildOAuth2CodeChallenge","OAuth2AuthorizationCodeVerifier","repository","verify","code","options","entity","popOneById","invalid","client_id","clientId","realmId","realm_id","redirect_uri","redirectUri","redirectUriMismatch","clientIsPublic","code_challenge","codeVerifier","code_challenge_method","SHA_256","codeVerifierHash"],"sources":["../../../../../../src/core/oauth2/authorization/code/verifier/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\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 { OAuth2AuthorizationCode } from '@authup/core-kit';\nimport { OAuth2AuthorizationCodeChallengeMethod, OAuth2GrantError } from '@authup/specs';\nimport { buildOAuth2CodeChallenge } from '../../helpers.ts';\n\nimport type { IOAuth2AuthorizationCodeRepository } from '../repository/index.ts';\nimport type { IOAuth2AuthorizationCodeVerifier, IOAuth2AuthorizationCodeVerifyOptions } from './types.ts';\n\nexport class OAuth2AuthorizationCodeVerifier implements IOAuth2AuthorizationCodeVerifier {\n protected repository : IOAuth2AuthorizationCodeRepository;\n\n constructor(repository: IOAuth2AuthorizationCodeRepository) {\n this.repository = repository;\n }\n\n async verify(code: string, options: IOAuth2AuthorizationCodeVerifyOptions) : Promise<OAuth2AuthorizationCode> {\n const entity = await this.repository.popOneById(code);\n if (!entity) {\n throw OAuth2GrantError.invalid();\n }\n\n // RFC 6749 §4.1.3: if the client was issued a client_id, verify the\n // authorization code was issued to the authenticated client. Always\n // require a clientId to be supplied so a malformed token request can't\n // bypass the binding by omitting it.\n if (entity.client_id) {\n if (!options.clientId || options.clientId !== entity.client_id) {\n throw OAuth2GrantError.invalid();\n }\n }\n\n // Realm binding (defense in depth): the code's realm (the authorizing\n // identity's realm) must match the authenticated client's realm. Blocks\n // redeeming a realm-A identity's code against a realm-B client — covers\n // codes minted outside OAuth2Authorization.authorize() (identity-provider\n // callback) and any in-flight codes issued before the authorize-side gate.\n if (options.realmId && entity.realm_id && entity.realm_id !== options.realmId) {\n throw OAuth2GrantError.invalid();\n }\n\n if (entity.redirect_uri) {\n if (!options.redirectUri || entity.redirect_uri !== options.redirectUri) {\n throw OAuth2GrantError.redirectUriMismatch();\n }\n }\n\n // Public clients MUST use PKCE (RFC 7636). Defense in depth in case\n // the authorize-side check was bypassed or the client's\n // auth_method changed between authorize and token.\n if (options.clientIsPublic && !entity.code_challenge) {\n throw OAuth2GrantError.invalid('PKCE is required for public clients.');\n }\n\n if (entity.code_challenge) {\n if (!options.codeVerifier) {\n throw OAuth2GrantError.invalid('Code verifier invalid.');\n }\n\n // RFC 7636 §4.3: code_challenge_method defaults to \"plain\" when\n // absent. Only treat the challenge as S256 when the client\n // explicitly sent code_challenge_method=S256.\n if (entity.code_challenge_method === OAuth2AuthorizationCodeChallengeMethod.SHA_256) {\n const codeVerifierHash = await buildOAuth2CodeChallenge(options.codeVerifier);\n if (codeVerifierHash !== entity.code_challenge) {\n throw OAuth2GrantError.invalid('PKCE code_verifier mismatch.');\n }\n } else if (options.codeVerifier !== entity.code_challenge) {\n throw OAuth2GrantError.invalid('PKCE code_verifier mismatch.');\n }\n }\n\n return entity;\n }\n}\n"],"mappings":";;;;;;AAcA,IAAaG,kCAAb,MAAaA;CACCC;CAEV,YAAYA,YAAgD;EACxD,KAAKA,aAAaA;CACtB;CAEA,MAAMC,OAAOC,MAAcC,SAAmF;EAC1G,MAAMC,SAAS,MAAM,KAAKJ,WAAWK,WAAWH,IAAAA;EAChD,IAAI,CAACE,QACD,MAAMP,iBAAiBS,QAAO;EAOlC,IAAIF,OAAOG,WACH;OAAA,CAACJ,QAAQK,YAAYL,QAAQK,aAAaJ,OAAOG,WACjD,MAAMV,iBAAiBS,QAAO;EAAA;EAStC,IAAIH,QAAQM,WAAWL,OAAOM,YAAYN,OAAOM,aAAaP,QAAQM,SAClE,MAAMZ,iBAAiBS,QAAO;EAGlC,IAAIF,OAAOO,cACH;OAAA,CAACR,QAAQS,eAAeR,OAAOO,iBAAiBR,QAAQS,aACxD,MAAMf,iBAAiBgB,oBAAmB;EAAA;EAOlD,IAAIV,QAAQW,kBAAkB,CAACV,OAAOW,gBAClC,MAAMlB,iBAAiBS,QAAQ,sCAAA;EAGnC,IAAIF,OAAOW,gBAAgB;GACvB,IAAI,CAACZ,QAAQa,cACT,MAAMnB,iBAAiBS,QAAQ,wBAAA;GAMnC,IAAIF,OAAOa,0BAA0BrB,uCAAuCsB,SAEpEC;QAAAA,MAD2BrB,yBAAyBK,QAAQa,YAAY,MACnDZ,OAAOW,gBAC5B,MAAMlB,iBAAiBS,QAAQ,8BAAA;GAAA,OAEhC,IAAIH,QAAQa,iBAAiBZ,OAAOW,gBACvC,MAAMlB,iBAAiBS,QAAQ,8BAAA;EAEvC;EAEA,OAAOF;CACX;AACJ"}
|