@authup/server-core 1.0.0-beta.50 → 1.0.0-beta.51

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.
Files changed (230) hide show
  1. package/dist/adapters/database/domains/client-permission/entity.d.ts +2 -1
  2. package/dist/adapters/database/domains/client-permission/entity.d.ts.map +1 -1
  3. package/dist/adapters/database/domains/client-permission/entity.mjs +6 -0
  4. package/dist/adapters/database/domains/client-permission/entity.mjs.map +1 -1
  5. package/dist/adapters/database/domains/robot-permission/entity.d.ts +2 -1
  6. package/dist/adapters/database/domains/robot-permission/entity.d.ts.map +1 -1
  7. package/dist/adapters/database/domains/robot-permission/entity.mjs +6 -0
  8. package/dist/adapters/database/domains/robot-permission/entity.mjs.map +1 -1
  9. package/dist/adapters/database/domains/robot-role/entity.mjs +1 -1
  10. package/dist/adapters/database/domains/robot-role/entity.mjs.map +1 -1
  11. package/dist/adapters/database/domains/role-permission/entity.d.ts +2 -1
  12. package/dist/adapters/database/domains/role-permission/entity.d.ts.map +1 -1
  13. package/dist/adapters/database/domains/role-permission/entity.mjs +6 -0
  14. package/dist/adapters/database/domains/role-permission/entity.mjs.map +1 -1
  15. package/dist/adapters/database/domains/user-permission/entity.d.ts +2 -1
  16. package/dist/adapters/database/domains/user-permission/entity.d.ts.map +1 -1
  17. package/dist/adapters/database/domains/user-permission/entity.mjs +6 -0
  18. package/dist/adapters/database/domains/user-permission/entity.mjs.map +1 -1
  19. package/dist/adapters/database/migrations/mysql/1779300000000-Default.d.ts +7 -0
  20. package/dist/adapters/database/migrations/mysql/1779300000000-Default.d.ts.map +1 -0
  21. package/dist/adapters/database/migrations/mysql/1779300000000-Default.mjs +85 -0
  22. package/dist/adapters/database/migrations/mysql/1779300000000-Default.mjs.map +1 -0
  23. package/dist/adapters/database/migrations/postgres/1779300000000-Default.d.ts +7 -0
  24. package/dist/adapters/database/migrations/postgres/1779300000000-Default.d.ts.map +1 -0
  25. package/dist/adapters/database/migrations/postgres/1779300000000-Default.mjs +87 -0
  26. package/dist/adapters/database/migrations/postgres/1779300000000-Default.mjs.map +1 -0
  27. package/dist/adapters/http/adapters/index.mjs +2 -2
  28. package/dist/adapters/http/adapters/oauth2/grant-types/index.mjs +2 -2
  29. package/dist/adapters/http/adapters/oauth2/grant-types/password.d.ts +2 -1
  30. package/dist/adapters/http/adapters/oauth2/grant-types/password.d.ts.map +1 -1
  31. package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs +12 -4
  32. package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs.map +1 -1
  33. package/dist/adapters/http/adapters/oauth2/grant-types/types.d.ts +2 -1
  34. package/dist/adapters/http/adapters/oauth2/grant-types/types.d.ts.map +1 -1
  35. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.d.ts +1 -0
  36. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.d.ts.map +1 -1
  37. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs +1 -1
  38. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs.map +1 -1
  39. package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.mjs +2 -2
  40. package/dist/adapters/http/adapters/oauth2/index.mjs +2 -2
  41. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
  42. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +24 -9
  43. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  44. package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
  45. package/dist/adapters/http/controllers/workflows/token/module.mjs +2 -1
  46. package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
  47. package/dist/adapters/http/controllers/workflows/token/types.d.ts +2 -1
  48. package/dist/adapters/http/controllers/workflows/token/types.d.ts.map +1 -1
  49. package/dist/adapters/http/index.mjs +3 -3
  50. package/dist/adapters/http/request/helpers/identity.d.ts +0 -1
  51. package/dist/adapters/http/request/helpers/identity.d.ts.map +1 -1
  52. package/dist/adapters/http/request/helpers/identity.mjs +2 -5
  53. package/dist/adapters/http/request/helpers/identity.mjs.map +1 -1
  54. package/dist/adapters/http/request/helpers/index.mjs +2 -2
  55. package/dist/adapters/http/request/index.mjs +2 -2
  56. package/dist/adapters/http/request/permission/module.mjs +2 -2
  57. package/dist/adapters/http/request/permission/module.mjs.map +1 -1
  58. package/dist/app/modules/database/repositories/bindings.d.ts +2 -0
  59. package/dist/app/modules/database/repositories/bindings.d.ts.map +1 -1
  60. package/dist/app/modules/database/repositories/bindings.mjs +3 -1
  61. package/dist/app/modules/database/repositories/bindings.mjs.map +1 -1
  62. package/dist/app/modules/database/repositories/identity-provider/repository.d.ts.map +1 -1
  63. package/dist/app/modules/database/repositories/identity-provider/repository.mjs +4 -2
  64. package/dist/app/modules/database/repositories/identity-provider/repository.mjs.map +1 -1
  65. package/dist/app/modules/database/repositories/permission-provider/module.d.ts +2 -2
  66. package/dist/app/modules/database/repositories/permission-provider/module.d.ts.map +1 -1
  67. package/dist/app/modules/database/repositories/permission-provider/module.mjs +4 -3
  68. package/dist/app/modules/database/repositories/permission-provider/module.mjs.map +1 -1
  69. package/dist/app/modules/database/repositories/realm/repository.d.ts.map +1 -1
  70. package/dist/app/modules/database/repositories/realm/repository.mjs +6 -2
  71. package/dist/app/modules/database/repositories/realm/repository.mjs.map +1 -1
  72. package/dist/app/modules/http/modules/controller.d.ts +2 -0
  73. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  74. package/dist/app/modules/http/modules/controller.mjs +18 -0
  75. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  76. package/dist/app/modules/identity/repositories/client.mjs +2 -2
  77. package/dist/app/modules/identity/repositories/client.mjs.map +1 -1
  78. package/dist/app/modules/identity/repositories/robot.mjs +2 -2
  79. package/dist/app/modules/identity/repositories/robot.mjs.map +1 -1
  80. package/dist/app/modules/identity/repositories/user.mjs +2 -2
  81. package/dist/app/modules/identity/repositories/user.mjs.map +1 -1
  82. package/dist/app/modules/oauth2/repositories/client/repository.mjs +2 -2
  83. package/dist/app/modules/oauth2/repositories/client/repository.mjs.map +1 -1
  84. package/dist/app/modules/provisioning/module.d.ts.map +1 -1
  85. package/dist/app/modules/provisioning/module.mjs +0 -1
  86. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  87. package/dist/app/modules/provisioning/sources/default/module.d.ts.map +1 -1
  88. package/dist/app/modules/provisioning/sources/default/module.mjs +14 -56
  89. package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
  90. package/dist/core/entities/client/service.mjs +25 -7
  91. package/dist/core/entities/client/service.mjs.map +1 -1
  92. package/dist/core/entities/client-permission/service.d.ts +7 -4
  93. package/dist/core/entities/client-permission/service.d.ts.map +1 -1
  94. package/dist/core/entities/client-permission/service.mjs +59 -19
  95. package/dist/core/entities/client-permission/service.mjs.map +1 -1
  96. package/dist/core/entities/client-role/service.d.ts +3 -2
  97. package/dist/core/entities/client-role/service.d.ts.map +1 -1
  98. package/dist/core/entities/client-role/service.mjs +12 -5
  99. package/dist/core/entities/client-role/service.mjs.map +1 -1
  100. package/dist/core/entities/client-scope/service.d.ts +3 -2
  101. package/dist/core/entities/client-scope/service.d.ts.map +1 -1
  102. package/dist/core/entities/client-scope/service.mjs +12 -5
  103. package/dist/core/entities/client-scope/service.mjs.map +1 -1
  104. package/dist/core/entities/identity-provider-role-mapping/service.d.ts +7 -4
  105. package/dist/core/entities/identity-provider-role-mapping/service.d.ts.map +1 -1
  106. package/dist/core/entities/identity-provider-role-mapping/service.mjs +29 -6
  107. package/dist/core/entities/identity-provider-role-mapping/service.mjs.map +1 -1
  108. package/dist/core/entities/permission/service.d.ts +3 -5
  109. package/dist/core/entities/permission/service.d.ts.map +1 -1
  110. package/dist/core/entities/permission/service.mjs +30 -24
  111. package/dist/core/entities/permission/service.mjs.map +1 -1
  112. package/dist/core/entities/permission-policy/service.d.ts +3 -2
  113. package/dist/core/entities/permission-policy/service.d.ts.map +1 -1
  114. package/dist/core/entities/permission-policy/service.mjs +12 -5
  115. package/dist/core/entities/permission-policy/service.mjs.map +1 -1
  116. package/dist/core/entities/policy/service.d.ts.map +1 -1
  117. package/dist/core/entities/policy/service.mjs +16 -7
  118. package/dist/core/entities/policy/service.mjs.map +1 -1
  119. package/dist/core/entities/realm/service.mjs +4 -4
  120. package/dist/core/entities/realm/service.mjs.map +1 -1
  121. package/dist/core/entities/realm/types.d.ts +4 -0
  122. package/dist/core/entities/realm/types.d.ts.map +1 -1
  123. package/dist/core/entities/robot/service.d.ts.map +1 -1
  124. package/dist/core/entities/robot/service.mjs +29 -11
  125. package/dist/core/entities/robot/service.mjs.map +1 -1
  126. package/dist/core/entities/robot-permission/service.d.ts +7 -4
  127. package/dist/core/entities/robot-permission/service.d.ts.map +1 -1
  128. package/dist/core/entities/robot-permission/service.mjs +59 -19
  129. package/dist/core/entities/robot-permission/service.mjs.map +1 -1
  130. package/dist/core/entities/robot-role/service.d.ts +3 -2
  131. package/dist/core/entities/robot-role/service.d.ts.map +1 -1
  132. package/dist/core/entities/robot-role/service.mjs +12 -5
  133. package/dist/core/entities/robot-role/service.mjs.map +1 -1
  134. package/dist/core/entities/role/service.d.ts.map +1 -1
  135. package/dist/core/entities/role/service.mjs +16 -7
  136. package/dist/core/entities/role/service.mjs.map +1 -1
  137. package/dist/core/entities/role-attribute/service.d.ts.map +1 -1
  138. package/dist/core/entities/role-attribute/service.mjs +24 -6
  139. package/dist/core/entities/role-attribute/service.mjs.map +1 -1
  140. package/dist/core/entities/role-permission/service.d.ts +7 -4
  141. package/dist/core/entities/role-permission/service.d.ts.map +1 -1
  142. package/dist/core/entities/role-permission/service.mjs +61 -21
  143. package/dist/core/entities/role-permission/service.mjs.map +1 -1
  144. package/dist/core/entities/scope/service.d.ts.map +1 -1
  145. package/dist/core/entities/scope/service.mjs +16 -7
  146. package/dist/core/entities/scope/service.mjs.map +1 -1
  147. package/dist/core/entities/user/service.d.ts.map +1 -1
  148. package/dist/core/entities/user/service.mjs +28 -10
  149. package/dist/core/entities/user/service.mjs.map +1 -1
  150. package/dist/core/entities/user-attribute/service.d.ts.map +1 -1
  151. package/dist/core/entities/user-attribute/service.mjs +18 -6
  152. package/dist/core/entities/user-attribute/service.mjs.map +1 -1
  153. package/dist/core/entities/user-permission/service.d.ts +7 -4
  154. package/dist/core/entities/user-permission/service.d.ts.map +1 -1
  155. package/dist/core/entities/user-permission/service.mjs +59 -19
  156. package/dist/core/entities/user-permission/service.mjs.map +1 -1
  157. package/dist/core/entities/user-role/service.d.ts +3 -2
  158. package/dist/core/entities/user-role/service.d.ts.map +1 -1
  159. package/dist/core/entities/user-role/service.mjs +12 -5
  160. package/dist/core/entities/user-role/service.mjs.map +1 -1
  161. package/dist/core/identity/index.mjs +2 -1
  162. package/dist/core/identity/permission/checker/service.d.ts.map +1 -1
  163. package/dist/core/identity/permission/checker/service.mjs +6 -4
  164. package/dist/core/identity/permission/checker/service.mjs.map +1 -1
  165. package/dist/core/identity/permission/index.d.ts +1 -0
  166. package/dist/core/identity/permission/index.d.ts.map +1 -1
  167. package/dist/core/identity/permission/index.mjs +2 -1
  168. package/dist/core/identity/permission/junction-grant.d.ts +49 -0
  169. package/dist/core/identity/permission/junction-grant.d.ts.map +1 -0
  170. package/dist/core/identity/permission/junction-grant.mjs +57 -0
  171. package/dist/core/identity/permission/junction-grant.mjs.map +1 -0
  172. package/dist/core/identity/permission/module.d.ts +2 -3
  173. package/dist/core/identity/permission/module.d.ts.map +1 -1
  174. package/dist/core/identity/permission/module.mjs +52 -14
  175. package/dist/core/identity/permission/module.mjs.map +1 -1
  176. package/dist/core/identity/permission/types.d.ts +22 -2
  177. package/dist/core/identity/permission/types.d.ts.map +1 -1
  178. package/dist/core/index.mjs +2 -1
  179. package/dist/core/provisioning/entities/role/types.d.ts +8 -5
  180. package/dist/core/provisioning/entities/role/types.d.ts.map +1 -1
  181. package/dist/core/provisioning/synchronizer/base.d.ts +3 -0
  182. package/dist/core/provisioning/synchronizer/base.d.ts.map +1 -1
  183. package/dist/core/provisioning/synchronizer/base.mjs +3 -0
  184. package/dist/core/provisioning/synchronizer/base.mjs.map +1 -1
  185. package/dist/core/provisioning/synchronizer/client/module.d.ts.map +1 -1
  186. package/dist/core/provisioning/synchronizer/client/module.mjs +1 -0
  187. package/dist/core/provisioning/synchronizer/client/module.mjs.map +1 -1
  188. package/dist/core/provisioning/synchronizer/entity-resolver.d.ts.map +1 -1
  189. package/dist/core/provisioning/synchronizer/entity-resolver.mjs +3 -0
  190. package/dist/core/provisioning/synchronizer/entity-resolver.mjs.map +1 -1
  191. package/dist/core/provisioning/synchronizer/index.mjs +1 -0
  192. package/dist/core/provisioning/synchronizer/permission/module.d.ts.map +1 -1
  193. package/dist/core/provisioning/synchronizer/permission/module.mjs +2 -1
  194. package/dist/core/provisioning/synchronizer/permission/module.mjs.map +1 -1
  195. package/dist/core/provisioning/synchronizer/policy/module.d.ts +2 -0
  196. package/dist/core/provisioning/synchronizer/policy/module.d.ts.map +1 -1
  197. package/dist/core/provisioning/synchronizer/policy/module.mjs +19 -1
  198. package/dist/core/provisioning/synchronizer/policy/module.mjs.map +1 -1
  199. package/dist/core/provisioning/synchronizer/realm/module.d.ts.map +1 -1
  200. package/dist/core/provisioning/synchronizer/realm/module.mjs +1 -0
  201. package/dist/core/provisioning/synchronizer/realm/module.mjs.map +1 -1
  202. package/dist/core/provisioning/synchronizer/robot/module.d.ts.map +1 -1
  203. package/dist/core/provisioning/synchronizer/robot/module.mjs +1 -0
  204. package/dist/core/provisioning/synchronizer/robot/module.mjs.map +1 -1
  205. package/dist/core/provisioning/synchronizer/role/module.d.ts +2 -3
  206. package/dist/core/provisioning/synchronizer/role/module.d.ts.map +1 -1
  207. package/dist/core/provisioning/synchronizer/role/module.mjs +14 -20
  208. package/dist/core/provisioning/synchronizer/role/module.mjs.map +1 -1
  209. package/dist/core/provisioning/synchronizer/role/types.d.ts +1 -2
  210. package/dist/core/provisioning/synchronizer/role/types.d.ts.map +1 -1
  211. package/dist/core/provisioning/synchronizer/scope/module.d.ts.map +1 -1
  212. package/dist/core/provisioning/synchronizer/scope/module.mjs +1 -0
  213. package/dist/core/provisioning/synchronizer/scope/module.mjs.map +1 -1
  214. package/dist/core/provisioning/synchronizer/user/module.d.ts.map +1 -1
  215. package/dist/core/provisioning/synchronizer/user/module.mjs +1 -0
  216. package/dist/core/provisioning/synchronizer/user/module.mjs.map +1 -1
  217. package/dist/core/security/policy/evaluator.d.ts +4 -4
  218. package/dist/core/security/policy/evaluator.d.ts.map +1 -1
  219. package/dist/core/security/policy/evaluator.mjs +19 -18
  220. package/dist/core/security/policy/evaluator.mjs.map +1 -1
  221. package/dist/index.mjs +3 -3
  222. package/dist/swagger.json +54 -0
  223. package/dist/ui/client/.vite/ssr-manifest.json +1017 -639
  224. package/dist/ui/client/assets/index-Cd3uWit-.js +127 -0
  225. package/dist/ui/client/assets/index-DoCTwJ8M.css +2 -0
  226. package/dist/ui/client/index.html +2 -2
  227. package/dist/ui/server/server.js +11086 -2362
  228. package/package.json +37 -35
  229. package/dist/ui/client/assets/index-BFXs98mu.js +0 -102
  230. package/dist/ui/client/assets/index-C_-HM1P-.css +0 -2
