@authup/server-core 1.0.0-beta.56 → 1.0.0-beta.58
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/domains/role/entity.d.ts.map +1 -1
- package/dist/adapters/database/domains/role/entity.mjs +2 -1
- package/dist/adapters/database/domains/role/entity.mjs.map +1 -1
- package/dist/adapters/database/logger/module.mjs +2 -4
- package/dist/adapters/database/logger/module.mjs.map +1 -1
- package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.d.ts +25 -0
- package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.d.ts.map +1 -0
- package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.mjs +60 -0
- package/dist/adapters/database/migrations/mysql/1784970000000-RoleClientForeignKey.mjs.map +1 -0
- package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.d.ts +25 -0
- package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.d.ts.map +1 -0
- package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.mjs +60 -0
- package/dist/adapters/database/migrations/postgres/1784970000000-RoleClientForeignKey.mjs.map +1 -0
- package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/identity.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/identity.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/client/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/client/module.mjs +30 -7
- package/dist/adapters/http/controllers/entities/client/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client-permission/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/client-permission/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/client-permission/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/client-permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client-role/module.d.ts +4 -4
- package/dist/adapters/http/controllers/entities/client-role/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/client-role/module.mjs +19 -4
- package/dist/adapters/http/controllers/entities/client-role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/client-scope/module.d.ts +4 -4
- package/dist/adapters/http/controllers/entities/client-scope/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/client-scope/module.mjs +19 -4
- package/dist/adapters/http/controllers/entities/client-scope/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/consent/module.d.ts +3 -3
- package/dist/adapters/http/controllers/entities/consent/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/consent/module.mjs +15 -3
- package/dist/adapters/http/controllers/entities/consent/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/event/module.d.ts +2 -2
- package/dist/adapters/http/controllers/entities/event/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/event/module.mjs +11 -2
- package/dist/adapters/http/controllers/entities/event/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provide-role/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/identity-provide-role/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +24 -8
- package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/key/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/key/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/key/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/key/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/permission/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/permission/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/permission/module.mjs +27 -6
- package/dist/adapters/http/controllers/entities/permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/permission-policy/module.d.ts +4 -4
- package/dist/adapters/http/controllers/entities/permission-policy/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/permission-policy/module.mjs +19 -4
- package/dist/adapters/http/controllers/entities/permission-policy/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/policy/module.d.ts +7 -7
- package/dist/adapters/http/controllers/entities/policy/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/policy/module.mjs +27 -6
- package/dist/adapters/http/controllers/entities/policy/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/realm/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/realm/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/realm/module.mjs +29 -8
- package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/role/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/role/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/role/module.mjs +27 -6
- package/dist/adapters/http/controllers/entities/role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/role-attribute/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/role-attribute/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/role-attribute/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/role-attribute/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/role-permission/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/role-permission/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/role-permission/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/role-permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/scope/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/scope/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/scope/module.mjs +27 -6
- package/dist/adapters/http/controllers/entities/scope/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/session/module.d.ts +3 -3
- package/dist/adapters/http/controllers/entities/session/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/session/module.mjs +15 -3
- package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/trust-anchor/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/trust-anchor/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user/module.d.ts +6 -6
- package/dist/adapters/http/controllers/entities/user/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/user/module.mjs +27 -6
- package/dist/adapters/http/controllers/entities/user/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-attribute/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/user-attribute/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/user-attribute/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/user-attribute/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-authenticator/module.d.ts +4 -4
- package/dist/adapters/http/controllers/entities/user-authenticator/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +19 -4
- package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-permission/module.d.ts +5 -5
- package/dist/adapters/http/controllers/entities/user-permission/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/user-permission/module.mjs +23 -5
- package/dist/adapters/http/controllers/entities/user-permission/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/user-role/module.d.ts +4 -4
- package/dist/adapters/http/controllers/entities/user-role/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/user-role/module.mjs +19 -4
- package/dist/adapters/http/controllers/entities/user-role/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/index.mjs +2 -1
- package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +1 -1
- package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/index.d.ts +1 -0
- package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/index.mjs +3 -1
- package/dist/adapters/http/controllers/workflows/logout/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/logout/module.mjs +5 -1
- package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/userinfo/index.d.ts +2 -0
- package/dist/adapters/http/controllers/workflows/userinfo/index.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/userinfo/index.mjs +5 -0
- package/dist/adapters/http/controllers/workflows/userinfo/module.d.ts +18 -0
- package/dist/adapters/http/controllers/workflows/userinfo/module.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/userinfo/module.mjs +53 -0
- package/dist/adapters/http/controllers/workflows/userinfo/module.mjs.map +1 -0
- package/dist/adapters/http/index.mjs +2 -1
- package/dist/adapters/http/middleware/built-in/authorization/module.d.ts +1 -0
- package/dist/adapters/http/middleware/built-in/authorization/module.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/authorization/module.mjs +10 -1
- package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/rate-limit.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/rate-limit.mjs +4 -2
- package/dist/adapters/http/middleware/built-in/rate-limit.mjs.map +1 -1
- package/dist/adapters/http/request/client-certificate.mjs +1 -1
- package/dist/adapters/http/request/client-certificate.mjs.map +1 -1
- package/dist/adapters/http/request/event-context.mjs +1 -1
- package/dist/adapters/http/request/event-context.mjs.map +1 -1
- package/dist/adapters/http/request/helpers/locations.mjs +1 -3
- package/dist/adapters/http/request/helpers/locations.mjs.map +1 -1
- package/dist/app/factory.d.ts +2 -1
- package/dist/app/factory.d.ts.map +1 -1
- package/dist/app/factory.mjs +2 -2
- package/dist/app/factory.mjs.map +1 -1
- package/dist/app/index.d.ts +1 -0
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.mjs +5 -1
- package/dist/app/modules/authentication/module.mjs +6 -3
- package/dist/app/modules/authentication/module.mjs.map +1 -1
- package/dist/app/modules/authentication/repositories/session.mjs +2 -2
- package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
- package/dist/app/modules/components/module.d.ts +3 -0
- package/dist/app/modules/components/module.d.ts.map +1 -1
- package/dist/app/modules/components/module.mjs +17 -2
- package/dist/app/modules/components/module.mjs.map +1 -1
- package/dist/app/modules/config/constants.d.ts +1 -0
- package/dist/app/modules/config/constants.d.ts.map +1 -1
- package/dist/app/modules/config/constants.mjs +1 -0
- package/dist/app/modules/config/constants.mjs.map +1 -1
- package/dist/app/modules/config/helpers.d.ts +9 -0
- package/dist/app/modules/config/helpers.d.ts.map +1 -0
- package/dist/app/modules/config/helpers.mjs +22 -0
- package/dist/app/modules/config/helpers.mjs.map +1 -0
- package/dist/app/modules/config/index.d.ts +2 -0
- package/dist/app/modules/config/index.d.ts.map +1 -1
- package/dist/app/modules/config/index.mjs +6 -1
- package/dist/app/modules/config/module.d.ts.map +1 -1
- package/dist/app/modules/config/module.mjs +2 -7
- package/dist/app/modules/config/module.mjs.map +1 -1
- package/dist/app/modules/config/normalize.d.ts.map +1 -1
- package/dist/app/modules/config/normalize.mjs +4 -0
- package/dist/app/modules/config/normalize.mjs.map +1 -1
- package/dist/app/modules/config/read/env.d.ts.map +1 -1
- package/dist/app/modules/config/read/env.mjs +2 -0
- package/dist/app/modules/config/read/env.mjs.map +1 -1
- package/dist/app/modules/config/read/fs.d.ts.map +1 -1
- package/dist/app/modules/config/read/fs.mjs +31 -8
- package/dist/app/modules/config/read/fs.mjs.map +1 -1
- package/dist/app/modules/config/read/module.mjs +8 -3
- package/dist/app/modules/config/read/module.mjs.map +1 -1
- package/dist/app/modules/config/trust-proxy.d.ts +28 -0
- package/dist/app/modules/config/trust-proxy.d.ts.map +1 -0
- package/dist/app/modules/config/trust-proxy.mjs +64 -0
- package/dist/app/modules/config/trust-proxy.mjs.map +1 -0
- package/dist/app/modules/config/types.d.ts +18 -0
- package/dist/app/modules/config/types.d.ts.map +1 -1
- package/dist/app/modules/config/validator.d.ts.map +1 -1
- package/dist/app/modules/config/validator.mjs +7 -0
- package/dist/app/modules/config/validator.mjs.map +1 -1
- package/dist/app/modules/database/module.mjs +2 -1
- package/dist/app/modules/database/module.mjs.map +1 -1
- package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/client/repository.mjs +3 -4
- package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/client-permission/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/client-permission/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/client-role/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/client-role/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/client-scope/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/client-scope/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/event/repository.mjs +4 -3
- package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/identity-provider/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/identity-provider/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/identity-provider-role-mapping/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/identity-provider-role-mapping/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/key/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/key/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/permission/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/permission/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/permission-policy/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/permission-policy/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/policy/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/policy/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/query.d.ts +20 -0
- package/dist/app/modules/database/repositories/query.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/query.mjs +26 -3
- package/dist/app/modules/database/repositories/query.mjs.map +1 -1
- package/dist/app/modules/database/repositories/realm/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/realm/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/role/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/role/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/role-attribute/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/role-attribute/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/role-permission/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/role-permission/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/schema-validation.d.ts +17 -3
- package/dist/app/modules/database/repositories/schema-validation.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/schema-validation.mjs +29 -5
- package/dist/app/modules/database/repositories/schema-validation.mjs.map +1 -1
- package/dist/app/modules/database/repositories/scope/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/scope/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/trust-anchor/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/trust-anchor/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user-attribute/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/user-attribute/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user-authenticator/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/user-authenticator/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user-permission/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/user-permission/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user-role/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/user-role/repository.mjs.map +1 -1
- package/dist/app/modules/http/constants.d.ts +2 -13
- package/dist/app/modules/http/constants.d.ts.map +1 -1
- package/dist/app/modules/http/constants.mjs.map +1 -1
- package/dist/app/modules/http/module.d.ts.map +1 -1
- package/dist/app/modules/http/module.mjs +7 -1
- package/dist/app/modules/http/module.mjs.map +1 -1
- package/dist/app/modules/http/modules/controller.d.ts +4 -2
- package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
- package/dist/app/modules/http/modules/controller.mjs +208 -124
- package/dist/app/modules/http/modules/controller.mjs.map +1 -1
- package/dist/app/modules/http/modules/middleware.mjs +10 -5
- package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
- package/dist/app/modules/identity/module.mjs +6 -3
- package/dist/app/modules/identity/module.mjs.map +1 -1
- package/dist/app/modules/index.mjs +5 -1
- package/dist/app/modules/oauth2/module.mjs +37 -17
- package/dist/app/modules/oauth2/module.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs +1 -1
- package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/consent/repository.mjs +2 -2
- package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
- package/dist/app/modules/oauth2/repositories/token/repository.mjs +1 -1
- package/dist/app/modules/oauth2/repositories/token/repository.mjs.map +1 -1
- package/dist/app/modules/provisioning/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/module.mjs +21 -12
- package/dist/app/modules/provisioning/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/file/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/sources/file/module.mjs +11 -2
- package/dist/app/modules/provisioning/sources/file/module.mjs.map +1 -1
- package/dist/app/types.d.ts +5 -0
- package/dist/app/types.d.ts.map +1 -0
- package/dist/app/types.mjs +4 -0
- package/dist/cli/commands/healthcheck.d.ts +2 -1
- package/dist/cli/commands/healthcheck.d.ts.map +1 -1
- package/dist/cli/commands/healthcheck.mjs +3 -2
- package/dist/cli/commands/healthcheck.mjs.map +1 -1
- package/dist/cli/commands/index.d.ts +0 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.mjs +1 -2
- package/dist/cli/commands/migration.d.ts +2 -1
- package/dist/cli/commands/migration.d.ts.map +1 -1
- package/dist/cli/commands/migration.mjs +3 -2
- package/dist/cli/commands/migration.mjs.map +1 -1
- package/dist/cli/commands/start.d.ts +2 -1
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.mjs +3 -2
- package/dist/cli/commands/start.mjs.map +1 -1
- package/dist/cli/config.d.ts +18 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.mjs +34 -0
- package/dist/cli/config.mjs.map +1 -0
- package/dist/cli/module.d.ts +8 -8
- package/dist/cli/module.d.ts.map +1 -1
- package/dist/cli/module.mjs +8 -28
- package/dist/cli/module.mjs.map +1 -1
- package/dist/cli/types.d.ts +5 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.mjs +4 -0
- package/dist/components/event-cleaner/module.d.ts.map +1 -1
- package/dist/components/event-cleaner/module.mjs +26 -14
- package/dist/components/event-cleaner/module.mjs.map +1 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.mjs +1 -4
- package/dist/components/oauth2-cleaner/module.d.ts.map +1 -1
- package/dist/components/oauth2-cleaner/module.mjs +29 -17
- package/dist/components/oauth2-cleaner/module.mjs.map +1 -1
- package/dist/components/types.d.ts +1 -0
- package/dist/components/types.d.ts.map +1 -1
- package/dist/core/authentication/login-throttle/service.d.ts.map +1 -1
- package/dist/core/authentication/login-throttle/service.mjs +2 -1
- package/dist/core/authentication/login-throttle/service.mjs.map +1 -1
- package/dist/core/authentication/session/module.mjs +2 -4
- package/dist/core/authentication/session/module.mjs.map +1 -1
- package/dist/core/entities/client/constants.d.ts +10 -0
- package/dist/core/entities/client/constants.d.ts.map +1 -0
- package/dist/core/entities/client/constants.mjs +20 -0
- package/dist/core/entities/client/constants.mjs.map +1 -0
- package/dist/core/entities/client/index.d.ts +1 -0
- package/dist/core/entities/client/index.d.ts.map +1 -1
- package/dist/core/entities/client/index.mjs +3 -2
- package/dist/core/entities/client/schema.d.ts.map +1 -1
- package/dist/core/entities/client/schema.mjs +40 -3
- package/dist/core/entities/client/schema.mjs.map +1 -1
- package/dist/core/entities/client/service.d.ts.map +1 -1
- package/dist/core/entities/client/service.mjs +9 -61
- package/dist/core/entities/client/service.mjs.map +1 -1
- package/dist/core/entities/client/web-client.d.ts +39 -3
- package/dist/core/entities/client/web-client.d.ts.map +1 -1
- package/dist/core/entities/client/web-client.mjs +68 -12
- package/dist/core/entities/client/web-client.mjs.map +1 -1
- package/dist/core/entities/client-permission/service.mjs +12 -9
- package/dist/core/entities/client-permission/service.mjs.map +1 -1
- package/dist/core/entities/client-scope/schema.d.ts.map +1 -1
- package/dist/core/entities/client-scope/schema.mjs +3 -1
- package/dist/core/entities/client-scope/schema.mjs.map +1 -1
- package/dist/core/entities/event/constants.d.ts +7 -0
- package/dist/core/entities/event/constants.d.ts.map +1 -1
- package/dist/core/entities/event/constants.mjs +7 -1
- package/dist/core/entities/event/constants.mjs.map +1 -1
- package/dist/core/entities/event/index.mjs +2 -2
- package/dist/core/entities/event/service.mjs +1 -1
- package/dist/core/entities/event/service.mjs.map +1 -1
- package/dist/core/entities/index.mjs +4 -3
- package/dist/core/entities/key/service.mjs +4 -2
- package/dist/core/entities/key/service.mjs.map +1 -1
- package/dist/core/entities/permission/service.d.ts.map +1 -1
- package/dist/core/entities/permission/service.mjs +1 -1
- package/dist/core/entities/permission/service.mjs.map +1 -1
- package/dist/core/entities/policy/service.d.ts.map +1 -1
- package/dist/core/entities/policy/service.mjs +3 -2
- package/dist/core/entities/policy/service.mjs.map +1 -1
- package/dist/core/entities/realm/service.d.ts.map +1 -1
- package/dist/core/entities/realm/service.mjs +1 -1
- package/dist/core/entities/realm/service.mjs.map +1 -1
- package/dist/core/entities/role/schema.d.ts.map +1 -1
- package/dist/core/entities/role/schema.mjs +4 -0
- package/dist/core/entities/role/schema.mjs.map +1 -1
- package/dist/core/entities/role/service.d.ts.map +1 -1
- package/dist/core/entities/role/service.mjs +1 -1
- package/dist/core/entities/role/service.mjs.map +1 -1
- package/dist/core/entities/role-permission/service.mjs +12 -9
- package/dist/core/entities/role-permission/service.mjs.map +1 -1
- package/dist/core/entities/scope/service.d.ts.map +1 -1
- package/dist/core/entities/scope/service.mjs +1 -1
- package/dist/core/entities/scope/service.mjs.map +1 -1
- package/dist/core/entities/session/schema.d.ts.map +1 -1
- package/dist/core/entities/session/schema.mjs +2 -0
- package/dist/core/entities/session/schema.mjs.map +1 -1
- package/dist/core/entities/user/schema.d.ts.map +1 -1
- package/dist/core/entities/user/schema.mjs +2 -0
- package/dist/core/entities/user/schema.mjs.map +1 -1
- package/dist/core/entities/user/service.d.ts.map +1 -1
- package/dist/core/entities/user/service.mjs +1 -1
- package/dist/core/entities/user/service.mjs.map +1 -1
- package/dist/core/entities/user-authenticator/helpers.mjs +1 -1
- package/dist/core/entities/user-authenticator/helpers.mjs.map +1 -1
- package/dist/core/entities/user-authenticator/service.mjs +7 -7
- package/dist/core/entities/user-authenticator/service.mjs.map +1 -1
- package/dist/core/entities/user-permission/service.mjs +12 -9
- package/dist/core/entities/user-permission/service.mjs.map +1 -1
- package/dist/core/identity/password-recovery/check.mjs +4 -4
- package/dist/core/identity/password-recovery/check.mjs.map +1 -1
- package/dist/core/identity/password-recovery/service.mjs +1 -1
- package/dist/core/identity/password-recovery/service.mjs.map +1 -1
- package/dist/core/identity/registration/check.mjs +2 -2
- package/dist/core/identity/registration/check.mjs.map +1 -1
- package/dist/core/index.mjs +5 -3
- package/dist/core/key/check.mjs +2 -2
- package/dist/core/key/check.mjs.map +1 -1
- package/dist/core/provisioning/entities/client/relations-validator.d.ts.map +1 -1
- package/dist/core/provisioning/entities/client/relations-validator.mjs +2 -0
- package/dist/core/provisioning/entities/client/relations-validator.mjs.map +1 -1
- package/dist/core/provisioning/entities/client/types.d.ts +8 -0
- package/dist/core/provisioning/entities/client/types.d.ts.map +1 -1
- package/dist/core/provisioning/synchronizer/client/module.d.ts +3 -1
- package/dist/core/provisioning/synchronizer/client/module.d.ts.map +1 -1
- package/dist/core/provisioning/synchronizer/client/module.mjs +10 -1
- package/dist/core/provisioning/synchronizer/client/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/client/types.d.ts +3 -1
- package/dist/core/provisioning/synchronizer/client/types.d.ts.map +1 -1
- package/dist/core/provisioning/synchronizer/entity-resolver.d.ts +4 -1
- package/dist/core/provisioning/synchronizer/entity-resolver.d.ts.map +1 -1
- package/dist/core/provisioning/synchronizer/entity-resolver.mjs +14 -29
- package/dist/core/provisioning/synchronizer/entity-resolver.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/index.d.ts +1 -0
- package/dist/core/provisioning/synchronizer/index.d.ts.map +1 -1
- package/dist/core/provisioning/synchronizer/permission/module.mjs +0 -1
- package/dist/core/provisioning/synchronizer/permission/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/realm/module.d.ts.map +1 -1
- package/dist/core/provisioning/synchronizer/realm/module.mjs +8 -9
- package/dist/core/provisioning/synchronizer/realm/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/role/module.mjs +0 -1
- package/dist/core/provisioning/synchronizer/role/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/scope/module.mjs +0 -1
- package/dist/core/provisioning/synchronizer/scope/module.mjs.map +1 -1
- package/dist/core/provisioning/synchronizer/types.d.ts +11 -0
- package/dist/core/provisioning/synchronizer/types.d.ts.map +1 -0
- package/dist/core/provisioning/synchronizer/types.mjs +4 -0
- package/dist/core/provisioning/synchronizer/user/module.mjs +0 -1
- package/dist/core/provisioning/synchronizer/user/module.mjs.map +1 -1
- package/dist/core/query/describe.d.ts +25 -0
- package/dist/core/query/describe.d.ts.map +1 -0
- package/dist/core/query/describe.mjs +50 -0
- package/dist/core/query/describe.mjs.map +1 -0
- package/dist/core/query/fields.d.ts +44 -0
- package/dist/core/query/fields.d.ts.map +1 -0
- package/dist/core/query/fields.mjs +46 -0
- package/dist/core/query/fields.mjs.map +1 -0
- package/dist/core/query/index.d.ts +1 -0
- package/dist/core/query/index.d.ts.map +1 -1
- package/dist/core/query/index.mjs +2 -1
- package/dist/core/query/module.d.ts +1 -1
- package/dist/core/query/module.mjs +1 -1
- package/dist/core/query/module.mjs.map +1 -1
- package/dist/index.mjs +6 -2
- package/dist/path.mjs.map +1 -1
- package/dist/swagger.json +1324 -193
- package/dist/ui/client/.vite/ssr-manifest.json +1030 -760
- package/dist/ui/client/assets/index-BTK3GPZZ.js +106 -0
- package/dist/ui/client/assets/index-Cx_pI7BS.css +2 -0
- package/dist/ui/client/index.html +2 -2
- package/dist/ui/server/server.js +4465 -11501
- package/package.json +51 -50
- package/dist/cli/commands/reset.d.ts +0 -2
- package/dist/cli/commands/reset.d.ts.map +0 -1
- package/dist/cli/commands/reset.mjs +0 -23
- package/dist/cli/commands/reset.mjs.map +0 -1
- package/dist/components/database/index.d.ts +0 -2
- package/dist/components/database/index.d.ts.map +0 -1
- package/dist/components/database/index.mjs +0 -7
- package/dist/components/database/unique-entries/factory.d.ts +0 -4
- package/dist/components/database/unique-entries/factory.d.ts.map +0 -1
- package/dist/components/database/unique-entries/factory.mjs +0 -12
- package/dist/components/database/unique-entries/factory.mjs.map +0 -1
- package/dist/components/database/unique-entries/index.d.ts +0 -3
- package/dist/components/database/unique-entries/index.d.ts.map +0 -1
- package/dist/components/database/unique-entries/index.mjs +0 -6
- package/dist/components/database/unique-entries/module.d.ts +0 -15
- package/dist/components/database/unique-entries/module.d.ts.map +0 -1
- package/dist/components/database/unique-entries/module.mjs +0 -69
- package/dist/components/database/unique-entries/module.mjs.map +0 -1
- package/dist/ui/client/assets/index-C05uGFDe.js +0 -131
- package/dist/ui/client/assets/index-CiHrf73J.css +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","eq","inArray","EntityConflictError","EntityNotFoundError","ValidationError","isError","isRawError","EntityType","EventName","EventScope","KeyStatus","KeyValidator","PermissionName","ValidatorGroup","arrayBufferToBase64","base64ToArrayBuffer","createNanoID","AbstractEntityService","AsymmetricKey","createAsymmetricKeyPair","JWKType","JWKUse","JWTAlgorithm","getRandomValues","buildEntityDiff","assertCertificateMatchesKey","isWrappedKeyMaterial","parseCertificateChain","appendQueryConditions","decodeQuery","keySchema","PERMISSION_NAMES","KEY_READ","KEY_UPDATE","KEY_DELETE","KeyService","repository","validator","eventService","requestContext","ctx","getMany","query","actor","options","permissionEvaluator","preEvaluateOneOf","name","parsed","schema","realmId","compiled","compile","verdict","condition","data","entities","meta","findMany","entity","decryptionKey","total","evaluateOneOf","ATTRIBUTES","resourceRealmMatch","push","getOne","idOrName","findOneByIdOrName","create","preEvaluate","KEY_CREATE","validated","run","group","CREATE","use","validateJoinColumns","identity","actorRealmId","getActorRealmId","evaluate","checkUniqueness","priority","highest","findHighestPriority","status","ACTIVE","certificate","SIGNATURE","material","importMaterial","generateMaterial","encryptionKey","chain","e","message","type","signatureAlgorithm","save","recordEvent","CREATED","update","UPDATE","previous","pickAuditFields","merge","diff","UPDATED","Object","keys","length","delete","id","findOneBy","ENCRYPTION","force","references","countBlobReferences","entityId","remove","forcedCryptoShred","DELETED","undefined","record","scope","ENTITY","refType","KEY","refId","actorType","actorId","actorName","requestPath","requestMethod","requestIpAddress","requestUserAgent","raw","Uint8Array","OCT","buffer","algorithm","RS256","buildAsymmetricOptions","keyPair","startsWith","EC","RSA","privateKey","toBase64","publicKey","trim","normalizeMaterial","byteLength","privateJwk","publicJwk","fromBase64","format","key","toJWK","components","mismatch","some","component","test","buildImportOptionsForJWTAlgorithm","value","includes","replace"],"sources":["../../../../src/core/entities/key/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { eq, inArray } from '@rapiq/core';\nimport {\n EntityConflictError,\n EntityNotFoundError,\n ValidationError,\n isError as isRawError,\n} from '@authup/errors';\nimport type { Key } from '@authup/core-kit';\nimport {\n EntityType,\n EventName,\n EventScope,\n KeyStatus,\n KeyValidator,\n PermissionName,\n} from '@authup/core-kit';\nimport {\n ValidatorGroup,\n arrayBufferToBase64,\n base64ToArrayBuffer,\n createNanoID,\n} from '@authup/kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService, AsymmetricKey, createAsymmetricKeyPair } from '@authup/server-kit';\nimport { JWKType, JWKUse, JWTAlgorithm } from '@authup/specs';\nimport { getRandomValues } from 'uncrypto';\nimport { buildEntityDiff } from '../event/index.ts';\nimport type { EventRequestContext, IEventService } from '../event/index.ts';\nimport { assertCertificateMatchesKey, isWrappedKeyMaterial, parseCertificateChain } from '../../key/index.ts';\nimport type {\n IKeyRepository, \n IKeyService, \n KeyDeleteOptions, \n KeyServiceReadOptions,\n} from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { keySchema } from './schema.ts';\n\nexport type KeyServiceContext = {\n repository: IKeyRepository;\n eventService?: IEventService;\n requestContext?: () => EventRequestContext | undefined;\n};\n\nconst PERMISSION_NAMES = [\n PermissionName.KEY_READ,\n PermissionName.KEY_UPDATE,\n PermissionName.KEY_DELETE,\n];\n\nexport class KeyService extends AbstractEntityService implements IKeyService {\n protected repository: IKeyRepository;\n\n protected validator: KeyValidator;\n\n protected eventService?: IEventService;\n\n protected requestContext?: () => EventRequestContext | undefined;\n\n constructor(ctx: KeyServiceContext) {\n super();\n this.repository = ctx.repository;\n this.validator = new KeyValidator();\n this.eventService = ctx.eventService;\n this.requestContext = ctx.requestContext;\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n options: KeyServiceReadOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Key>> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n let parsed = await decodeQuery(query, { schema: keySchema, actor });\n if (options.realmId) {\n parsed = appendQueryConditions(parsed, eq('realmId', options.realmId));\n }\n\n // Compile the read permissions against the knowns (actor identity) into a\n // row condition (issue #3286 phase 3): the authorization runs as WHERE, so\n // pagination and totals stay exact. Non-expressible policies fall back to\n // the per-row post-evaluation below.\n const compiled = await actor.permissionEvaluator.compile({ name: PERMISSION_NAMES });\n if (compiled.verdict === 'deny') {\n // no row can pass — a constant-false condition keeps the meta shape\n parsed = appendQueryConditions(parsed, inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n parsed = appendQueryConditions(parsed, compiled.condition);\n }\n\n const { data: entities, meta } = await this.repository.findMany(parsed);\n\n if (compiled.verdict !== 'post') {\n for (const entity of entities) {\n // Belt-and-braces: the read projection never selects private\n // material, but null it explicitly so no future adapter change\n // can leak it onto a read surface (cf. authentik CVE-2024-42490).\n entity.decryptionKey = null;\n }\n\n return { data: entities, meta };\n }\n\n const data: Key[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n entity.decryptionKey = null;\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total,\n },\n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n // Belt-and-braces null of private material (see getMany).\n entity.decryptionKey = null;\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n const { use } = validated;\n if (!use) {\n throw new ValidationError('A key use must be specified.');\n }\n\n await this.repository.validateJoinColumns(validated);\n\n if (!validated.realmId && actor.identity) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realmId = actorRealmId;\n }\n }\n\n // keys are realm-bound infrastructure — no global (null realm) keys\n // via the API.\n if (!validated.realmId) {\n throw new ValidationError('A realm must be specified.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: validated,\n ...this.resourceRealmMatch(validated),\n }),\n });\n\n if (!validated.name) {\n validated.name = `${use}-${createNanoID(10)}`;\n }\n\n await this.repository.checkUniqueness(validated);\n\n if (typeof validated.priority !== 'number') {\n const highest = await this.repository.findHighestPriority(validated.realmId, use);\n // generate doubles as rotate: a new key outranks the current one.\n validated.priority = typeof highest === 'number' ? highest + 1 : 0;\n }\n\n if (!validated.status) {\n validated.status = KeyStatus.ACTIVE;\n }\n\n const certificate = typeof validated.certificate === 'string' ? validated.certificate : null;\n if (certificate && (!validated.decryptionKey || use !== JWKUse.SIGNATURE)) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n const material = validated.decryptionKey ?\n await this.importMaterial(validated, use) :\n await this.generateMaterial(validated, use);\n\n if (certificate) {\n if (!material.encryptionKey) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n try {\n const chain = parseCertificateChain(certificate);\n assertCertificateMatchesKey(chain, material.encryptionKey);\n } catch (e) {\n throw new ValidationError(\n isRawError(e) ?\n e.message :\n 'The certificate could not be matched against the imported key material.',\n );\n }\n }\n\n let entity = this.repository.create({\n ...validated,\n type: material.type,\n signatureAlgorithm: material.signatureAlgorithm,\n decryptionKey: material.decryptionKey,\n encryptionKey: material.encryptionKey,\n });\n\n entity = await this.repository.save(entity);\n\n // private material never leaves the server — the response carries\n // metadata + public part only (authentik CVE-2024-42490).\n entity.decryptionKey = null;\n\n await this.recordEvent(EventName.CREATED, entity, actor);\n\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_UPDATE });\n\n let entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // only name / priority / status are mounted for UPDATE — material,\n // use, type and realm are immutable.\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (validated.name && validated.name !== entity.name) {\n await this.repository.checkUniqueness({\n name: validated.name,\n realmId: entity.realmId,\n }, entity);\n }\n\n const previous = this.pickAuditFields(entity);\n\n entity = this.repository.merge(entity, validated);\n await this.repository.save(entity);\n\n entity.decryptionKey = null;\n\n const diff = buildEntityDiff(this.pickAuditFields(entity), previous);\n await this.recordEvent(EventName.UPDATED, entity, actor, { ...(Object.keys(diff).length > 0 ? { diff } : {}) });\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n options: KeyDeleteOptions = {},\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (entity.use === JWKUse.ENCRYPTION && !options.force) {\n const references = await this.repository.countBlobReferences(entity.id);\n if (references > 0) {\n throw new EntityConflictError({\n message: `The encryption key is still referenced by ${references} encrypted secret(s) — ` +\n 'deleting it makes them unrecoverable. Repeat with force to crypto-shred them.',\n data: { references },\n });\n }\n }\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n entity.decryptionKey = null;\n\n // force only carries crypto-shred semantics for encryption keys — a\n // sig-key delete with a stray force flag must not read as a shred.\n const forcedCryptoShred = entity.use === JWKUse.ENCRYPTION && !!options.force;\n await this.recordEvent(EventName.DELETED, entity, actor, { ...(forcedCryptoShred ? { force: true } : {}) });\n\n return entity;\n }\n\n // ------------------------------------------------------------------\n\n /**\n * Metadata-only audit trail for key lifecycle operations (issue #3269) —\n * keys deliberately have no entity subscriber (private material must stay\n * off the realtime/audit bus), so the security-relevant mutations are\n * recorded explicitly. The payload never carries key material.\n */\n protected async recordEvent(\n name: `${EventName}`,\n entity: Key,\n actor: ActorContext,\n data: Record<string, any> = {},\n ): Promise<void> {\n const requestContext = this.requestContext ?\n this.requestContext() :\n undefined;\n\n await this.eventService?.record({\n scope: EventScope.ENTITY,\n name,\n refType: EntityType.KEY,\n refId: entity.id,\n realmId: entity.realmId ?? null,\n actorType: actor.identity?.type ?? null,\n actorId: actor.identity?.data.id ?? null,\n actorName: actor.identity?.data.name ?? null,\n requestPath: requestContext?.requestPath ?? null,\n requestMethod: requestContext?.requestMethod ?? null,\n requestIpAddress: requestContext?.requestIpAddress ?? null,\n requestUserAgent: requestContext?.requestUserAgent ?? null,\n data: {\n name: entity.name,\n use: entity.use,\n status: entity.status,\n ...data,\n },\n });\n }\n\n protected pickAuditFields(entity: Key): Record<string, any> {\n return {\n name: entity.name,\n priority: entity.priority,\n status: entity.status,\n };\n }\n\n protected async generateMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n const raw = new Uint8Array(32);\n getRandomValues(raw);\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey: arrayBufferToBase64(raw.buffer),\n encryptionKey: null,\n };\n }\n\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n const keyPair = await createAsymmetricKeyPair(options);\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey: await new AsymmetricKey(keyPair.privateKey).toBase64(),\n encryptionKey: await new AsymmetricKey(keyPair.publicKey).toBase64(),\n };\n }\n\n protected async importMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (!validated.decryptionKey) {\n throw new ValidationError('Importing key material requires its private part (decryptionKey).');\n }\n\n // Reject material masquerading as an at-rest KEK-wrapped blob — it\n // would be treated as wrapped on the next read (and, with a KEK,\n // fail GCM authentication).\n if (isWrappedKeyMaterial(validated.decryptionKey.trim())) {\n throw new ValidationError('The imported key material is not valid.');\n }\n\n const decryptionKey = this.normalizeMaterial(validated.decryptionKey);\n\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n if (validated.encryptionKey) {\n throw new ValidationError('An encryption key holds no public part.');\n }\n\n let byteLength : number;\n try {\n byteLength = base64ToArrayBuffer(decryptionKey).byteLength;\n } catch {\n throw new ValidationError('The key material is not valid base64.');\n }\n\n if (byteLength !== 32) {\n throw new ValidationError('The key material must be 32 base64-encoded bytes.');\n }\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey,\n encryptionKey: null,\n };\n }\n\n if (!validated.encryptionKey) {\n throw new ValidationError('Importing a signature key requires its public part (encryptionKey, SPKI).');\n }\n\n const encryptionKey = this.normalizeMaterial(validated.encryptionKey);\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n let privateJwk : JsonWebKey;\n let publicJwk : JsonWebKey;\n\n try {\n const privateKey = await AsymmetricKey.fromBase64({\n format: 'pkcs8',\n key: decryptionKey,\n options,\n });\n const publicKey = await AsymmetricKey.fromBase64({\n format: 'spki',\n key: encryptionKey,\n options,\n });\n\n privateJwk = await privateKey.toJWK();\n publicJwk = await publicKey.toJWK();\n } catch {\n throw new ValidationError(`The key material could not be imported for ${algorithm}.`);\n }\n\n // the public components (RSA: n/e, EC: crv/x/y) must agree — a\n // private key paired with a foreign public part would publish a\n // wrong JWKS entry and break verification of every token it signs.\n const components : (keyof JsonWebKey)[] = ['kty', 'n', 'e', 'crv', 'x', 'y'];\n const mismatch = components.some(\n (component) => publicJwk[component] !== undefined &&\n publicJwk[component] !== privateJwk[component],\n );\n if (mismatch) {\n throw new ValidationError('The private and public key material do not form a pair.');\n }\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey,\n encryptionKey,\n };\n }\n\n protected buildAsymmetricOptions(algorithm: `${JWTAlgorithm}`) {\n if (!/^(RS|ES)(256|384|512)$/.test(algorithm)) {\n throw new ValidationError(`The signature algorithm ${algorithm} is not supported for stored keys.`);\n }\n\n return AsymmetricKey.buildImportOptionsForJWTAlgorithm(algorithm);\n }\n\n protected normalizeMaterial(value: string) : string {\n if (value.includes('-----BEGIN')) {\n // PEM body IS base64 DER — strip armor + whitespace.\n return value\n .replace(/-----(BEGIN|END)[^-]+-----/g, '')\n .replace(/\\s+/g, '');\n }\n\n return value.trim();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","eq","inArray","EntityConflictError","EntityNotFoundError","ValidationError","isError","isRawError","EntityType","EventName","EventScope","KeyStatus","KeyValidator","PermissionName","ValidatorGroup","arrayBufferToBase64","base64ToArrayBuffer","createNanoID","AbstractEntityService","AsymmetricKey","createAsymmetricKeyPair","JWKType","JWKUse","JWTAlgorithm","getRandomValues","buildEntityDiff","assertCertificateMatchesKey","isWrappedKeyMaterial","parseCertificateChain","appendQueryConditions","decodeQuery","keySchema","PERMISSION_NAMES","KEY_READ","KEY_UPDATE","KEY_DELETE","KeyService","repository","validator","eventService","requestContext","ctx","getMany","query","actor","options","permissionEvaluator","preEvaluateOneOf","name","parsed","schema","realmId","compiled","compile","verdict","condition","data","entities","meta","findMany","entity","decryptionKey","total","evaluateOneOf","ATTRIBUTES","resourceRealmMatch","push","getOne","idOrName","findOneByIdOrName","create","preEvaluate","KEY_CREATE","validated","run","group","CREATE","use","validateJoinColumns","identity","actorRealmId","getActorRealmId","evaluate","checkUniqueness","priority","highest","findHighestPriority","status","ACTIVE","certificate","SIGNATURE","material","importMaterial","generateMaterial","encryptionKey","chain","e","message","type","signatureAlgorithm","save","recordEvent","CREATED","update","UPDATE","previous","pickAuditFields","merge","diff","UPDATED","Object","keys","length","delete","id","findOneBy","ENCRYPTION","force","references","countBlobReferences","entityId","remove","forcedCryptoShred","DELETED","undefined","record","scope","ENTITY","refType","KEY","refId","actorType","actorId","actorName","requestPath","requestMethod","requestIpAddress","requestUserAgent","raw","Uint8Array","OCT","buffer","algorithm","RS256","buildAsymmetricOptions","keyPair","startsWith","EC","RSA","privateKey","toBase64","publicKey","trim","normalizeMaterial","byteLength","privateJwk","publicJwk","fromBase64","format","key","toJWK","components","mismatch","some","component","test","buildImportOptionsForJWTAlgorithm","value","includes","replace"],"sources":["../../../../src/core/entities/key/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { eq, inArray } from '@rapiq/core';\nimport {\n EntityConflictError,\n EntityNotFoundError,\n ValidationError,\n isError as isRawError,\n} from '@authup/errors';\nimport type { Key } from '@authup/core-kit';\nimport {\n EntityType,\n EventName,\n EventScope,\n KeyStatus,\n KeyValidator,\n PermissionName,\n} from '@authup/core-kit';\nimport {\n ValidatorGroup,\n arrayBufferToBase64,\n base64ToArrayBuffer,\n createNanoID,\n} from '@authup/kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService, AsymmetricKey, createAsymmetricKeyPair } from '@authup/server-kit';\nimport { JWKType, JWKUse, JWTAlgorithm } from '@authup/specs';\nimport { getRandomValues } from 'uncrypto';\nimport { buildEntityDiff } from '../event/index.ts';\nimport type { EventRequestContext, IEventService } from '../event/index.ts';\nimport { assertCertificateMatchesKey, isWrappedKeyMaterial, parseCertificateChain } from '../../key/index.ts';\nimport type {\n IKeyRepository, \n IKeyService, \n KeyDeleteOptions, \n KeyServiceReadOptions,\n} from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { keySchema } from './schema.ts';\n\nexport type KeyServiceContext = {\n repository: IKeyRepository;\n eventService?: IEventService;\n requestContext?: () => EventRequestContext | undefined;\n};\n\nconst PERMISSION_NAMES = [\n PermissionName.KEY_READ,\n PermissionName.KEY_UPDATE,\n PermissionName.KEY_DELETE,\n];\n\nexport class KeyService extends AbstractEntityService implements IKeyService {\n protected repository: IKeyRepository;\n\n protected validator: KeyValidator;\n\n protected eventService?: IEventService;\n\n protected requestContext?: () => EventRequestContext | undefined;\n\n constructor(ctx: KeyServiceContext) {\n super();\n this.repository = ctx.repository;\n this.validator = new KeyValidator();\n this.eventService = ctx.eventService;\n this.requestContext = ctx.requestContext;\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n options: KeyServiceReadOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Key>> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n let parsed = await decodeQuery(query, { schema: keySchema, actor });\n if (options.realmId) {\n parsed = appendQueryConditions(parsed, eq('realmId', options.realmId));\n }\n\n // Compile the read permissions against the knowns (actor identity) into a\n // row condition (issue #3286 phase 3): the authorization runs as WHERE, so\n // pagination and totals stay exact. Non-expressible policies fall back to\n // the per-row post-evaluation below.\n const compiled = await actor.permissionEvaluator.compile({ name: PERMISSION_NAMES });\n if (compiled.verdict === 'deny') {\n // no row can pass — a constant-false condition keeps the meta shape\n parsed = appendQueryConditions(parsed, inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n parsed = appendQueryConditions(parsed, compiled.condition);\n }\n\n const { data: entities, meta } = await this.repository.findMany(parsed);\n\n if (compiled.verdict !== 'post') {\n for (const entity of entities) {\n // Belt-and-braces: the read projection never selects private\n // material, but null it explicitly so no future adapter change\n // can leak it onto a read surface (cf. authentik CVE-2024-42490).\n entity.decryptionKey = null;\n }\n\n return { data: entities, meta };\n }\n\n const data: Key[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n entity.decryptionKey = null;\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total,\n },\n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n // Belt-and-braces null of private material (see getMany).\n entity.decryptionKey = null;\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n const { use } = validated;\n if (!use) {\n throw new ValidationError('A key use must be specified.');\n }\n\n await this.repository.validateJoinColumns(validated);\n\n if (!validated.realmId && actor.identity) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realmId = actorRealmId;\n }\n }\n\n // keys are realm-bound infrastructure — no global (null realm) keys\n // via the API.\n if (!validated.realmId) {\n throw new ValidationError('A realm must be specified.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: validated,\n ...this.resourceRealmMatch(validated),\n }),\n });\n\n if (!validated.name) {\n validated.name = `${use}-${createNanoID(10)}`;\n }\n\n await this.repository.checkUniqueness(validated);\n\n if (typeof validated.priority !== 'number') {\n const highest = await this.repository.findHighestPriority(validated.realmId, use);\n // generate doubles as rotate: a new key outranks the current one.\n validated.priority = typeof highest === 'number' ? highest + 1 : 0;\n }\n\n if (!validated.status) {\n validated.status = KeyStatus.ACTIVE;\n }\n\n const certificate = typeof validated.certificate === 'string' ? validated.certificate : null;\n if (certificate && (!validated.decryptionKey || use !== JWKUse.SIGNATURE)) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n const material = validated.decryptionKey ?\n await this.importMaterial(validated, use) :\n await this.generateMaterial(validated, use);\n\n if (certificate) {\n if (!material.encryptionKey) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n try {\n const chain = parseCertificateChain(certificate);\n assertCertificateMatchesKey(chain, material.encryptionKey);\n } catch (e) {\n throw new ValidationError(\n isRawError(e) ?\n e.message :\n 'The certificate could not be matched against the imported key material.',\n );\n }\n }\n\n let entity = this.repository.create({\n ...validated,\n type: material.type,\n signatureAlgorithm: material.signatureAlgorithm,\n decryptionKey: material.decryptionKey,\n encryptionKey: material.encryptionKey,\n });\n\n entity = await this.repository.save(entity);\n\n // private material never leaves the server — the response carries\n // metadata + public part only (authentik CVE-2024-42490).\n entity.decryptionKey = null;\n\n await this.recordEvent(EventName.CREATED, entity, actor);\n\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_UPDATE });\n\n let entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // only name / priority / status are mounted for UPDATE — material,\n // use, type and realm are immutable.\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (validated.name && validated.name !== entity.name) {\n await this.repository.checkUniqueness({\n name: validated.name,\n realmId: entity.realmId,\n }, entity);\n }\n\n const previous = this.pickAuditFields(entity);\n\n entity = this.repository.merge(entity, validated);\n await this.repository.save(entity);\n\n entity.decryptionKey = null;\n\n const diff = buildEntityDiff(this.pickAuditFields(entity), previous);\n await this.recordEvent(EventName.UPDATED, entity, actor, { ...(Object.keys(diff).length > 0 ? { diff } : {}) });\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n options: KeyDeleteOptions = {},\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (entity.use === JWKUse.ENCRYPTION && !options.force) {\n const references = await this.repository.countBlobReferences(entity.id);\n if (references > 0) {\n throw new EntityConflictError({\n message: `The encryption key is still referenced by ${references} encrypted secret(s) — ` +\n 'deleting it makes them unrecoverable. Repeat with force to crypto-shred them.',\n data: { references },\n });\n }\n }\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n entity.decryptionKey = null;\n\n // force only carries crypto-shred semantics for encryption keys — a\n // sig-key delete with a stray force flag must not read as a shred.\n const forcedCryptoShred = entity.use === JWKUse.ENCRYPTION && !!options.force;\n await this.recordEvent(EventName.DELETED, entity, actor, { ...(forcedCryptoShred ? { force: true } : {}) });\n\n return entity;\n }\n\n // ------------------------------------------------------------------\n\n /**\n * Metadata-only audit trail for key lifecycle operations (issue #3269) —\n * keys deliberately have no entity subscriber (private material must stay\n * off the realtime/audit bus), so the security-relevant mutations are\n * recorded explicitly. The payload never carries key material.\n */\n protected async recordEvent(\n name: `${EventName}`,\n entity: Key,\n actor: ActorContext,\n data: Record<string, any> = {},\n ): Promise<void> {\n const requestContext = this.requestContext ?\n this.requestContext() :\n undefined;\n\n await this.eventService?.record({\n scope: EventScope.ENTITY,\n name,\n refType: EntityType.KEY,\n refId: entity.id,\n realmId: entity.realmId ?? null,\n actorType: actor.identity?.type ?? null,\n actorId: actor.identity?.data.id ?? null,\n actorName: actor.identity?.data.name ?? null,\n requestPath: requestContext?.requestPath ?? null,\n requestMethod: requestContext?.requestMethod ?? null,\n requestIpAddress: requestContext?.requestIpAddress ?? null,\n requestUserAgent: requestContext?.requestUserAgent ?? null,\n data: {\n name: entity.name,\n use: entity.use,\n status: entity.status,\n ...data,\n },\n });\n }\n\n protected pickAuditFields(entity: Key): Record<string, any> {\n return {\n name: entity.name,\n priority: entity.priority,\n status: entity.status,\n };\n }\n\n protected async generateMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n const raw = new Uint8Array(32);\n getRandomValues(raw);\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey: arrayBufferToBase64(raw.buffer),\n encryptionKey: null,\n };\n }\n\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n const keyPair = await createAsymmetricKeyPair(options);\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey: await new AsymmetricKey(keyPair.privateKey).toBase64(),\n encryptionKey: await new AsymmetricKey(keyPair.publicKey).toBase64(),\n };\n }\n\n protected async importMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (!validated.decryptionKey) {\n throw new ValidationError('Importing key material requires its private part (decryptionKey).');\n }\n\n // Reject material masquerading as an at-rest KEK-wrapped blob — it\n // would be treated as wrapped on the next read (and, with a KEK,\n // fail GCM authentication).\n if (isWrappedKeyMaterial(validated.decryptionKey.trim())) {\n throw new ValidationError('The imported key material is not valid.');\n }\n\n const decryptionKey = this.normalizeMaterial(validated.decryptionKey);\n\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n if (validated.encryptionKey) {\n throw new ValidationError('An encryption key holds no public part.');\n }\n\n let byteLength : number;\n try {\n byteLength = base64ToArrayBuffer(decryptionKey).byteLength;\n } catch {\n throw new ValidationError('The key material is not valid base64.');\n }\n\n if (byteLength !== 32) {\n throw new ValidationError('The key material must be 32 base64-encoded bytes.');\n }\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey,\n encryptionKey: null,\n };\n }\n\n if (!validated.encryptionKey) {\n throw new ValidationError('Importing a signature key requires its public part (encryptionKey, SPKI).');\n }\n\n const encryptionKey = this.normalizeMaterial(validated.encryptionKey);\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n let privateJwk : JsonWebKey;\n let publicJwk : JsonWebKey;\n\n try {\n const privateKey = await AsymmetricKey.fromBase64({\n format: 'pkcs8',\n key: decryptionKey,\n options,\n });\n const publicKey = await AsymmetricKey.fromBase64({\n format: 'spki',\n key: encryptionKey,\n options,\n });\n\n privateJwk = await privateKey.toJWK();\n publicJwk = await publicKey.toJWK();\n } catch {\n throw new ValidationError(`The key material could not be imported for ${algorithm}.`);\n }\n\n // the public components (RSA: n/e, EC: crv/x/y) must agree — a\n // private key paired with a foreign public part would publish a\n // wrong JWKS entry and break verification of every token it signs.\n const components : (keyof JsonWebKey)[] = ['kty', 'n', 'e', 'crv', 'x', 'y'];\n const mismatch = components.some(\n (component) => publicJwk[component] !== undefined &&\n publicJwk[component] !== privateJwk[component],\n );\n if (mismatch) {\n throw new ValidationError('The private and public key material do not form a pair.');\n }\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey,\n encryptionKey,\n };\n }\n\n protected buildAsymmetricOptions(algorithm: `${JWTAlgorithm}`) {\n if (!/^(RS|ES)(256|384|512)$/.test(algorithm)) {\n throw new ValidationError(`The signature algorithm ${algorithm} is not supported for stored keys.`);\n }\n\n return AsymmetricKey.buildImportOptionsForJWTAlgorithm(algorithm);\n }\n\n protected normalizeMaterial(value: string) : string {\n if (value.includes('-----BEGIN')) {\n // PEM body IS base64 DER — strip armor + whitespace.\n return value\n .replace(/-----(BEGIN|END)[^-]+-----/g, '')\n .replace(/\\s+/g, '');\n }\n\n return value.trim();\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/permission/service.ts"],"names":[],"mappings":"AAeA,OAAO,EAEH,mBAAmB,EAGtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAyC5E,MAAM,MAAM,wBAAwB,GAAG;IACnC,UAAU,EAAE,qBAAqB,CAAC;IAClC,eAAe,EAAE,gBAAgB,CAAC;IAClC,cAAc,EAAE,eAAe,CAAC;IAChC,wBAAwB,EAAE,yBAAyB,CAAC;IACpD,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,0BAA0B,EAAE,2BAA2B,CAAC;CAC3D,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,qBAAsB,YAAW,kBAAkB;IACtF,SAAS,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAE5C,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,cAAc,EAAE,eAAe,CAAC;IAE1C,SAAS,CAAC,wBAAwB,EAAE,yBAAyB,CAAC;IAE9D,SAAS,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;IAE9C,SAAS,CAAC,0BAA0B,EAAE,2BAA2B,CAAC;IAElE,SAAS,CAAC,SAAS,EAAE,mBAAmB,CAAC;gBAE7B,GAAG,EAAE,wBAAwB;IAWnC,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC;IAYhD,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC;IAiBhB,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAKhB,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAKhB,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,UAAU,CAAC;QACnB,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/permission/service.ts"],"names":[],"mappings":"AAeA,OAAO,EAEH,mBAAmB,EAGtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAyC5E,MAAM,MAAM,wBAAwB,GAAG;IACnC,UAAU,EAAE,qBAAqB,CAAC;IAClC,eAAe,EAAE,gBAAgB,CAAC;IAClC,cAAc,EAAE,eAAe,CAAC;IAChC,wBAAwB,EAAE,yBAAyB,CAAC;IACpD,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,0BAA0B,EAAE,2BAA2B,CAAC;CAC3D,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,qBAAsB,YAAW,kBAAkB;IACtF,SAAS,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAE5C,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,cAAc,EAAE,eAAe,CAAC;IAE1C,SAAS,CAAC,wBAAwB,EAAE,yBAAyB,CAAC;IAE9D,SAAS,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;IAE9C,SAAS,CAAC,0BAA0B,EAAE,2BAA2B,CAAC;IAElE,SAAS,CAAC,SAAS,EAAE,mBAAmB,CAAC;gBAE7B,GAAG,EAAE,wBAAwB;IAWnC,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC;IAYhD,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC;IAiBhB,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAKhB,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAKhB,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,UAAU,CAAC;QACnB,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAqHI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAwBtB;;;;OAIG;YACW,mBAAmB;IAuBjC;;;;;;;;OAQG;YACW,iBAAiB;IAyB/B;;;;;;;;;;;;;;OAcG;YACW,uBAAuB;CAuCxC"}
|
|
@@ -101,7 +101,7 @@ var PermissionService = class extends AbstractEntityService {
|
|
|
101
101
|
else where.name = idOrName;
|
|
102
102
|
if (realm) where.realmId = realm.id;
|
|
103
103
|
entity = await this.repository.findOneBy(where);
|
|
104
|
-
if (!entity && options.updateOnly) throw new EntityNotFoundError();
|
|
104
|
+
if (!entity && (options.updateOnly || where.id)) throw new EntityNotFoundError();
|
|
105
105
|
} else if (options.updateOnly) throw new EntityNotFoundError();
|
|
106
106
|
if (entity) {
|
|
107
107
|
await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","RealmScope","SystemPolicyName","definePolicyData","ValidatorGroup","isPropertySet","isUUID","AuthupError","EntityNotFoundError","ValidationError","PermissionName","PermissionValidator","ROLE_ADMIN_NAME","ROLE_REALM_ADMIN_NAME","AbstractEntityService","decodeQuery","permissionSchema","REALM_ADMIN_EXCLUDED_PERMISSIONS","REALM_CREATE","REALM_UPDATE","REALM_DELETE","REALM_ADMIN_BOUND_PERMISSIONS","CLIENT_CREATE","CLIENT_UPDATE","CLIENT_DELETE","IDENTITY_PROVIDER_CREATE","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","PERMISSION_CREATE","PERMISSION_UPDATE","PERMISSION_DELETE","ROLE_CREATE","ROLE_UPDATE","ROLE_DELETE","SCOPE_CREATE","SCOPE_UPDATE","SCOPE_DELETE","USER_CREATE","USER_UPDATE","USER_DELETE","PermissionService","repository","realmRepository","roleRepository","rolePermissionRepository","policyRepository","permissionPolicyRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","PERMISSION_READ","findMany","schema","getOne","idOrName","realm","entity","findOneByIdOrName","create","data","save","undefined","update","updateOnly","options","group","realmId","resolve","where","id","findOneBy","preEvaluate","UPDATE","CREATE","validated","run","validateJoinColumns","builtIn","evaluate","ATTRIBUTES","REALM_MATCH","checkUniqueness","merge","created","identity","getActorRealmId","resourceRealmMatch","assignToAdminRole","assignToRealmAdminRoles","assignDefaultPolicy","e","remove","catch","delete","entityId","permission","defaultPolicy","findOneByName","DEFAULT","existing","permissionId","policyId","entry","permissionRealmId","policyRealmId","adminRole","roleId","roleRealmId","realmScope","ANY","includes","isBuiltIn","Object","values","OWN","OWN_OR_NULL","realmAdminRoles","findManyBy","role"],"sources":["../../../../src/core/entities/permission/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 BuiltInPolicyType, \n RealmScope, \n SystemPolicyName, \n definePolicyData, \n} from '@authup/access';\nimport { ValidatorGroup, isPropertySet, isUUID } from '@authup/kit';\nimport { AuthupError, EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n PermissionValidator,\n ROLE_ADMIN_NAME,\n ROLE_REALM_ADMIN_NAME,\n} from '@authup/core-kit';\nimport type { Permission } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IPermissionPolicyRepository } from '../permission-policy/types.ts';\nimport type { IPolicyRepository } from '../policy/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport type { IRoleRepository } from '../role/types.ts';\nimport type { IRolePermissionRepository } from '../role-permission/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IPermissionRepository, IPermissionService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { permissionSchema } from './schema.ts';\n\nconst REALM_ADMIN_EXCLUDED_PERMISSIONS = [\n PermissionName.REALM_CREATE,\n PermissionName.REALM_UPDATE,\n PermissionName.REALM_DELETE,\n];\n\n/**\n * Direct-entity CUD permissions that realm_admin grants at `realmScope: own`\n * (strictly the actor's own realm — see line 372). Every other realm_admin\n * permission defaults to `ownOrNull` (own realm OR global/null resources) so it\n * can act on global building blocks.\n *\n * Junction CUD (e.g. user_role, role_permission) is intentionally NOT listed here:\n * it stays `ownOrNull` because a junction can legitimately reference a global\n * side (realmId: null) — a strict `own` would reject those.\n */\nconst REALM_ADMIN_BOUND_PERMISSIONS = [\n PermissionName.CLIENT_CREATE,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n PermissionName.IDENTITY_PROVIDER_CREATE,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n PermissionName.PERMISSION_CREATE,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n PermissionName.ROLE_CREATE,\n PermissionName.ROLE_UPDATE,\n PermissionName.ROLE_DELETE,\n PermissionName.SCOPE_CREATE,\n PermissionName.SCOPE_UPDATE,\n PermissionName.SCOPE_DELETE,\n PermissionName.USER_CREATE,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n];\n\nexport type PermissionServiceContext = {\n repository: IPermissionRepository;\n realmRepository: IRealmRepository;\n roleRepository: IRoleRepository;\n rolePermissionRepository: IRolePermissionRepository;\n policyRepository: IPolicyRepository;\n permissionPolicyRepository: IPermissionPolicyRepository;\n};\n\nexport class PermissionService extends AbstractEntityService implements IPermissionService {\n protected repository: IPermissionRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected roleRepository: IRoleRepository;\n\n protected rolePermissionRepository: IRolePermissionRepository;\n\n protected policyRepository: IPolicyRepository;\n\n protected permissionPolicyRepository: IPermissionPolicyRepository;\n\n protected validator: PermissionValidator;\n\n constructor(ctx: PermissionServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.roleRepository = ctx.roleRepository;\n this.rolePermissionRepository = ctx.rolePermissionRepository;\n this.policyRepository = ctx.policyRepository;\n this.permissionPolicyRepository = ctx.permissionPolicyRepository;\n this.validator = new PermissionValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Permission>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: permissionSchema, actor }));\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realm?: string,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realm);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Permission,\n created: boolean\n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: Permission | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n if (entity) {\n if (\n entity.builtIn &&\n isPropertySet(validated, 'name') &&\n entity.name !== validated.name\n ) {\n throw new ValidationError('The name of a built-in permission can not be changed.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n\n await this.repository.checkUniqueness(validated, entity);\n\n entity = this.repository.merge(entity, validated);\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false,\n };\n }\n\n if (!isPropertySet(validated, 'realmId') && actor.identity) {\n validated.realmId = this.getActorRealmId(actor) || null;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n\n await this.repository.checkUniqueness(validated);\n\n entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n // The permission row is now committed, but its security wiring — the\n // admin/realm_admin grants and the system.default binding — is written\n // through separate repositories with no shared transaction. A failure\n // partway through would strand the permission bound by system.default\n // yet held by nobody, which the uniform member gate on\n // POST /role-permissions then makes permanently un-grantable (#3303).\n // Two safeguards:\n // 1. Establish the grants BEFORE binding system.default, so even an\n // un-compensated interruption (a hard process crash) cannot produce\n // the bound-but-ungranted strand — at worst a benign, still-grantable\n // permission that lacks its baseline policy.\n // 2. On any thrown failure, remove the just-created permission — its\n // CASCADE foreign keys drop any partial junction/binding rows — and\n // rethrow so the caller sees the failure instead of a stale record.\n try {\n await this.assignToAdminRole(entity);\n await this.assignToRealmAdminRoles(entity);\n await this.assignDefaultPolicy(entity);\n } catch (e) {\n await this.repository.remove(entity).catch(() => { /* best-effort rollback */ });\n throw e;\n }\n\n return {\n entity,\n created: true,\n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in permission can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n\n /**\n * Assign the system.default policy to a newly created permission.\n * This ensures all permissions are evaluated with the baseline security\n * policy (identity, permission-binding, realm-match) by default.\n */\n private async assignDefaultPolicy(permission: Permission): Promise<void> {\n const defaultPolicy = await this.policyRepository.findOneByName(SystemPolicyName.DEFAULT);\n if (!defaultPolicy) {\n throw new AuthupError(`The ${SystemPolicyName.DEFAULT} policy is not provisioned. Cannot create permissions without the default security policy.`);\n }\n\n const existing = await this.permissionPolicyRepository.findOneBy({\n permissionId: permission.id,\n policyId: defaultPolicy.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.permissionPolicyRepository.create({\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n policyId: defaultPolicy.id,\n policyRealmId: defaultPolicy.realmId,\n });\n await this.permissionPolicyRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to the global admin role.\n * The admin role receives every permission without policy restrictions.\n *\n * Throws when the admin role is not provisioned: without an admin grant the\n * permission is bound by `system.default` yet held by nobody, and the uniform\n * member gate on junction creation makes it permanently un-grantable (even by\n * admin). Fail loud so the stranded state is surfaced instead of swallowed.\n */\n private async assignToAdminRole(permission: Permission): Promise<void> {\n const adminRole = await this.roleRepository.findOneByName(ROLE_ADMIN_NAME);\n if (!adminRole) {\n throw new AuthupError(`The ${ROLE_ADMIN_NAME} role is not provisioned. Cannot grant the created permission to the administrator role.`);\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: adminRole.id,\n permissionId: permission.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: adminRole.id,\n roleRealmId: adminRole.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n // Global admin: unrestricted realm reach.\n realmScope: RealmScope.ANY,\n });\n await this.rolePermissionRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to all matching realm_admin roles.\n *\n * Uses differentiated realmScope on the junction:\n * - CUD on global-capable entity types → own (strictly own realm)\n * - Everything else → ownOrNull (own realm + null/global resources)\n *\n * Eligible permissions:\n * - Built-in authup permissions (global) — assigned to all realm_admin roles\n * - Realm-scoped permissions — assigned to the realm_admin in the matching realm\n *\n * Excluded:\n * - Realm CRUD permissions (realm_create, realm_update, realm_delete)\n * - Custom global permissions (non-built-in with realmId: null)\n */\n private async assignToRealmAdminRoles(permission: Permission): Promise<void> {\n if (REALM_ADMIN_EXCLUDED_PERMISSIONS.includes(permission.name as PermissionName)) {\n return;\n }\n\n const isBuiltIn = (Object.values(PermissionName) as string[]).includes(permission.name);\n if (!permission.realmId && !isBuiltIn) {\n return;\n }\n\n const realmScope = REALM_ADMIN_BOUND_PERMISSIONS.includes(permission.name as PermissionName) ?\n RealmScope.OWN :\n RealmScope.OWN_OR_NULL;\n\n const realmAdminRoles = await this.roleRepository.findManyBy({ name: ROLE_REALM_ADMIN_NAME });\n\n for (const role of realmAdminRoles) {\n if (permission.realmId && permission.realmId !== role.realmId) {\n continue;\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: role.id,\n permissionId: permission.id,\n });\n if (existing) {\n continue;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: role.id,\n roleRealmId: role.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n realmScope,\n });\n await this.rolePermissionRepository.save(entry);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","RealmScope","SystemPolicyName","definePolicyData","ValidatorGroup","isPropertySet","isUUID","AuthupError","EntityNotFoundError","ValidationError","PermissionName","PermissionValidator","ROLE_ADMIN_NAME","ROLE_REALM_ADMIN_NAME","AbstractEntityService","decodeQuery","permissionSchema","REALM_ADMIN_EXCLUDED_PERMISSIONS","REALM_CREATE","REALM_UPDATE","REALM_DELETE","REALM_ADMIN_BOUND_PERMISSIONS","CLIENT_CREATE","CLIENT_UPDATE","CLIENT_DELETE","IDENTITY_PROVIDER_CREATE","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","PERMISSION_CREATE","PERMISSION_UPDATE","PERMISSION_DELETE","ROLE_CREATE","ROLE_UPDATE","ROLE_DELETE","SCOPE_CREATE","SCOPE_UPDATE","SCOPE_DELETE","USER_CREATE","USER_UPDATE","USER_DELETE","PermissionService","repository","realmRepository","roleRepository","rolePermissionRepository","policyRepository","permissionPolicyRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","PERMISSION_READ","findMany","schema","getOne","idOrName","realm","entity","findOneByIdOrName","create","data","save","undefined","update","updateOnly","options","group","realmId","resolve","where","id","findOneBy","preEvaluate","UPDATE","CREATE","validated","run","validateJoinColumns","builtIn","evaluate","ATTRIBUTES","REALM_MATCH","checkUniqueness","merge","created","identity","getActorRealmId","resourceRealmMatch","assignToAdminRole","assignToRealmAdminRoles","assignDefaultPolicy","e","remove","catch","delete","entityId","permission","defaultPolicy","findOneByName","DEFAULT","existing","permissionId","policyId","entry","permissionRealmId","policyRealmId","adminRole","roleId","roleRealmId","realmScope","ANY","includes","isBuiltIn","Object","values","OWN","OWN_OR_NULL","realmAdminRoles","findManyBy","role"],"sources":["../../../../src/core/entities/permission/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 BuiltInPolicyType, \n RealmScope, \n SystemPolicyName, \n definePolicyData, \n} from '@authup/access';\nimport { ValidatorGroup, isPropertySet, isUUID } from '@authup/kit';\nimport { AuthupError, EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n PermissionValidator,\n ROLE_ADMIN_NAME,\n ROLE_REALM_ADMIN_NAME,\n} from '@authup/core-kit';\nimport type { Permission } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IPermissionPolicyRepository } from '../permission-policy/types.ts';\nimport type { IPolicyRepository } from '../policy/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport type { IRoleRepository } from '../role/types.ts';\nimport type { IRolePermissionRepository } from '../role-permission/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IPermissionRepository, IPermissionService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { permissionSchema } from './schema.ts';\n\nconst REALM_ADMIN_EXCLUDED_PERMISSIONS = [\n PermissionName.REALM_CREATE,\n PermissionName.REALM_UPDATE,\n PermissionName.REALM_DELETE,\n];\n\n/**\n * Direct-entity CUD permissions that realm_admin grants at `realmScope: own`\n * (strictly the actor's own realm — see line 372). Every other realm_admin\n * permission defaults to `ownOrNull` (own realm OR global/null resources) so it\n * can act on global building blocks.\n *\n * Junction CUD (e.g. user_role, role_permission) is intentionally NOT listed here:\n * it stays `ownOrNull` because a junction can legitimately reference a global\n * side (realmId: null) — a strict `own` would reject those.\n */\nconst REALM_ADMIN_BOUND_PERMISSIONS = [\n PermissionName.CLIENT_CREATE,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n PermissionName.IDENTITY_PROVIDER_CREATE,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n PermissionName.PERMISSION_CREATE,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n PermissionName.ROLE_CREATE,\n PermissionName.ROLE_UPDATE,\n PermissionName.ROLE_DELETE,\n PermissionName.SCOPE_CREATE,\n PermissionName.SCOPE_UPDATE,\n PermissionName.SCOPE_DELETE,\n PermissionName.USER_CREATE,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n];\n\nexport type PermissionServiceContext = {\n repository: IPermissionRepository;\n realmRepository: IRealmRepository;\n roleRepository: IRoleRepository;\n rolePermissionRepository: IRolePermissionRepository;\n policyRepository: IPolicyRepository;\n permissionPolicyRepository: IPermissionPolicyRepository;\n};\n\nexport class PermissionService extends AbstractEntityService implements IPermissionService {\n protected repository: IPermissionRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected roleRepository: IRoleRepository;\n\n protected rolePermissionRepository: IRolePermissionRepository;\n\n protected policyRepository: IPolicyRepository;\n\n protected permissionPolicyRepository: IPermissionPolicyRepository;\n\n protected validator: PermissionValidator;\n\n constructor(ctx: PermissionServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.roleRepository = ctx.roleRepository;\n this.rolePermissionRepository = ctx.rolePermissionRepository;\n this.policyRepository = ctx.policyRepository;\n this.permissionPolicyRepository = ctx.permissionPolicyRepository;\n this.validator = new PermissionValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Permission>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: permissionSchema, actor }));\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realm?: string,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realm);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Permission,\n created: boolean\n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: Permission | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n // Only a NAME key may upsert-create. A UUID addresses one specific\n // row, so a miss is a 404 (creating would write a different id).\n if (!entity && (options.updateOnly || where.id)) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n if (entity) {\n if (\n entity.builtIn &&\n isPropertySet(validated, 'name') &&\n entity.name !== validated.name\n ) {\n throw new ValidationError('The name of a built-in permission can not be changed.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n\n await this.repository.checkUniqueness(validated, entity);\n\n entity = this.repository.merge(entity, validated);\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false,\n };\n }\n\n if (!isPropertySet(validated, 'realmId') && actor.identity) {\n validated.realmId = this.getActorRealmId(actor) || null;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n\n await this.repository.checkUniqueness(validated);\n\n entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n // The permission row is now committed, but its security wiring — the\n // admin/realm_admin grants and the system.default binding — is written\n // through separate repositories with no shared transaction. A failure\n // partway through would strand the permission bound by system.default\n // yet held by nobody, which the uniform member gate on\n // POST /role-permissions then makes permanently un-grantable (#3303).\n // Two safeguards:\n // 1. Establish the grants BEFORE binding system.default, so even an\n // un-compensated interruption (a hard process crash) cannot produce\n // the bound-but-ungranted strand — at worst a benign, still-grantable\n // permission that lacks its baseline policy.\n // 2. On any thrown failure, remove the just-created permission — its\n // CASCADE foreign keys drop any partial junction/binding rows — and\n // rethrow so the caller sees the failure instead of a stale record.\n try {\n await this.assignToAdminRole(entity);\n await this.assignToRealmAdminRoles(entity);\n await this.assignDefaultPolicy(entity);\n } catch (e) {\n await this.repository.remove(entity).catch(() => { /* best-effort rollback */ });\n throw e;\n }\n\n return {\n entity,\n created: true,\n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in permission can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n\n /**\n * Assign the system.default policy to a newly created permission.\n * This ensures all permissions are evaluated with the baseline security\n * policy (identity, permission-binding, realm-match) by default.\n */\n private async assignDefaultPolicy(permission: Permission): Promise<void> {\n const defaultPolicy = await this.policyRepository.findOneByName(SystemPolicyName.DEFAULT);\n if (!defaultPolicy) {\n throw new AuthupError(`The ${SystemPolicyName.DEFAULT} policy is not provisioned. Cannot create permissions without the default security policy.`);\n }\n\n const existing = await this.permissionPolicyRepository.findOneBy({\n permissionId: permission.id,\n policyId: defaultPolicy.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.permissionPolicyRepository.create({\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n policyId: defaultPolicy.id,\n policyRealmId: defaultPolicy.realmId,\n });\n await this.permissionPolicyRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to the global admin role.\n * The admin role receives every permission without policy restrictions.\n *\n * Throws when the admin role is not provisioned: without an admin grant the\n * permission is bound by `system.default` yet held by nobody, and the uniform\n * member gate on junction creation makes it permanently un-grantable (even by\n * admin). Fail loud so the stranded state is surfaced instead of swallowed.\n */\n private async assignToAdminRole(permission: Permission): Promise<void> {\n const adminRole = await this.roleRepository.findOneByName(ROLE_ADMIN_NAME);\n if (!adminRole) {\n throw new AuthupError(`The ${ROLE_ADMIN_NAME} role is not provisioned. Cannot grant the created permission to the administrator role.`);\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: adminRole.id,\n permissionId: permission.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: adminRole.id,\n roleRealmId: adminRole.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n // Global admin: unrestricted realm reach.\n realmScope: RealmScope.ANY,\n });\n await this.rolePermissionRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to all matching realm_admin roles.\n *\n * Uses differentiated realmScope on the junction:\n * - CUD on global-capable entity types → own (strictly own realm)\n * - Everything else → ownOrNull (own realm + null/global resources)\n *\n * Eligible permissions:\n * - Built-in authup permissions (global) — assigned to all realm_admin roles\n * - Realm-scoped permissions — assigned to the realm_admin in the matching realm\n *\n * Excluded:\n * - Realm CRUD permissions (realm_create, realm_update, realm_delete)\n * - Custom global permissions (non-built-in with realmId: null)\n */\n private async assignToRealmAdminRoles(permission: Permission): Promise<void> {\n if (REALM_ADMIN_EXCLUDED_PERMISSIONS.includes(permission.name as PermissionName)) {\n return;\n }\n\n const isBuiltIn = (Object.values(PermissionName) as string[]).includes(permission.name);\n if (!permission.realmId && !isBuiltIn) {\n return;\n }\n\n const realmScope = REALM_ADMIN_BOUND_PERMISSIONS.includes(permission.name as PermissionName) ?\n RealmScope.OWN :\n RealmScope.OWN_OR_NULL;\n\n const realmAdminRoles = await this.roleRepository.findManyBy({ name: ROLE_REALM_ADMIN_NAME });\n\n for (const role of realmAdminRoles) {\n if (permission.realmId && permission.realmId !== role.realmId) {\n continue;\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: role.id,\n permissionId: permission.id,\n });\n if (existing) {\n continue;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: role.id,\n roleRealmId: role.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n realmScope,\n });\n await this.rolePermissionRepository.save(entry);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/policy/service.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEH,eAAe,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIpE,MAAM,MAAM,oBAAoB,GAAG;IAC/B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,aAAc,SAAQ,qBAAsB,YAAW,cAAc;IAC9E,SAAS,CAAC,UAAU,EAAE,iBAAiB,CAAC;IAExC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,eAAe,CAAC;IAErC,SAAS,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;gBAE7C,GAAG,EAAE,oBAAoB;IAQ/B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAY5C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAiBZ,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;IAKZ,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;IAKZ,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/policy/service.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEH,eAAe,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIpE,MAAM,MAAM,oBAAoB,GAAG;IAC/B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,aAAc,SAAQ,qBAAsB,YAAW,cAAc;IAC9E,SAAS,CAAC,UAAU,EAAE,iBAAiB,CAAC;IAExC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,eAAe,CAAC;IAErC,SAAS,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;gBAE7C,GAAG,EAAE,oBAAoB;IAQ/B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAY5C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAiBZ,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;IAKZ,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;IAKZ,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;YAiGY,QAAQ;IAqBhB,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;CA4BrB"}
|
|
@@ -62,7 +62,7 @@ var PolicyService = class extends AbstractEntityService {
|
|
|
62
62
|
else where.name = idOrName;
|
|
63
63
|
if (realm) where.realmId = realm.id;
|
|
64
64
|
entity = await this.repository.findOneBy(where);
|
|
65
|
-
if (!entity && options.updateOnly) throw new EntityNotFoundError();
|
|
65
|
+
if (!entity && (options.updateOnly || where.id)) throw new EntityNotFoundError();
|
|
66
66
|
} else if (options.updateOnly) throw new EntityNotFoundError();
|
|
67
67
|
if (entity) {
|
|
68
68
|
await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });
|
|
@@ -112,7 +112,8 @@ var PolicyService = class extends AbstractEntityService {
|
|
|
112
112
|
}
|
|
113
113
|
async validate(data, group) {
|
|
114
114
|
const validated = await this.validator.run(data, { group });
|
|
115
|
-
|
|
115
|
+
const attributes = await this.attributesValidator.run(data);
|
|
116
|
+
extendObject(validated, attributes);
|
|
116
117
|
if (Array.isArray(data.children)) {
|
|
117
118
|
if (data.type === BuiltInPolicyType.COMPOSITE) {
|
|
118
119
|
const promises = data.children.map((child) => this.validate(child, group));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","ValidatorGroup","extendObject","isPropertySet","isUUID","removeObjectProperty","EntityNotFoundError","ValidationError","PermissionName","PolicyValidator","AbstractEntityService","PolicyAttributesValidator","decodeQuery","policySchema","PolicyService","repository","realmRepository","validator","attributesValidator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","PERMISSION_READ","PERMISSION_UPDATE","PERMISSION_DELETE","findMany","schema","getOne","idOrName","realm","entity","findOneByIdOrName","create","data","save","undefined","update","updateOnly","options","group","realmId","resolve","where","id","findOneBy","preEvaluate","UPDATE","PERMISSION_CREATE","CREATE","validated","validate","validateJoinColumns","parent","type","COMPOSITE","builtIn","evaluate","ATTRIBUTES","REALM_MATCH","checkUniqueness","saveWithEA","created","identity","getActorRealmId","resourceRealmMatch","run","attributes","Array","isArray","children","promises","map","child","Promise","all","delete","entityId","deleteFromTree"],"sources":["../../../../src/core/entities/policy/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 { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport {\n ValidatorGroup,\n extendObject,\n isPropertySet,\n isUUID,\n removeObjectProperty,\n} from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n PolicyValidator,\n} from '@authup/core-kit';\nimport type { Policy } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport { PolicyAttributesValidator } from './attributes-validator.ts';\nimport type { IPolicyRepository, IPolicyService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { policySchema } from './schema.ts';\n\nexport type PolicyServiceContext = {\n repository: IPolicyRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class PolicyService extends AbstractEntityService implements IPolicyService {\n protected repository: IPolicyRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: PolicyValidator;\n\n protected attributesValidator: PolicyAttributesValidator;\n\n constructor(ctx: PolicyServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new PolicyValidator();\n this.attributesValidator = new PolicyAttributesValidator({});\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Policy>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: policySchema, actor }));\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realm?: string,\n ): Promise<Policy> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realm);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Policy> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Policy> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Policy,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: Policy | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validate(data, group);\n\n await this.repository.validateJoinColumns(validated);\n\n if (\n validated.parent &&\n validated.parent.type !== BuiltInPolicyType.COMPOSITE\n ) {\n throw new ValidationError('The parent policy must be of type group.');\n }\n\n if (entity) {\n if (entity.builtIn) {\n throw new ValidationError('A built-in policy can not be updated.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n\n await this.repository.checkUniqueness(validated, entity);\n\n extendObject(entity, validated);\n\n await this.repository.saveWithEA(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!isPropertySet(validated, 'realmId') && actor.identity) {\n validated.realmId = this.getActorRealmId(actor) || null;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n\n await this.repository.checkUniqueness(validated);\n\n entity = this.repository.create(validated);\n await this.repository.saveWithEA(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n private async validate(\n data: Record<string, any>,\n group: string,\n ): Promise<Policy> {\n const validated = await this.validator.run(data, { group });\n\n const attributes = await this.attributesValidator.run(data);\n extendObject(validated, attributes);\n\n if (Array.isArray(data.children)) {\n if (data.type === BuiltInPolicyType.COMPOSITE) {\n const promises = data.children.map(\n (child) => this.validate(child, group),\n );\n validated.children = await Promise.all(promises);\n }\n }\n\n return validated;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Policy> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in policy can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n\n await this.repository.deleteFromTree(entity);\n\n entity.id = entityId;\n\n // todo: remove after PolicyEntity - parent delete on cascade\n removeObjectProperty(entity, 'children');\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","ValidatorGroup","extendObject","isPropertySet","isUUID","removeObjectProperty","EntityNotFoundError","ValidationError","PermissionName","PolicyValidator","AbstractEntityService","PolicyAttributesValidator","decodeQuery","policySchema","PolicyService","repository","realmRepository","validator","attributesValidator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","PERMISSION_READ","PERMISSION_UPDATE","PERMISSION_DELETE","findMany","schema","getOne","idOrName","realm","entity","findOneByIdOrName","create","data","save","undefined","update","updateOnly","options","group","realmId","resolve","where","id","findOneBy","preEvaluate","UPDATE","PERMISSION_CREATE","CREATE","validated","validate","validateJoinColumns","parent","type","COMPOSITE","builtIn","evaluate","ATTRIBUTES","REALM_MATCH","checkUniqueness","saveWithEA","created","identity","getActorRealmId","resourceRealmMatch","run","attributes","Array","isArray","children","promises","map","child","Promise","all","delete","entityId","deleteFromTree"],"sources":["../../../../src/core/entities/policy/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 { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport {\n ValidatorGroup,\n extendObject,\n isPropertySet,\n isUUID,\n removeObjectProperty,\n} from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n PolicyValidator,\n} from '@authup/core-kit';\nimport type { Policy } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport { PolicyAttributesValidator } from './attributes-validator.ts';\nimport type { IPolicyRepository, IPolicyService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { policySchema } from './schema.ts';\n\nexport type PolicyServiceContext = {\n repository: IPolicyRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class PolicyService extends AbstractEntityService implements IPolicyService {\n protected repository: IPolicyRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: PolicyValidator;\n\n protected attributesValidator: PolicyAttributesValidator;\n\n constructor(ctx: PolicyServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new PolicyValidator();\n this.attributesValidator = new PolicyAttributesValidator({});\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Policy>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: policySchema, actor }));\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realm?: string,\n ): Promise<Policy> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realm);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Policy> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Policy> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Policy,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: Policy | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n // Only a NAME key may upsert-create. A UUID addresses one specific\n // row, so a miss is a 404 (creating would write a different id).\n if (!entity && (options.updateOnly || where.id)) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validate(data, group);\n\n await this.repository.validateJoinColumns(validated);\n\n if (\n validated.parent &&\n validated.parent.type !== BuiltInPolicyType.COMPOSITE\n ) {\n throw new ValidationError('The parent policy must be of type group.');\n }\n\n if (entity) {\n if (entity.builtIn) {\n throw new ValidationError('A built-in policy can not be updated.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n\n await this.repository.checkUniqueness(validated, entity);\n\n extendObject(entity, validated);\n\n await this.repository.saveWithEA(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!isPropertySet(validated, 'realmId') && actor.identity) {\n validated.realmId = this.getActorRealmId(actor) || null;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n\n await this.repository.checkUniqueness(validated);\n\n entity = this.repository.create(validated);\n await this.repository.saveWithEA(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n private async validate(\n data: Record<string, any>,\n group: string,\n ): Promise<Policy> {\n const validated = await this.validator.run(data, { group });\n\n const attributes = await this.attributesValidator.run(data);\n extendObject(validated, attributes);\n\n if (Array.isArray(data.children)) {\n if (data.type === BuiltInPolicyType.COMPOSITE) {\n const promises = data.children.map(\n (child) => this.validate(child, group),\n );\n validated.children = await Promise.all(promises);\n }\n }\n\n return validated;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Policy> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in policy can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n\n await this.repository.deleteFromTree(entity);\n\n entity.id = entityId;\n\n // todo: remove after PolicyEntity - parent delete on cascade\n removeObjectProperty(entity, 'children');\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/realm/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,cAAc,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,MAAM,EAAG,MAAM,oBAAoB,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIlE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAC7C,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,YAAa,SAAQ,qBAAsB,YAAW,aAAa;IAC5E,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEvC,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC;IAEpC,SAAS,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAEvD,SAAS,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;IAE3C,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEd,GAAG,EAAE,mBAAmB;IAS9B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAI3C,MAAM,CACR,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,KAAK,CAAC;IASX,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;IAKX,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;IAKX,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/realm/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,cAAc,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,MAAM,EAAG,MAAM,oBAAoB,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIlE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAC7C,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,YAAa,SAAQ,qBAAsB,YAAW,aAAa;IAC5E,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEvC,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC;IAEpC,SAAS,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAEvD,SAAS,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;IAE3C,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEd,GAAG,EAAE,mBAAmB;IAS9B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAI3C,MAAM,CACR,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,KAAK,CAAC;IASX,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;IAKX,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;IAKX,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAgGI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;CAuBpB"}
|
|
@@ -48,7 +48,7 @@ var RealmService = class extends AbstractEntityService {
|
|
|
48
48
|
if (isUUID(idOrName)) where.id = idOrName;
|
|
49
49
|
else where.name = idOrName;
|
|
50
50
|
entity = await this.repository.findOneBy(where);
|
|
51
|
-
if (!entity && options.updateOnly) throw new EntityNotFoundError();
|
|
51
|
+
if (!entity && (options.updateOnly || where.id)) throw new EntityNotFoundError();
|
|
52
52
|
} else if (options.updateOnly) throw new EntityNotFoundError();
|
|
53
53
|
if (entity) {
|
|
54
54
|
await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_UPDATE });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","ValidatorGroup","isPropertySet","isUUID","EntityNotFoundError","ValidationError","PermissionName","REALM_MASTER_NAME","RealmValidator","AbstractEntityService","decodeQuery","realmSchema","RealmService","repository","validator","webClientProvisioner","keyProvisioner","logger","ctx","getMany","query","findMany","schema","getOne","idOrName","entity","findOneByIdOrName","create","data","actor","save","undefined","update","updateOnly","options","group","where","id","name","findOneBy","permissionEvaluator","preEvaluate","REALM_UPDATE","UPDATE","REALM_CREATE","CREATE","validated","run","validateJoinColumns","evaluate","ATTRIBUTES","merge","created","ensureForRealm","e","warn","Error","message","String","delete","REALM_DELETE","builtIn","entityId","remove"],"sources":["../../../../src/core/entities/realm/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 { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { ValidatorGroup, isPropertySet, isUUID } from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n REALM_MASTER_NAME,\n RealmValidator,\n} from '@authup/core-kit';\nimport type { Realm } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, Logger } from '@authup/server-kit';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IWebClientProvisioner } from '../client/types.ts';\nimport type { IKeyProvisioner } from '../../key/types.ts';\nimport type { IRealmRepository, IRealmService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { realmSchema } from './schema.ts';\n\nexport type RealmServiceContext = {\n repository: IRealmRepository;\n webClientProvisioner?: IWebClientProvisioner;\n keyProvisioner?: IKeyProvisioner;\n logger?: Logger;\n};\n\nexport class RealmService extends AbstractEntityService implements IRealmService {\n protected repository: IRealmRepository;\n\n protected validator: RealmValidator;\n\n protected webClientProvisioner?: IWebClientProvisioner;\n\n protected keyProvisioner?: IKeyProvisioner;\n\n protected logger?: Logger;\n\n constructor(ctx: RealmServiceContext) {\n super();\n this.repository = ctx.repository;\n this.webClientProvisioner = ctx.webClientProvisioner;\n this.keyProvisioner = ctx.keyProvisioner;\n this.logger = ctx.logger;\n this.validator = new RealmValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n ): Promise<EntityRepositoryFindManyResult<Realm>> {\n return this.repository.findMany(await decodeQuery(query, { schema: realmSchema }));\n }\n\n async getOne(\n idOrName: string,\n ): Promise<Realm> {\n const entity = await this.repository.findOneByIdOrName(idOrName);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Realm> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Realm> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Realm,\n created: boolean \n }> {\n let group: string;\n\n let entity: Realm | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n if (entity) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.REALM_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n }),\n });\n\n if (entity.name === REALM_MASTER_NAME && isPropertySet(validated, 'name') && entity.name !== validated.name) {\n throw new ValidationError(`The name of the ${REALM_MASTER_NAME} can not be changed.`);\n }\n\n entity = this.repository.merge(entity, validated);\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.REALM_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n entity = this.repository.create(validated);\n await this.repository.save(entity);\n\n // Provision the realm's public `web` client via the system-level\n // provisioner (NOT clientService.create) — it must not be gated on\n // the actor's CLIENT_CREATE, since a realm creator may lack it.\n // Realm creation must stay atomic from the caller's perspective: the\n // realm is already persisted, so a provisioning failure is logged and\n // swallowed (startup provisioning reconciles every realm's web client).\n if (this.webClientProvisioner) {\n try {\n await this.webClientProvisioner.ensureForRealm(entity);\n } catch (e) {\n if (this.logger) {\n this.logger.warn(\n `Failed to provision web client for realm ${entity.id}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n }\n }\n\n // Mint the realm's sig + enc keys eagerly (plan 071 hybrid model) —\n // same system-level, never-fail posture as the web client above.\n if (this.keyProvisioner) {\n await this.keyProvisioner.ensureForRealm(entity);\n }\n\n return {\n entity,\n created: true,\n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Realm> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in realm can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.REALM_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","ValidatorGroup","isPropertySet","isUUID","EntityNotFoundError","ValidationError","PermissionName","REALM_MASTER_NAME","RealmValidator","AbstractEntityService","decodeQuery","realmSchema","RealmService","repository","validator","webClientProvisioner","keyProvisioner","logger","ctx","getMany","query","findMany","schema","getOne","idOrName","entity","findOneByIdOrName","create","data","actor","save","undefined","update","updateOnly","options","group","where","id","name","findOneBy","permissionEvaluator","preEvaluate","REALM_UPDATE","UPDATE","REALM_CREATE","CREATE","validated","run","validateJoinColumns","evaluate","ATTRIBUTES","merge","created","ensureForRealm","e","warn","Error","message","String","delete","REALM_DELETE","builtIn","entityId","remove"],"sources":["../../../../src/core/entities/realm/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 { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { ValidatorGroup, isPropertySet, isUUID } from '@authup/kit';\nimport { EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n REALM_MASTER_NAME,\n RealmValidator,\n} from '@authup/core-kit';\nimport type { Realm } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, Logger } from '@authup/server-kit';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IWebClientProvisioner } from '../client/types.ts';\nimport type { IKeyProvisioner } from '../../key/types.ts';\nimport type { IRealmRepository, IRealmService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { realmSchema } from './schema.ts';\n\nexport type RealmServiceContext = {\n repository: IRealmRepository;\n webClientProvisioner?: IWebClientProvisioner;\n keyProvisioner?: IKeyProvisioner;\n logger?: Logger;\n};\n\nexport class RealmService extends AbstractEntityService implements IRealmService {\n protected repository: IRealmRepository;\n\n protected validator: RealmValidator;\n\n protected webClientProvisioner?: IWebClientProvisioner;\n\n protected keyProvisioner?: IKeyProvisioner;\n\n protected logger?: Logger;\n\n constructor(ctx: RealmServiceContext) {\n super();\n this.repository = ctx.repository;\n this.webClientProvisioner = ctx.webClientProvisioner;\n this.keyProvisioner = ctx.keyProvisioner;\n this.logger = ctx.logger;\n this.validator = new RealmValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n ): Promise<EntityRepositoryFindManyResult<Realm>> {\n return this.repository.findMany(await decodeQuery(query, { schema: realmSchema }));\n }\n\n async getOne(\n idOrName: string,\n ): Promise<Realm> {\n const entity = await this.repository.findOneByIdOrName(idOrName);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Realm> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Realm> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Realm,\n created: boolean \n }> {\n let group: string;\n\n let entity: Realm | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n entity = await this.repository.findOneBy(where);\n // Only a NAME key may upsert-create. A UUID addresses one specific\n // row, so a miss is a 404 (creating would write a different id).\n if (!entity && (options.updateOnly || where.id)) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n if (entity) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.REALM_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n }),\n });\n\n if (entity.name === REALM_MASTER_NAME && isPropertySet(validated, 'name') && entity.name !== validated.name) {\n throw new ValidationError(`The name of the ${REALM_MASTER_NAME} can not be changed.`);\n }\n\n entity = this.repository.merge(entity, validated);\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.REALM_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n entity = this.repository.create(validated);\n await this.repository.save(entity);\n\n // Provision the realm's public `web` client via the system-level\n // provisioner (NOT clientService.create) — it must not be gated on\n // the actor's CLIENT_CREATE, since a realm creator may lack it.\n // Realm creation must stay atomic from the caller's perspective: the\n // realm is already persisted, so a provisioning failure is logged and\n // swallowed (startup provisioning reconciles every realm's web client).\n if (this.webClientProvisioner) {\n try {\n await this.webClientProvisioner.ensureForRealm(entity);\n } catch (e) {\n if (this.logger) {\n this.logger.warn(\n `Failed to provision web client for realm ${entity.id}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n }\n }\n\n // Mint the realm's sig + enc keys eagerly (plan 071 hybrid model) —\n // same system-level, never-fail posture as the web client above.\n if (this.keyProvisioner) {\n await this.keyProvisioner.ensureForRealm(entity);\n }\n\n return {\n entity,\n created: true,\n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Realm> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.REALM_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in realm can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.REALM_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/role/schema.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM7C,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/role/schema.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM7C,eAAO,MAAM,UAAU,yCAqBrB,CAAC"}
|
|
@@ -10,18 +10,22 @@ const roleSchema = defineSchema({
|
|
|
10
10
|
name: EntityType.ROLE,
|
|
11
11
|
fields: { allowed: [
|
|
12
12
|
"id",
|
|
13
|
+
"builtIn",
|
|
13
14
|
"name",
|
|
14
15
|
"displayName",
|
|
15
16
|
"target",
|
|
16
17
|
"description",
|
|
18
|
+
"clientId",
|
|
17
19
|
"realmId",
|
|
18
20
|
"createdAt",
|
|
19
21
|
"updatedAt"
|
|
20
22
|
] },
|
|
21
23
|
filters: { allowed: [
|
|
22
24
|
"id",
|
|
25
|
+
"builtIn",
|
|
23
26
|
"name",
|
|
24
27
|
"target",
|
|
28
|
+
"clientId",
|
|
25
29
|
"realmId"
|
|
26
30
|
] },
|
|
27
31
|
relations: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","roleSchema","name","ROLE","fields","allowed","filters","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/role/schema.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 { defineSchema } from '@rapiq/core';\nimport type { Role } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const roleSchema = defineSchema<Role>({\n name: EntityType.ROLE,\n fields: {\n allowed: [\n 'id',\n 'name',\n 'displayName',\n 'target',\n 'description',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['id', 'name', 'target', 'realmId'] },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'name', 'updatedAt', 'createdAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,aAAaN,aAAmB;CACzCO,MAAMN,WAAWO;CACjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EAAED,SAAS;EAAC;EAAM;EAAQ;EAAU;CAAU,EAAC;
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","roleSchema","name","ROLE","fields","allowed","filters","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/role/schema.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 { defineSchema } from '@rapiq/core';\nimport type { Role } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const roleSchema = defineSchema<Role>({\n name: EntityType.ROLE,\n fields: {\n allowed: [\n 'id',\n 'builtIn',\n 'name',\n 'displayName',\n 'target',\n 'description',\n 'clientId',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['id', 'builtIn', 'name', 'target', 'clientId', 'realmId'] },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'name', 'updatedAt', 'createdAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,aAAaN,aAAmB;CACzCO,MAAMN,WAAWO;CACjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EAAED,SAAS;EAAC;EAAM;EAAW;EAAQ;EAAU;EAAY;CAAU,EAAC;CAC/EE,WAAW;EAAEF,SAAS,CAAC,OAAQ;EAAEG,UAAUX,wBAAwBC,aAAAA;CAAe;CAClFW,MAAM,EAAEJ,SAAS;EAAC;EAAM;EAAQ;EAAa;CAAY,EAAC;CAC1DK,YAAY,EAAEC,UAAU,GAAG;CAC3Bb;AACJ,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/role/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,aAAa,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIhE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,YAAY;IAC1E,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;gBAEvB,GAAG,EAAE,kBAAkB;IAO7B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;IAY1C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAiBV,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/role/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,aAAa,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIhE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,YAAY;IAC1E,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;gBAEvB,GAAG,EAAE,kBAAkB;IAO7B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;IAY1C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAiBV,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAoFI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;CAuBnB"}
|
|
@@ -59,7 +59,7 @@ var RoleService = class extends AbstractEntityService {
|
|
|
59
59
|
else where.name = idOrName;
|
|
60
60
|
if (realm) where.realmId = realm.id;
|
|
61
61
|
entity = await this.repository.findOneBy(where);
|
|
62
|
-
if (!entity && options.updateOnly) throw new EntityNotFoundError();
|
|
62
|
+
if (!entity && (options.updateOnly || where.id)) throw new EntityNotFoundError();
|
|
63
63
|
} else if (options.updateOnly) throw new EntityNotFoundError();
|
|
64
64
|
if (entity) {
|
|
65
65
|
await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROLE_UPDATE });
|