@@ -3,11 +3,12 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { ValidatorGroup } from "@authup/kit";
5
5
  import { ClientRoleValidator, PermissionName } from "@authup/core-kit";
6
- import { AbstractEntityService } from "@authup/server-kit";
7
- import { BuiltInPolicyType, PermissionError, PolicyData } from "@authup/access";
6
+ import { JunctionEntityService } from "@authup/server-kit";
7
+ import { BuiltInPolicyType, PermissionError, definePolicyData } from "@authup/access";
8
8
  import { EntityConflictError, EntityNotFoundError } from "@authup/errors";
9
9
  //#region src/core/entities/client-role/service.ts
10
- var ClientRoleService = class extends AbstractEntityService {
10
+ var ClientRoleService = class extends JunctionEntityService {
11
+ ownerRealmKey = "client_realm_id";
11
12
  repository;
12
13
  identityPermissionProvider;
13
14
  validator;
@@ -57,7 +58,10 @@ var ClientRoleService = class extends AbstractEntityService {
57
58
  }
58
59
  await actor.permissionEvaluator.evaluate({
59
60
  name: PermissionName.CLIENT_ROLE_CREATE,
60
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated })
61
+ data: definePolicyData({
62
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),
63
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated)
64
+ })
61
65
  });
62
66
  let entity = this.repository.create(validated);
63
67
  entity = await this.repository.save(entity);
@@ -69,7 +73,10 @@ var ClientRoleService = class extends AbstractEntityService {
69
73
  if (!entity) throw new EntityNotFoundError();
70
74
  await actor.permissionEvaluator.evaluate({
71
75
  name: PermissionName.CLIENT_ROLE_DELETE,
72
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
76
+ data: definePolicyData({
77
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),
78
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity)
79
+ })
73
80
  });
74
81
  const { id: entityId } = entity;
75
82
  await this.repository.remove(entity);
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PermissionError","PolicyData","EntityConflictError","EntityNotFoundError","ValidatorGroup","ClientRoleValidator","PermissionName","AbstractEntityService","ClientRoleService","repository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","CLIENT_ROLE_READ","CLIENT_ROLE_UPDATE","CLIENT_ROLE_DELETE","findMany","getOne","id","entity","findOneBy","create","data","preEvaluate","CLIENT_ROLE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","role_id","client_id","role","role_realm_id","realm_id","client","client_realm_id","identity","hasPermissions","isSuperset","type","clientId","message","evaluate","input","ATTRIBUTES","save","delete","entityId","remove"],"sources":["../../../../src/core/entities/client-role/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, PermissionError, PolicyData } from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { ClientRoleValidator, PermissionName } from '@authup/core-kit';\nimport type { ClientRole } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport type { IClientRoleRepository, IClientRoleService } from './types.ts';\n\nexport type ClientRoleServiceContext = {\n repository: IClientRoleRepository;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class ClientRoleService extends AbstractEntityService implements IClientRoleService {\n protected repository: IClientRoleRepository;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: ClientRoleValidator;\n\n constructor(ctx: ClientRoleServiceContext) {\n super();\n this.repository = ctx.repository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new ClientRoleValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<ClientRole>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_ROLE_READ,\n PermissionName.CLIENT_ROLE_UPDATE,\n PermissionName.CLIENT_ROLE_DELETE,\n ],\n });\n\n return this.repository.findMany(query);\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<ClientRole> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_ROLE_READ,\n PermissionName.CLIENT_ROLE_UPDATE,\n PermissionName.CLIENT_ROLE_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\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<ClientRole> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_ROLE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n role_id: validated.role_id,\n client_id: validated.client_id,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'client-role' });\n }\n\n if (validated.role) {\n validated.role_realm_id = validated.role.realm_id;\n }\n\n if (validated.client) {\n validated.client_realm_id = validated.client.realm_id;\n }\n\n if (validated.role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: validated.role_id,\n clientId: validated.role.client_id,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_ROLE_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<ClientRole> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_ROLE_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.CLIENT_ROLE_DELETE,\n input: new PolicyData({ [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":";;;;;;;;;AAsBA,IAAaS,oBAAb,cAAuCD,sBAAAA;CACzBE;CAEAC;CAEAC;CAEV,YAAYC,KAA+B;EACvC,MAAK;EACL,KAAKH,aAAaG,IAAIH;EACtB,KAAKC,6BAA6BE,IAAIF;EACtC,KAAKC,YAAY,IAAIN,oBAAAA;CACzB;CAEA,MAAMQ,QACFC,OACAC,OACmD;EACnD,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFZ,eAAea;GACfb,eAAec;GACfd,eAAee;IAEvB,CAAA;EAEA,OAAO,KAAKZ,WAAWa,SAASR,KAAAA;CACpC;CAEA,MAAMS,OACFC,IACAT,OACmB;EACnB,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFZ,eAAea;GACfb,eAAec;GACfd,eAAee;IAEvB,CAAA;EAEA,MAAMI,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAItB,oBAAAA;EAGd,OAAOsB;CACX;CAEA,MAAME,OACFC,MACAb,OACmB;EACnB,MAAMA,MAAMC,oBAAoBa,YAAY,EAAEX,MAAMZ,eAAewB,mBAAmB,CAAA;EAEtF,MAAMC,YAAY,MAAM,KAAKpB,UAAUqB,IAAIJ,MAAM,EAAEK,OAAO7B,eAAe8B,OAAO,CAAA;EAEhF,MAAM,KAAKzB,WAAW0B,oBAAoBJ,SAAAA;EAM1C,IAAIK,MAJmB,KAAK3B,WAAWiB,UAAU;GAC7CW,SAASN,UAAUM;GACnBC,WAAWP,UAAUO;EACzB,CAAA,GAEI,MAAM,IAAIpC,oBAAoB,EAAEuB,QAAQ,cAAc,CAAA;EAG1D,IAAIM,UAAUQ,MACVR,UAAUS,gBAAgBT,UAAUQ,KAAKE;EAG7C,IAAIV,UAAUW,QACVX,UAAUY,kBAAkBZ,UAAUW,OAAOD;EAGjD,IAAIV,UAAUQ,QAAQxB,MAAM6B;OAYpB,CAACC,MAXwB,KAAKnC,2BAA2BoC,WACzD;IACIC,MAAMhC,MAAM6B,SAASG;IACrBvB,IAAIT,MAAM6B,SAAShB,KAAKJ;GAC5B,GACA;IACIuB,MAAM;IACNvB,IAAIO,UAAUM;IACdW,UAAUjB,UAAUQ,KAAKD;GAC7B,CAAA,GAGA,MAAM,IAAItC,gBAAgB,EAAEiD,SAAS,0CAA2C,CAAA;EAAA;EAIxF,MAAMlC,MAAMC,oBAAoBkC,SAAS;GACrChC,MAAMZ,eAAewB;GACrBqB,OAAO,IAAIlD,WAAW,GAAGF,kBAAkBqD,aAAarB,UAAU,CAAA;EACtE,CAAA;EAEA,IAAIN,SAAS,KAAKhB,WAAWkB,OAAOI,SAAAA;EACpCN,SAAS,MAAM,KAAKhB,WAAW4C,KAAK5B,MAAAA;EAEpC,OAAOA;CACX;CAEA,MAAM6B,OACF9B,IACAT,OACmB;EACnB,MAAMA,MAAMC,oBAAoBa,YAAY,EAAEX,MAAMZ,eAAee,mBAAmB,CAAA;EAEtF,MAAMI,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAItB,oBAAAA;EAGd,MAAMY,MAAMC,oBAAoBkC,SAAS;GACrChC,MAAMZ,eAAee;GACrB8B,OAAO,IAAIlD,WAAW,GAAGF,kBAAkBqD,aAAa3B,OAAO,CAAA;EACnE,CAAA;EAEA,MAAM,EAAED,IAAI+B,aAAa9B;EACzB,MAAM,KAAKhB,WAAW+C,OAAO/B,MAAAA;EAC7BA,OAAOD,KAAK+B;EAEZ,OAAO9B;CACX;AACJ"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PermissionError","definePolicyData","EntityConflictError","EntityNotFoundError","ValidatorGroup","ClientRoleValidator","PermissionName","JunctionEntityService","ClientRoleService","ownerRealmKey","repository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","CLIENT_ROLE_READ","CLIENT_ROLE_UPDATE","CLIENT_ROLE_DELETE","findMany","getOne","id","entity","findOneBy","create","data","preEvaluate","CLIENT_ROLE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","role_id","client_id","role","role_realm_id","realm_id","client","client_realm_id","identity","hasPermissions","isSuperset","type","clientId","message","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","delete","entityId","remove"],"sources":["../../../../src/core/entities/client-role/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, PermissionError, definePolicyData } from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { ClientRoleValidator, PermissionName } from '@authup/core-kit';\nimport type { ClientRole } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport type { IClientRoleRepository, IClientRoleService } from './types.ts';\n\nexport type ClientRoleServiceContext = {\n repository: IClientRoleRepository;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class ClientRoleService extends JunctionEntityService implements IClientRoleService {\n protected readonly ownerRealmKey = 'client_realm_id';\n\n protected repository: IClientRoleRepository;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: ClientRoleValidator;\n\n constructor(ctx: ClientRoleServiceContext) {\n super();\n this.repository = ctx.repository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new ClientRoleValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<ClientRole>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_ROLE_READ,\n PermissionName.CLIENT_ROLE_UPDATE,\n PermissionName.CLIENT_ROLE_DELETE,\n ],\n });\n\n return this.repository.findMany(query);\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<ClientRole> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_ROLE_READ,\n PermissionName.CLIENT_ROLE_UPDATE,\n PermissionName.CLIENT_ROLE_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\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<ClientRole> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_ROLE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n role_id: validated.role_id,\n client_id: validated.client_id,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'client-role' });\n }\n\n if (validated.role) {\n validated.role_realm_id = validated.role.realm_id;\n }\n\n if (validated.client) {\n validated.client_realm_id = validated.client.realm_id;\n }\n\n if (validated.role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: validated.role_id,\n clientId: validated.role.client_id,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n // Stamp the owner (client) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_ROLE_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<ClientRole> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_ROLE_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // Stamp the owner (client) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_ROLE_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\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":";;;;;;;;;AAsBA,IAAaS,oBAAb,cAAuCD,sBAAAA;CAChBE,gBAAgB;CAEzBC;CAEAC;CAEAC;CAEV,YAAYC,KAA+B;EACvC,MAAK;EACL,KAAKH,aAAaG,IAAIH;EACtB,KAAKC,6BAA6BE,IAAIF;EACtC,KAAKC,YAAY,IAAIP,oBAAAA;CACzB;CAEA,MAAMS,QACFC,OACAC,OACmD;EACnD,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFb,eAAec;GACfd,eAAee;GACff,eAAegB;IAEvB,CAAA;EAEA,OAAO,KAAKZ,WAAWa,SAASR,KAAAA;CACpC;CAEA,MAAMS,OACFC,IACAT,OACmB;EACnB,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFb,eAAec;GACfd,eAAee;GACff,eAAegB;IAEvB,CAAA;EAEA,MAAMI,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAIvB,oBAAAA;EAGd,OAAOuB;CACX;CAEA,MAAME,OACFC,MACAb,OACmB;EACnB,MAAMA,MAAMC,oBAAoBa,YAAY,EAAEX,MAAMb,eAAeyB,mBAAmB,CAAA;EAEtF,MAAMC,YAAY,MAAM,KAAKpB,UAAUqB,IAAIJ,MAAM,EAAEK,OAAO9B,eAAe+B,OAAO,CAAA;EAEhF,MAAM,KAAKzB,WAAW0B,oBAAoBJ,SAAAA;EAM1C,IAAIK,MAJmB,KAAK3B,WAAWiB,UAAU;GAC7CW,SAASN,UAAUM;GACnBC,WAAWP,UAAUO;EACzB,CAAA,GAEI,MAAM,IAAIrC,oBAAoB,EAAEwB,QAAQ,cAAc,CAAA;EAG1D,IAAIM,UAAUQ,MACVR,UAAUS,gBAAgBT,UAAUQ,KAAKE;EAG7C,IAAIV,UAAUW,QACVX,UAAUY,kBAAkBZ,UAAUW,OAAOD;EAGjD,IAAIV,UAAUQ,QAAQxB,MAAM6B;OAYpB,CAACC,MAXwB,KAAKnC,2BAA2BoC,WACzD;IACIC,MAAMhC,MAAM6B,SAASG;IACrBvB,IAAIT,MAAM6B,SAAShB,KAAKJ;GAC5B,GACA;IACIuB,MAAM;IACNvB,IAAIO,UAAUM;IACdW,UAAUjB,UAAUQ,KAAKD;GAC7B,CAAA,GAGA,MAAM,IAAIvC,gBAAgB,EAAEkD,SAAS,0CAA2C,CAAA;EAAA;EAKxF,MAAMlC,MAAMC,oBAAoBkC,SAAS;GACrChC,MAAMb,eAAeyB;GACrBF,MAAM5B,iBAAiB;KAClBF,kBAAkBqD,aAAa,KAAKC,mBAAmBrB,SAAAA;KACvDjC,kBAAkBuD,cAAc,KAAKC,sBAAsBvB,SAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,IAAIN,SAAS,KAAKhB,WAAWkB,OAAOI,SAAAA;EACpCN,SAAS,MAAM,KAAKhB,WAAW8C,KAAK9B,MAAAA;EAEpC,OAAOA;CACX;CAEA,MAAM+B,OACFhC,IACAT,OACmB;EACnB,MAAMA,MAAMC,oBAAoBa,YAAY,EAAEX,MAAMb,eAAegB,mBAAmB,CAAA;EAEtF,MAAMI,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAIvB,oBAAAA;EAId,MAAMa,MAAMC,oBAAoBkC,SAAS;GACrChC,MAAMb,eAAegB;GACrBO,MAAM5B,iBAAiB;KAClBF,kBAAkBqD,aAAa,KAAKC,mBAAmB3B,MAAAA;KACvD3B,kBAAkBuD,cAAc,KAAKC,sBAAsB7B,MAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,MAAM,EAAED,IAAIiC,aAAahC;EACzB,MAAM,KAAKhB,WAAWiD,OAAOjC,MAAAA;EAC7BA,OAAOD,KAAKiC;EAEZ,OAAOhC;CACX;AACJ"}
@@ -1,12 +1,13 @@
1
1
  import { ClientScopeValidator } from '@authup/core-kit';
2
2
  import type { ClientScope } from '@authup/core-kit';
3
3
  import type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';
4
- import { AbstractEntityService } from '@authup/server-kit';
4
+ import { JunctionEntityService } from '@authup/server-kit';
5
5
  import type { IClientScopeRepository, IClientScopeService } from './types.ts';
6
6
  export type ClientScopeServiceContext = {
7
7
  repository: IClientScopeRepository;
8
8
  };
9
- export declare class ClientScopeService extends AbstractEntityService implements IClientScopeService {
9
+ export declare class ClientScopeService extends JunctionEntityService implements IClientScopeService {
10
+ protected readonly ownerRealmKey = "client_realm_id";
10
11
  protected repository: IClientScopeRepository;
11
12
  protected validator: ClientScopeValidator;
12
13
  constructor(ctx: ClientScopeServiceContext);
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/client-scope/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,oBAAoB,EAAkB,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,MAAM,yBAAyB,GAAG;IACpC,UAAU,EAAE,sBAAsB,CAAC;CACtC,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,qBAAsB,YAAW,mBAAmB;IACxF,SAAS,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAE7C,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC;gBAE9B,GAAG,EAAE,yBAAyB;IAMpC,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,WAAW,CAAC,CAAC;IAajD,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;IAkBjB,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;IAkCjB,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;CAmB1B"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/client-scope/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,oBAAoB,EAAkB,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,MAAM,yBAAyB,GAAG;IACpC,UAAU,EAAE,sBAAsB,CAAC;CACtC,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,qBAAsB,YAAW,mBAAmB;IACxF,SAAS,CAAC,QAAQ,CAAC,aAAa,qBAAqB;IAErD,SAAS,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAE7C,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC;gBAE9B,GAAG,EAAE,yBAAyB;IAMpC,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,WAAW,CAAC,CAAC;IAajD,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;IAkBjB,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;IAsCjB,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;CAuB1B"}
@@ -3,11 +3,12 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { ValidatorGroup } from "@authup/kit";
5
5
  import { ClientScopeValidator, PermissionName } from "@authup/core-kit";
6
- import { AbstractEntityService } from "@authup/server-kit";
7
- import { BuiltInPolicyType, PolicyData } from "@authup/access";
6
+ import { JunctionEntityService } from "@authup/server-kit";
7
+ import { BuiltInPolicyType, definePolicyData } from "@authup/access";
8
8
  import { EntityConflictError, EntityNotFoundError } from "@authup/errors";
9
9
  //#region src/core/entities/client-scope/service.ts
10
- var ClientScopeService = class extends AbstractEntityService {
10
+ var ClientScopeService = class extends JunctionEntityService {
11
+ ownerRealmKey = "client_realm_id";
11
12
  repository;
12
13
  validator;
13
14
  constructor(ctx) {
@@ -47,7 +48,10 @@ var ClientScopeService = class extends AbstractEntityService {
47
48
  if (validated.scope) validated.scope_realm_id = validated.scope.realm_id;
48
49
  await actor.permissionEvaluator.evaluate({
49
50
  name: PermissionName.CLIENT_SCOPE_CREATE,
50
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated })
51
+ data: definePolicyData({
52
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),
53
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated)
54
+ })
51
55
  });
52
56
  let entity = this.repository.create(validated);
53
57
  entity = await this.repository.save(entity);
@@ -59,7 +63,10 @@ var ClientScopeService = class extends AbstractEntityService {
59
63
  if (!entity) throw new EntityNotFoundError();
60
64
  await actor.permissionEvaluator.evaluate({
61
65
  name: PermissionName.CLIENT_SCOPE_DELETE,
62
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
66
+ data: definePolicyData({
67
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),
68
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity)
69
+ })
63
70
  });
64
71
  const { id: entityId } = entity;
65
72
  await this.repository.remove(entity);
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","EntityConflictError","EntityNotFoundError","ValidatorGroup","ClientScopeValidator","PermissionName","AbstractEntityService","ClientScopeService","repository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","CLIENT_SCOPE_READ","CLIENT_READ","CLIENT_UPDATE","CLIENT_DELETE","findMany","getOne","id","entity","findOneBy","create","data","preEvaluate","CLIENT_SCOPE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","client_id","scope_id","client","client_realm_id","realm_id","scope","scope_realm_id","evaluate","input","ATTRIBUTES","save","delete","CLIENT_SCOPE_DELETE","entityId","remove"],"sources":["../../../../src/core/entities/client-scope/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, PolicyData } from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { ClientScopeValidator, PermissionName } from '@authup/core-kit';\nimport type { ClientScope } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IClientScopeRepository, IClientScopeService } from './types.ts';\n\nexport type ClientScopeServiceContext = {\n repository: IClientScopeRepository;\n};\n\nexport class ClientScopeService extends AbstractEntityService implements IClientScopeService {\n protected repository: IClientScopeRepository;\n\n protected validator: ClientScopeValidator;\n\n constructor(ctx: ClientScopeServiceContext) {\n super();\n this.repository = ctx.repository;\n this.validator = new ClientScopeValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<ClientScope>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_SCOPE_READ,\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n return this.repository.findMany(query);\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<ClientScope> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_SCOPE_READ,\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\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<ClientScope> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_SCOPE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n client_id: validated.client_id,\n scope_id: validated.scope_id,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'client-scope' });\n }\n\n if (validated.client) {\n validated.client_realm_id = validated.client.realm_id;\n }\n\n if (validated.scope) {\n validated.scope_realm_id = validated.scope.realm_id;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_SCOPE_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<ClientScope> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_SCOPE_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.CLIENT_SCOPE_DELETE,\n input: new PolicyData({ [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":";;;;;;;;;AAoBA,IAAaQ,qBAAb,cAAwCD,sBAAAA;CAC1BE;CAEAC;CAEV,YAAYC,KAAgC;EACxC,MAAK;EACL,KAAKF,aAAaE,IAAIF;EACtB,KAAKC,YAAY,IAAIL,qBAAAA;CACzB;CAEA,MAAMO,QACFC,OACAC,OACoD;EACpD,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFX,eAAeY;GACfZ,eAAea;GACfb,eAAec;GACfd,eAAee;IAEvB,CAAA;EAEA,OAAO,KAAKZ,WAAWa,SAAST,KAAAA;CACpC;CAEA,MAAMU,OACFC,IACAV,OACoB;EACpB,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFX,eAAeY;GACfZ,eAAea;GACfb,eAAec;GACfd,eAAee;IAEvB,CAAA;EAEA,MAAMI,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAItB,oBAAAA;EAGd,OAAOsB;CACX;CAEA,MAAME,OACFC,MACAd,OACoB;EACpB,MAAMA,MAAMC,oBAAoBc,YAAY,EAAEZ,MAAMX,eAAewB,oBAAoB,CAAA;EAEvF,MAAMC,YAAY,MAAM,KAAKrB,UAAUsB,IAAIJ,MAAM,EAAEK,OAAO7B,eAAe8B,OAAO,CAAA;EAEhF,MAAM,KAAKzB,WAAW0B,oBAAoBJ,SAAAA;EAM1C,IAAIK,MAJmB,KAAK3B,WAAWiB,UAAU;GAC7CW,WAAWN,UAAUM;GACrBC,UAAUP,UAAUO;EACxB,CAAA,GAEI,MAAM,IAAIpC,oBAAoB,EAAEuB,QAAQ,eAAe,CAAA;EAG3D,IAAIM,UAAUQ,QACVR,UAAUS,kBAAkBT,UAAUQ,OAAOE;EAGjD,IAAIV,UAAUW,OACVX,UAAUY,iBAAiBZ,UAAUW,MAAMD;EAG/C,MAAM3B,MAAMC,oBAAoB6B,SAAS;GACrC3B,MAAMX,eAAewB;GACrBe,OAAO,IAAI5C,WAAW,GAAGD,kBAAkB8C,aAAaf,UAAU,CAAA;EACtE,CAAA;EAEA,IAAIN,SAAS,KAAKhB,WAAWkB,OAAOI,SAAAA;EACpCN,SAAS,MAAM,KAAKhB,WAAWsC,KAAKtB,MAAAA;EAEpC,OAAOA;CACX;CAEA,MAAMuB,OACFxB,IACAV,OACoB;EACpB,MAAMA,MAAMC,oBAAoBc,YAAY,EAAEZ,MAAMX,eAAe2C,oBAAoB,CAAA;EAEvF,MAAMxB,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAItB,oBAAAA;EAGd,MAAMW,MAAMC,oBAAoB6B,SAAS;GACrC3B,MAAMX,eAAe2C;GACrBJ,OAAO,IAAI5C,WAAW,GAAGD,kBAAkB8C,aAAarB,OAAO,CAAA;EACnE,CAAA;EAEA,MAAM,EAAED,IAAI0B,aAAazB;EACzB,MAAM,KAAKhB,WAAW0C,OAAO1B,MAAAA;EAC7BA,OAAOD,KAAK0B;EAEZ,OAAOzB;CACX;AACJ"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","EntityConflictError","EntityNotFoundError","ValidatorGroup","ClientScopeValidator","PermissionName","JunctionEntityService","ClientScopeService","ownerRealmKey","repository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","CLIENT_SCOPE_READ","CLIENT_READ","CLIENT_UPDATE","CLIENT_DELETE","findMany","getOne","id","entity","findOneBy","create","data","preEvaluate","CLIENT_SCOPE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","client_id","scope_id","client","client_realm_id","realm_id","scope","scope_realm_id","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","delete","CLIENT_SCOPE_DELETE","entityId","remove"],"sources":["../../../../src/core/entities/client-scope/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 { EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { ClientScopeValidator, PermissionName } from '@authup/core-kit';\nimport type { ClientScope } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IClientScopeRepository, IClientScopeService } from './types.ts';\n\nexport type ClientScopeServiceContext = {\n repository: IClientScopeRepository;\n};\n\nexport class ClientScopeService extends JunctionEntityService implements IClientScopeService {\n protected readonly ownerRealmKey = 'client_realm_id';\n\n protected repository: IClientScopeRepository;\n\n protected validator: ClientScopeValidator;\n\n constructor(ctx: ClientScopeServiceContext) {\n super();\n this.repository = ctx.repository;\n this.validator = new ClientScopeValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<ClientScope>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_SCOPE_READ,\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n return this.repository.findMany(query);\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<ClientScope> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_SCOPE_READ,\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\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<ClientScope> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_SCOPE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n client_id: validated.client_id,\n scope_id: validated.scope_id,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'client-scope' });\n }\n\n if (validated.client) {\n validated.client_realm_id = validated.client.realm_id;\n }\n\n if (validated.scope) {\n validated.scope_realm_id = validated.scope.realm_id;\n }\n\n // Stamp the owner (client) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_SCOPE_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<ClientScope> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_SCOPE_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // Stamp the owner (client) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_SCOPE_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\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":";;;;;;;;;AAoBA,IAAaQ,qBAAb,cAAwCD,sBAAAA;CACjBE,gBAAgB;CAEzBC;CAEAC;CAEV,YAAYC,KAAgC;EACxC,MAAK;EACL,KAAKF,aAAaE,IAAIF;EACtB,KAAKC,YAAY,IAAIN,qBAAAA;CACzB;CAEA,MAAMQ,QACFC,OACAC,OACoD;EACpD,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFZ,eAAea;GACfb,eAAec;GACfd,eAAee;GACff,eAAegB;IAEvB,CAAA;EAEA,OAAO,KAAKZ,WAAWa,SAAST,KAAAA;CACpC;CAEA,MAAMU,OACFC,IACAV,OACoB;EACpB,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFZ,eAAea;GACfb,eAAec;GACfd,eAAee;GACff,eAAegB;IAEvB,CAAA;EAEA,MAAMI,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAIvB,oBAAAA;EAGd,OAAOuB;CACX;CAEA,MAAME,OACFC,MACAd,OACoB;EACpB,MAAMA,MAAMC,oBAAoBc,YAAY,EAAEZ,MAAMZ,eAAeyB,oBAAoB,CAAA;EAEvF,MAAMC,YAAY,MAAM,KAAKrB,UAAUsB,IAAIJ,MAAM,EAAEK,OAAO9B,eAAe+B,OAAO,CAAA;EAEhF,MAAM,KAAKzB,WAAW0B,oBAAoBJ,SAAAA;EAM1C,IAAIK,MAJmB,KAAK3B,WAAWiB,UAAU;GAC7CW,WAAWN,UAAUM;GACrBC,UAAUP,UAAUO;EACxB,CAAA,GAEI,MAAM,IAAIrC,oBAAoB,EAAEwB,QAAQ,eAAe,CAAA;EAG3D,IAAIM,UAAUQ,QACVR,UAAUS,kBAAkBT,UAAUQ,OAAOE;EAGjD,IAAIV,UAAUW,OACVX,UAAUY,iBAAiBZ,UAAUW,MAAMD;EAI/C,MAAM3B,MAAMC,oBAAoB6B,SAAS;GACrC3B,MAAMZ,eAAeyB;GACrBF,MAAM5B,iBAAiB;KAClBD,kBAAkB8C,aAAa,KAAKC,mBAAmBf,SAAAA;KACvDhC,kBAAkBgD,cAAc,KAAKC,sBAAsBjB,SAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,IAAIN,SAAS,KAAKhB,WAAWkB,OAAOI,SAAAA;EACpCN,SAAS,MAAM,KAAKhB,WAAWwC,KAAKxB,MAAAA;EAEpC,OAAOA;CACX;CAEA,MAAMyB,OACF1B,IACAV,OACoB;EACpB,MAAMA,MAAMC,oBAAoBc,YAAY,EAAEZ,MAAMZ,eAAe8C,oBAAoB,CAAA;EAEvF,MAAM1B,SAAS,MAAM,KAAKhB,WAAWiB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAIvB,oBAAAA;EAId,MAAMY,MAAMC,oBAAoB6B,SAAS;GACrC3B,MAAMZ,eAAe8C;GACrBvB,MAAM5B,iBAAiB;KAClBD,kBAAkB8C,aAAa,KAAKC,mBAAmBrB,MAAAA;KACvD1B,kBAAkBgD,cAAc,KAAKC,sBAAsBvB,MAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,MAAM,EAAED,IAAI4B,aAAa3B;EACzB,MAAM,KAAKhB,WAAW4C,OAAO5B,MAAAA;EAC7BA,OAAOD,KAAK4B;EAEZ,OAAO3B;CACX;AACJ"}
@@ -1,15 +1,18 @@
1
1
  import { IdentityProviderRoleMappingValidator } from '@authup/core-kit';
2
- import type { IdentityProviderRoleMapping } from '@authup/core-kit';
3
- import type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';
4
- import { AbstractEntityService } from '@authup/server-kit';
2
+ import type { IdentityProviderRoleMapping, Role } from '@authup/core-kit';
3
+ import type { ActorContext, EntityRepositoryFindManyResult, IEntityRepository } from '@authup/server-kit';
4
+ import { JunctionEntityService } from '@authup/server-kit';
5
5
  import type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';
6
6
  import type { IIdentityProviderRoleMappingRepository, IIdentityProviderRoleMappingService } from './types.ts';
7
7
  export type IdentityProviderRoleMappingServiceContext = {
8
8
  repository: IIdentityProviderRoleMappingRepository;
9
+ roleRepository: IEntityRepository<Role>;
9
10
  identityPermissionProvider: IIdentityPermissionProvider;
10
11
  };
11
- export declare class IdentityProviderRoleMappingService extends AbstractEntityService implements IIdentityProviderRoleMappingService {
12
+ export declare class IdentityProviderRoleMappingService extends JunctionEntityService implements IIdentityProviderRoleMappingService {
13
+ protected readonly ownerRealmKey = "provider_realm_id";
12
14
  protected repository: IIdentityProviderRoleMappingRepository;
15
+ protected roleRepository: IEntityRepository<Role>;
13
16
  protected identityPermissionProvider: IIdentityPermissionProvider;
14
17
  protected validator: IdentityProviderRoleMappingValidator;
15
18
  constructor(ctx: IdentityProviderRoleMappingServiceContext);
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/identity-provider-role-mapping/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,oCAAoC,EAAkB,MAAM,kBAAkB,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAG,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,KAAK,EAAE,sCAAsC,EAAE,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAE9G,MAAM,MAAM,yCAAyC,GAAG;IACpD,UAAU,EAAE,sCAAsC,CAAC;IACnD,0BAA0B,EAAE,2BAA2B,CAAC;CAC3D,CAAC;AAEF,qBAAa,kCAAmC,SAAQ,qBAAsB,YAAW,mCAAmC;IACxH,SAAS,CAAC,UAAU,EAAE,sCAAsC,CAAC;IAE7D,SAAS,CAAC,0BAA0B,EAAE,2BAA2B,CAAC;IAElE,SAAS,CAAC,SAAS,EAAE,oCAAoC,CAAC;gBAE9C,GAAG,EAAE,yCAAyC;IAOpD,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,2BAA2B,CAAC,CAAC;IAajE,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;IAkBjC,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;IA2DjC,MAAM,CACR,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;IAsBjC,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;CAmB1C"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/identity-provider-role-mapping/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,oCAAoC,EAAkB,MAAM,kBAAkB,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1G,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,KAAK,EAAE,sCAAsC,EAAE,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAE9G,MAAM,MAAM,yCAAyC,GAAG;IACpD,UAAU,EAAE,sCAAsC,CAAC;IACnD,cAAc,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACxC,0BAA0B,EAAE,2BAA2B,CAAC;CAC3D,CAAC;AAEF,qBAAa,kCAAmC,SAAQ,qBAAsB,YAAW,mCAAmC;IACxH,SAAS,CAAC,QAAQ,CAAC,aAAa,uBAAuB;IAEvD,SAAS,CAAC,UAAU,EAAE,sCAAsC,CAAC;IAE7D,SAAS,CAAC,cAAc,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAElD,SAAS,CAAC,0BAA0B,EAAE,2BAA2B,CAAC;IAElE,SAAS,CAAC,SAAS,EAAE,oCAAoC,CAAC;gBAE9C,GAAG,EAAE,yCAAyC;IAQpD,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,2BAA2B,CAAC,CAAC;IAajE,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;IAkBjC,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;IA+DjC,MAAM,CACR,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;IAiDjC,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,2BAA2B,CAAC;CAuB1C"}
@@ -3,17 +3,20 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { ValidatorGroup } from "@authup/kit";
5
5
  import { IdentityProviderRoleMappingValidator, PermissionName } from "@authup/core-kit";
6
- import { AbstractEntityService } from "@authup/server-kit";
7
- import { BuiltInPolicyType, PermissionError, PolicyData } from "@authup/access";
6
+ import { JunctionEntityService } from "@authup/server-kit";
7
+ import { BuiltInPolicyType, PermissionError, definePolicyData } from "@authup/access";
8
8
  import { BadRequestError, EntityConflictError, EntityNotFoundError } from "@authup/errors";
9
9
  //#region src/core/entities/identity-provider-role-mapping/service.ts
10
- var IdentityProviderRoleMappingService = class extends AbstractEntityService {
10
+ var IdentityProviderRoleMappingService = class extends JunctionEntityService {
11
+ ownerRealmKey = "provider_realm_id";
11
12
  repository;
13
+ roleRepository;
12
14
  identityPermissionProvider;
13
15
  validator;
14
16
  constructor(ctx) {
15
17
  super();
16
18
  this.repository = ctx.repository;
19
+ this.roleRepository = ctx.roleRepository;
17
20
  this.identityPermissionProvider = ctx.identityPermissionProvider;
18
21
  this.validator = new IdentityProviderRoleMappingValidator();
19
22
  }
@@ -60,7 +63,10 @@ var IdentityProviderRoleMappingService = class extends AbstractEntityService {
60
63
  }
61
64
  await actor.permissionEvaluator.evaluate({
62
65
  name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE,
63
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated })
66
+ data: definePolicyData({
67
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),
68
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated)
69
+ })
64
70
  });
65
71
  let entity = this.repository.create(validated);
66
72
  entity = await this.repository.save(entity);
@@ -72,10 +78,24 @@ var IdentityProviderRoleMappingService = class extends AbstractEntityService {
72
78
  if (!entity) throw new EntityNotFoundError();
73
79
  const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });
74
80
  await this.repository.validateJoinColumns(validated);
81
+ const role = await this.roleRepository.findOneById(entity.role_id);
82
+ if (role && actor.identity) {
83
+ if (!await this.identityPermissionProvider.isSuperset({
84
+ type: actor.identity.type,
85
+ id: actor.identity.data.id
86
+ }, {
87
+ type: "role",
88
+ id: role.id,
89
+ clientId: role.client_id
90
+ })) throw new PermissionError({ message: "You don't own the required permissions." });
91
+ }
75
92
  const merged = this.repository.merge(entity, validated);
76
93
  await actor.permissionEvaluator.evaluate({
77
94
  name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE,
78
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: merged })
95
+ data: definePolicyData({
96
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(merged),
97
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(merged)
98
+ })
79
99
  });
80
100
  return this.repository.save(merged);
81
101
  }
@@ -85,7 +105,10 @@ var IdentityProviderRoleMappingService = class extends AbstractEntityService {
85
105
  if (!entity) throw new EntityNotFoundError();
86
106
  await actor.permissionEvaluator.evaluate({
87
107
  name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE,
88
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
108
+ data: definePolicyData({
109
+ [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),
110
+ [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity)
111
+ })
89
112
  });
90
113
  const { id: entityId } = entity;
91
114
  await this.repository.remove(entity);
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PermissionError","PolicyData","BadRequestError","EntityConflictError","EntityNotFoundError","ValidatorGroup","IdentityProviderRoleMappingValidator","PermissionName","AbstractEntityService","IdentityProviderRoleMappingService","repository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","IDENTITY_PROVIDER_ROLE_READ","IDENTITY_PROVIDER_READ","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","findMany","getOne","id","entity","findOneBy","create","data","preEvaluate","IDENTITY_PROVIDER_ROLE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","provider_id","role_id","provider","provider_realm_id","realm_id","role","role_realm_id","identity","hasPermissions","isSuperset","type","clientId","client_id","message","evaluate","input","ATTRIBUTES","save","update","IDENTITY_PROVIDER_ROLE_UPDATE","UPDATE","merged","merge","delete","IDENTITY_PROVIDER_ROLE_DELETE","entityId","remove"],"sources":["../../../../src/core/entities/identity-provider-role-mapping/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, PermissionError, PolicyData } from '@authup/access';\nimport { BadRequestError, EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { IdentityProviderRoleMappingValidator, PermissionName } from '@authup/core-kit';\nimport type { IdentityProviderRoleMapping } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport type { IIdentityProviderRoleMappingRepository, IIdentityProviderRoleMappingService } from './types.ts';\n\nexport type IdentityProviderRoleMappingServiceContext = {\n repository: IIdentityProviderRoleMappingRepository;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class IdentityProviderRoleMappingService extends AbstractEntityService implements IIdentityProviderRoleMappingService {\n protected repository: IIdentityProviderRoleMappingRepository;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: IdentityProviderRoleMappingValidator;\n\n constructor(ctx: IdentityProviderRoleMappingServiceContext) {\n super();\n this.repository = ctx.repository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new IdentityProviderRoleMappingValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<IdentityProviderRoleMapping>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n return this.repository.findMany(query);\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\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<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n provider_id: validated.provider_id,\n role_id: validated.role_id,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'identity-provider-role-mapping' });\n }\n\n if (validated.provider) {\n validated.provider_realm_id = validated.provider.realm_id;\n }\n\n if (validated.role) {\n validated.role_realm_id = validated.role.realm_id;\n }\n\n if (\n validated.role_realm_id &&\n validated.provider_realm_id &&\n validated.role_realm_id !== validated.provider_realm_id\n ) {\n throw new BadRequestError('It is not possible to map an identity provider to a role of another realm.');\n }\n\n if (validated.role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: validated.role_id,\n clientId: validated.role.client_id,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async update(\n id: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const merged = this.repository.merge(entity, validated);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: merged }),\n });\n\n return this.repository.save(merged);\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_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.IDENTITY_PROVIDER_ROLE_DELETE,\n input: new PolicyData({ [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","PermissionError","definePolicyData","BadRequestError","EntityConflictError","EntityNotFoundError","ValidatorGroup","IdentityProviderRoleMappingValidator","PermissionName","JunctionEntityService","IdentityProviderRoleMappingService","ownerRealmKey","repository","roleRepository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","IDENTITY_PROVIDER_ROLE_READ","IDENTITY_PROVIDER_READ","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","findMany","getOne","id","entity","findOneBy","create","data","preEvaluate","IDENTITY_PROVIDER_ROLE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","provider_id","role_id","provider","provider_realm_id","realm_id","role","role_realm_id","identity","hasPermissions","isSuperset","type","clientId","client_id","message","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","update","IDENTITY_PROVIDER_ROLE_UPDATE","UPDATE","findOneById","merged","merge","delete","IDENTITY_PROVIDER_ROLE_DELETE","entityId","remove"],"sources":["../../../../src/core/entities/identity-provider-role-mapping/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, PermissionError, definePolicyData } from '@authup/access';\nimport { BadRequestError, EntityConflictError, EntityNotFoundError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { IdentityProviderRoleMappingValidator, PermissionName } from '@authup/core-kit';\nimport type { IdentityProviderRoleMapping, Role } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, IEntityRepository } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport type { IIdentityProviderRoleMappingRepository, IIdentityProviderRoleMappingService } from './types.ts';\n\nexport type IdentityProviderRoleMappingServiceContext = {\n repository: IIdentityProviderRoleMappingRepository;\n roleRepository: IEntityRepository<Role>;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class IdentityProviderRoleMappingService extends JunctionEntityService implements IIdentityProviderRoleMappingService {\n protected readonly ownerRealmKey = 'provider_realm_id';\n\n protected repository: IIdentityProviderRoleMappingRepository;\n\n protected roleRepository: IEntityRepository<Role>;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: IdentityProviderRoleMappingValidator;\n\n constructor(ctx: IdentityProviderRoleMappingServiceContext) {\n super();\n this.repository = ctx.repository;\n this.roleRepository = ctx.roleRepository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new IdentityProviderRoleMappingValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<IdentityProviderRoleMapping>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n return this.repository.findMany(query);\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\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<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n provider_id: validated.provider_id,\n role_id: validated.role_id,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'identity-provider-role-mapping' });\n }\n\n if (validated.provider) {\n validated.provider_realm_id = validated.provider.realm_id;\n }\n\n if (validated.role) {\n validated.role_realm_id = validated.role.realm_id;\n }\n\n if (\n validated.role_realm_id &&\n validated.provider_realm_id &&\n validated.role_realm_id !== validated.provider_realm_id\n ) {\n throw new BadRequestError('It is not possible to map an identity provider to a role of another realm.');\n }\n\n if (validated.role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: validated.role_id,\n clientId: validated.role.client_id,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n // Stamp the owner (identity-provider) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async update(\n id: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await this.repository.validateJoinColumns(validated);\n\n // `role_id` is immutable on update (CREATE-group only in the validator), so the conferred\n // role never changes here — only the attribute-matching criteria do. Still re-verify the\n // actor OWNS that role before letting it edit (e.g. broaden) the mapping, mirroring create()\n // and the permission-junction member gate (#3164): you may not modify a role-conferring\n // mapping for a role you no longer own.\n const role = await this.roleRepository.findOneById(entity.role_id);\n if (role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: role.id,\n clientId: role.client_id,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n const merged = this.repository.merge(entity, validated);\n\n // Stamp the owner (identity-provider) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(merged),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(merged),\n }),\n });\n\n return this.repository.save(merged);\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // Stamp the owner (identity-provider) realm so the realm_scope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\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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"}
@@ -50,9 +50,9 @@ export declare class PermissionService extends AbstractEntityService implements
50
50
  /**
51
51
  * Assign a newly created permission to all matching realm_admin roles.
52
52
  *
53
- * Uses differentiated junction policies:
54
- * - CUD on global-capable entity types → system.realm-bound
55
- * - Everything else → system.realm-or-global
53
+ * Uses differentiated realm_scope on the junction:
54
+ * - CUD on global-capable entity types → own (strictly own realm)
55
+ * - Everything else → ownOrNull (own realm + null/global resources)
56
56
  *
57
57
  * Eligible permissions:
58
58
  * - Built-in authup permissions (global) — assigned to all realm_admin roles
@@ -61,8 +61,6 @@ export declare class PermissionService extends AbstractEntityService implements
61
61
  * Excluded:
62
62
  * - Realm CRUD permissions (realm_create, realm_update, realm_delete)
63
63
  * - Custom global permissions (non-built-in with realm_id: null)
64
- *
65
- * Fails closed: skips assignment entirely if required policies are not found.
66
64
  */
67
65
  private assignToRealmAdminRoles;
68
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/permission/service.ts"],"names":[],"mappings":"AAUA,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;AA0C5E,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;IA+FI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAwBtB;;;;OAIG;YACW,mBAAmB;IAuBjC;;;OAGG;YACW,iBAAiB;IAuB/B;;;;;;;;;;;;;;;;OAgBG;YACW,uBAAuB;CA4CxC"}
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;AA0C5E,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;IAgGI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC;IAwBtB;;;;OAIG;YACW,mBAAmB;IAuBjC;;;OAGG;YACW,iBAAiB;IAyB/B;;;;;;;;;;;;;;OAcG;YACW,uBAAuB;CAuCxC"}
@@ -4,7 +4,7 @@ import.meta.url;
4
4
  import { ValidatorGroup, isPropertySet, isUUID } from "@authup/kit";
5
5
  import { PermissionName, PermissionValidator, ROLE_ADMIN_NAME, ROLE_REALM_ADMIN_NAME } from "@authup/core-kit";
6
6
  import { AbstractEntityService } from "@authup/server-kit";
7
- import { BuiltInPolicyType, PolicyData, SystemPolicyName } from "@authup/access";
7
+ import { BuiltInPolicyType, RealmScope, SystemPolicyName, definePolicyData } from "@authup/access";
8
8
  import { AuthupError, BadRequestError, EntityNotFoundError } from "@authup/errors";
9
9
  //#region src/core/entities/permission/service.ts
10
10
  const REALM_ADMIN_EXCLUDED_PERMISSIONS = [
@@ -13,14 +13,14 @@ const REALM_ADMIN_EXCLUDED_PERMISSIONS = [
13
13
  PermissionName.REALM_DELETE
14
14
  ];
15
15
  /**
16
- * CUD permissions that get system.realm-bound on realm_admin.
17
- * Covers direct entity types (both global-capable and realm-only).
16
+ * Direct-entity CUD permissions that realm_admin grants at `realm_scope: own`
17
+ * (strictly the actor's own realm see line 372). Every other realm_admin
18
+ * permission defaults to `ownOrNull` (own realm OR global/null resources) so it
19
+ * can act on global building blocks.
18
20
  *
19
- * Junction entity CUD (e.g. user_role, role_permission) intentionally
20
- * use realm-or-global instead, because their attributes include
21
- * multiple realm_id fields (e.g. user_realm_id + role_realm_id).
22
- * With attribute_name_strict: false, realm-bound would reject
23
- * junctions where one side is global (realm_id: null).
21
+ * Junction CUD (e.g. user_role, role_permission) is intentionally NOT listed here:
22
+ * it stays `ownOrNull` because a junction can legitimately reference a global
23
+ * side (realm_id: null) a strict `own` would reject those.
24
24
  */ const REALM_ADMIN_BOUND_PERMISSIONS = [
25
25
  PermissionName.CLIENT_CREATE,
26
26
  PermissionName.CLIENT_UPDATE,
@@ -113,10 +113,13 @@ var PermissionService = class extends AbstractEntityService {
113
113
  if (entity.built_in && isPropertySet(validated, "name") && entity.name !== validated.name) throw new BadRequestError("The name of a built-in permission can not be changed.");
114
114
  await actor.permissionEvaluator.evaluate({
115
115
  name: PermissionName.PERMISSION_UPDATE,
116
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: {
117
- ...entity,
118
- ...validated
119
- } })
116
+ data: definePolicyData({
117
+ [BuiltInPolicyType.ATTRIBUTES]: {
118
+ ...entity,
119
+ ...validated
120
+ },
121
+ [BuiltInPolicyType.REALM_MATCH]: validated.realm_id ?? entity.realm_id ?? null
122
+ })
120
123
  });
121
124
  await this.repository.checkUniqueness(validated, entity);
122
125
  entity = this.repository.merge(entity, validated);
@@ -129,7 +132,10 @@ var PermissionService = class extends AbstractEntityService {
129
132
  if (!isPropertySet(validated, "realm_id") && actor.identity) validated.realm_id = this.getActorRealmId(actor) || null;
130
133
  await actor.permissionEvaluator.evaluate({
131
134
  name: PermissionName.PERMISSION_CREATE,
132
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated })
135
+ data: definePolicyData({
136
+ [BuiltInPolicyType.ATTRIBUTES]: validated,
137
+ ...this.resourceRealmMatch(validated)
138
+ })
133
139
  });
134
140
  await this.repository.checkUniqueness(validated);
135
141
  entity = this.repository.create(validated);
@@ -149,7 +155,10 @@ var PermissionService = class extends AbstractEntityService {
149
155
  if (entity.built_in) throw new BadRequestError("A built-in permission can not be deleted.");
150
156
  await actor.permissionEvaluator.evaluate({
151
157
  name: PermissionName.PERMISSION_DELETE,
152
- input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
158
+ data: definePolicyData({
159
+ [BuiltInPolicyType.ATTRIBUTES]: entity,
160
+ ...this.resourceRealmMatch(entity)
161
+ })
153
162
  });
154
163
  const { id: entityId } = entity;
155
164
  await this.repository.remove(entity);
@@ -189,16 +198,17 @@ var PermissionService = class extends AbstractEntityService {
189
198
  role_id: adminRole.id,
190
199
  role_realm_id: adminRole.realm_id,
191
200
  permission_id: permission.id,
192
- permission_realm_id: permission.realm_id
201
+ permission_realm_id: permission.realm_id,
202
+ realm_scope: RealmScope.ANY
193
203
  });
194
204
  await this.rolePermissionRepository.save(entry);
195
205
  }
196
206
  /**
197
207
  * Assign a newly created permission to all matching realm_admin roles.
198
208
  *
199
- * Uses differentiated junction policies:
200
- * - CUD on global-capable entity types → system.realm-bound
201
- * - Everything else → system.realm-or-global
209
+ * Uses differentiated realm_scope on the junction:
210
+ * - CUD on global-capable entity types → own (strictly own realm)
211
+ * - Everything else → ownOrNull (own realm + null/global resources)
202
212
  *
203
213
  * Eligible permissions:
204
214
  * - Built-in authup permissions (global) — assigned to all realm_admin roles
@@ -207,15 +217,11 @@ var PermissionService = class extends AbstractEntityService {
207
217
  * Excluded:
208
218
  * - Realm CRUD permissions (realm_create, realm_update, realm_delete)
209
219
  * - Custom global permissions (non-built-in with realm_id: null)
210
- *
211
- * Fails closed: skips assignment entirely if required policies are not found.
212
220
  */ async assignToRealmAdminRoles(permission) {
213
221
  if (REALM_ADMIN_EXCLUDED_PERMISSIONS.includes(permission.name)) return;
214
222
  const isBuiltIn = Object.values(PermissionName).includes(permission.name);
215
223
  if (!permission.realm_id && !isBuiltIn) return;
216
- const policyName = REALM_ADMIN_BOUND_PERMISSIONS.includes(permission.name) ? SystemPolicyName.REALM_BOUND : SystemPolicyName.REALM_OR_GLOBAL;
217
- const policy = await this.policyRepository.findOneByName(policyName);
218
- if (!policy) return;
224
+ const realmScope = REALM_ADMIN_BOUND_PERMISSIONS.includes(permission.name) ? RealmScope.OWN : RealmScope.OWN_OR_NULL;
219
225
  const realmAdminRoles = await this.roleRepository.findManyBy({ name: ROLE_REALM_ADMIN_NAME });
220
226
  for (const role of realmAdminRoles) {
221
227
  if (permission.realm_id && permission.realm_id !== role.realm_id) continue;
@@ -228,7 +234,7 @@ var PermissionService = class extends AbstractEntityService {
228
234
  role_realm_id: role.realm_id,
229
235
  permission_id: permission.id,
230
236
  permission_realm_id: permission.realm_id,
231
- policy_id: policy.id
237
+ realm_scope: realmScope
232
238
  });
233
239
  await this.rolePermissionRepository.save(entry);
234
240
  }