@astrale-domains/shell 0.1.6 → 0.1.7

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 (301) hide show
  1. package/README.md +73 -173
  2. package/dist/domain.d.ts +477 -31
  3. package/dist/domain.js +87 -78
  4. package/dist/functions/application/index.js +2 -1
  5. package/dist/functions/application/legacy/index.js +1 -0
  6. package/dist/functions/application/legacy/list-entrypoints.js +8 -0
  7. package/dist/functions/authority/capabilities.js +1 -0
  8. package/dist/functions/authority/composition.js +47 -0
  9. package/dist/functions/authority/index.js +2 -0
  10. package/dist/functions/authority/roles.js +98 -0
  11. package/dist/functions/directory/disconnect-directory.js +35 -0
  12. package/dist/functions/directory/index.js +1 -0
  13. package/dist/functions/group/change-group-membership.js +43 -9
  14. package/dist/functions/group/create-group.js +23 -0
  15. package/dist/functions/group/delete-group.js +33 -0
  16. package/dist/functions/group/deprovision-group.js +27 -0
  17. package/dist/functions/group/group-errors.js +43 -0
  18. package/dist/functions/group/group-membership-errors.js +2 -0
  19. package/dist/functions/group/group.js +51 -0
  20. package/dist/functions/group/index.js +8 -2
  21. package/dist/functions/group/legacy/index.js +1 -0
  22. package/dist/functions/group/legacy/membership.js +60 -0
  23. package/dist/functions/group/membership-laws.js +40 -0
  24. package/dist/functions/group/provision-group.js +33 -0
  25. package/dist/functions/group/update-group.js +55 -0
  26. package/dist/functions/invitation/index.js +2 -0
  27. package/dist/functions/invitation/invitation-errors.js +13 -0
  28. package/dist/functions/invitation/invitation-methods.js +41 -0
  29. package/dist/functions/invitation/send-invitation.js +81 -0
  30. package/dist/functions/user/account.js +35 -0
  31. package/dist/functions/user/create-user.js +45 -0
  32. package/dist/functions/user/deactivate-user.js +19 -0
  33. package/dist/functions/user/delete-user.js +34 -0
  34. package/dist/functions/user/deprovision-user.js +21 -0
  35. package/dist/functions/user/index.js +15 -1
  36. package/dist/functions/user/invite-errors.js +18 -0
  37. package/dist/functions/user/invite-user.js +42 -34
  38. package/dist/functions/user/legacy/claimed-account.js +11 -0
  39. package/dist/functions/user/legacy/index.js +4 -0
  40. package/dist/functions/user/legacy/invite.js +20 -0
  41. package/dist/functions/user/legacy/migrate-accounts.js +98 -0
  42. package/dist/functions/user/legacy/record-profile.js +19 -0
  43. package/dist/functions/user/protect-administrators.js +16 -0
  44. package/dist/functions/user/provision-user.js +70 -0
  45. package/dist/functions/user/reactivate-user.js +19 -0
  46. package/dist/functions/user/read-account.js +12 -0
  47. package/dist/functions/user/request-invitation.js +17 -0
  48. package/dist/functions/user/update-profile.js +22 -0
  49. package/dist/functions/user/update-user.js +68 -0
  50. package/dist/functions/user/user-errors.js +69 -0
  51. package/dist/functions/user/write-account.js +57 -0
  52. package/dist/functions/view-access/index.js +2 -1
  53. package/dist/functions/view-access/{assign-views.js → legacy/assign-views.js} +11 -7
  54. package/dist/functions/view-access/legacy/index.js +1 -0
  55. package/dist/functions/view-access/{view-access-errors.js → legacy/view-access-errors.js} +5 -1
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +3 -1
  58. package/dist/integrations/user-invitation/invite-user-request.d.ts +6 -0
  59. package/dist/legacy/index.js +1 -0
  60. package/dist/legacy/release.js +33 -0
  61. package/dist/mutations/composition/grant-role.js +13 -0
  62. package/dist/mutations/composition/index.js +1 -0
  63. package/dist/mutations/group/legacy/index.js +1 -0
  64. package/dist/mutations/group/legacy/membership-class.js +7 -0
  65. package/dist/mutations/group/set-group-membership.js +23 -14
  66. package/dist/mutations/identity/create-profile.js +37 -0
  67. package/dist/mutations/identity/delete-identity.js +28 -0
  68. package/dist/mutations/identity/index.js +4 -0
  69. package/dist/mutations/identity/write-account.js +109 -0
  70. package/dist/mutations/identity/write-group.js +72 -0
  71. package/dist/mutations/invitation/index.js +1 -0
  72. package/dist/mutations/invitation/write-invitation.js +62 -0
  73. package/dist/mutations/user/legacy/index.js +1 -0
  74. package/dist/mutations/user/{record-user-profile.js → legacy/record-user-profile.js} +5 -2
  75. package/dist/providers/admin-enrollment/create-admin-enrollment-provider.js +6 -3
  76. package/dist/providers/admin-enrollment/legacy/index.js +1 -0
  77. package/dist/providers/admin-enrollment/legacy/send-without-profile.js +16 -0
  78. package/dist/queries/application/legacy/index.js +1 -0
  79. package/dist/queries/application/legacy/read-installed-entrypoints.js +47 -0
  80. package/dist/queries/composition/index.js +2 -0
  81. package/dist/queries/composition/read-extensions.js +34 -0
  82. package/dist/queries/composition/read-role-nodes.js +41 -0
  83. package/dist/queries/group/index.js +1 -1
  84. package/dist/queries/group/legacy/index.js +2 -0
  85. package/dist/queries/group/legacy/read-core-groups.js +46 -0
  86. package/dist/queries/group/legacy/read-member-of-group.js +24 -0
  87. package/dist/queries/group/read-group-membership-endpoints.js +11 -0
  88. package/dist/queries/group/read-group-membership.js +6 -21
  89. package/dist/queries/identity/index.js +1 -0
  90. package/dist/queries/identity/read-identities.js +29 -0
  91. package/dist/queries/invitation/index.js +1 -0
  92. package/dist/queries/invitation/read-invitation.js +25 -0
  93. package/dist/queries/profile/index.js +1 -0
  94. package/dist/queries/profile/read-profile.js +15 -0
  95. package/dist/queries/role/index.js +1 -0
  96. package/dist/queries/role/read-role-node.js +13 -0
  97. package/dist/queries/user/legacy/index.js +1 -0
  98. package/dist/queries/user/legacy/read-user-profile.js +27 -0
  99. package/dist/runtime.d.ts +18203 -630
  100. package/dist/runtime.js +32 -7
  101. package/dist/schema/index.d.ts +7 -4
  102. package/dist/schema/index.js +8 -4
  103. package/dist/schema/legacy/index.js +1 -0
  104. package/dist/schema/legacy/schema.js +32 -0
  105. package/dist/schema/modules/application/legacy/entrypoint-entry.js +11 -0
  106. package/dist/schema/modules/application/legacy/functions/index.js +1 -0
  107. package/dist/schema/modules/application/legacy/functions/list-entrypoints.js +21 -0
  108. package/dist/schema/modules/application/legacy/index.js +2 -0
  109. package/dist/schema/modules/directory/functions/disconnect-directory.d.ts +13 -0
  110. package/dist/schema/modules/directory/functions/disconnect-directory.js +15 -0
  111. package/dist/schema/modules/directory/functions/index.d.ts +1 -0
  112. package/dist/schema/modules/directory/functions/index.js +1 -0
  113. package/dist/schema/modules/directory/index.d.ts +1 -0
  114. package/dist/schema/modules/directory/index.js +1 -0
  115. package/dist/schema/modules/group/classes/group-profile-link.d.ts +34 -0
  116. package/dist/schema/modules/group/classes/group-profile-link.js +21 -0
  117. package/dist/schema/modules/group/classes/group-profile.d.ts +15 -0
  118. package/dist/schema/modules/group/classes/group-profile.js +20 -0
  119. package/dist/schema/modules/group/classes/group.d.ts +73 -1
  120. package/dist/schema/modules/group/classes/group.js +28 -7
  121. package/dist/schema/modules/group/classes/index.d.ts +2 -1
  122. package/dist/schema/modules/group/classes/index.js +3 -1
  123. package/dist/schema/modules/group/functions/assign-member.js +17 -0
  124. package/dist/schema/modules/group/functions/create-group.js +20 -0
  125. package/dist/schema/modules/group/functions/delete-group.js +12 -0
  126. package/dist/schema/modules/group/functions/deprovision-group.js +14 -0
  127. package/dist/schema/modules/group/functions/index.js +7 -2
  128. package/dist/schema/modules/group/functions/provision-group.js +14 -0
  129. package/dist/schema/modules/group/functions/unassign-member.js +17 -0
  130. package/dist/schema/modules/group/functions/update-group.js +20 -0
  131. package/dist/schema/modules/group/index.d.ts +3 -3
  132. package/dist/schema/modules/group/index.js +4 -3
  133. package/dist/schema/modules/group/legacy/admission.d.ts +9 -0
  134. package/dist/schema/modules/group/legacy/admission.js +9 -0
  135. package/dist/schema/modules/group/legacy/classes/index.d.ts +1 -0
  136. package/dist/schema/modules/group/legacy/classes/index.js +1 -0
  137. package/dist/schema/modules/group/{classes → legacy/classes}/member-of-group.d.ts +10 -1
  138. package/dist/schema/modules/group/legacy/classes/member-of-group.js +32 -0
  139. package/dist/schema/modules/group/legacy/core-groups.d.ts +22 -0
  140. package/dist/schema/modules/group/legacy/core-groups.js +28 -0
  141. package/dist/schema/modules/group/legacy/index.d.ts +5 -0
  142. package/dist/schema/modules/group/legacy/index.js +6 -0
  143. package/dist/schema/modules/group/legacy/policies/belongs-to-group.d.ts +5 -0
  144. package/dist/schema/modules/group/legacy/policies/belongs-to-group.js +9 -0
  145. package/dist/schema/modules/group/legacy/policies/index.d.ts +2 -0
  146. package/dist/schema/modules/group/legacy/policies/index.js +2 -0
  147. package/dist/schema/modules/group/legacy/policies/owns-membership-group.d.ts +6 -0
  148. package/dist/schema/modules/group/legacy/policies/owns-membership-group.js +12 -0
  149. package/dist/schema/modules/group/legacy/relaxations.d.ts +21 -0
  150. package/dist/schema/modules/group/legacy/relaxations.js +27 -0
  151. package/dist/schema/modules/group/policies/describes-group-of-subject.d.ts +2 -0
  152. package/dist/schema/modules/group/policies/describes-group-of-subject.js +7 -0
  153. package/dist/schema/modules/group/policies/index.d.ts +2 -1
  154. package/dist/schema/modules/group/policies/index.js +2 -1
  155. package/dist/schema/modules/group/policies/is-group-profile-source.d.ts +2 -0
  156. package/dist/schema/modules/group/policies/is-group-profile-source.js +6 -0
  157. package/dist/schema/modules/group/types/group.js +10 -0
  158. package/dist/schema/modules/group/types/index.js +1 -0
  159. package/dist/schema/modules/invitation/classes/index.js +2 -0
  160. package/dist/schema/modules/invitation/classes/invitation-user.js +17 -0
  161. package/dist/schema/modules/invitation/classes/invitation.js +30 -0
  162. package/dist/schema/modules/invitation/functions/accept.js +16 -0
  163. package/dist/schema/modules/invitation/functions/cancel.js +12 -0
  164. package/dist/schema/modules/invitation/functions/index.js +4 -0
  165. package/dist/schema/modules/invitation/functions/resend.js +12 -0
  166. package/dist/schema/modules/invitation/functions/send.js +20 -0
  167. package/dist/schema/modules/invitation/index.js +2 -0
  168. package/dist/schema/modules/invitation/types/index.js +1 -0
  169. package/dist/schema/modules/invitation/types/invitation-status.js +5 -0
  170. package/dist/schema/modules/namespace/classes/alias.d.ts +2 -1
  171. package/dist/schema/modules/namespace/classes/alias.js +11 -2
  172. package/dist/schema/modules/namespace/functions/link.js +3 -2
  173. package/dist/schema/modules/namespace/functions/rename.js +3 -2
  174. package/dist/schema/modules/namespace/functions/unlink.js +3 -2
  175. package/dist/schema/modules/role/classes/index.d.ts +1 -0
  176. package/dist/schema/modules/role/classes/index.js +1 -0
  177. package/dist/schema/modules/role/classes/role.d.ts +16 -0
  178. package/dist/schema/modules/role/classes/role.js +19 -0
  179. package/dist/schema/modules/role/core/index.d.ts +1 -0
  180. package/dist/schema/modules/role/core/index.js +1 -0
  181. package/dist/schema/modules/role/core/roles.d.ts +37 -0
  182. package/dist/schema/modules/role/core/roles.js +30 -0
  183. package/dist/schema/modules/role/index.d.ts +2 -0
  184. package/dist/schema/modules/role/index.js +2 -0
  185. package/dist/schema/modules/user/classes/index.d.ts +2 -0
  186. package/dist/schema/modules/user/classes/index.js +3 -0
  187. package/dist/schema/modules/user/classes/user-profile-link.d.ts +35 -0
  188. package/dist/schema/modules/user/classes/user-profile-link.js +22 -0
  189. package/dist/schema/modules/user/classes/user-profile.d.ts +41 -0
  190. package/dist/schema/modules/user/classes/user-profile.js +30 -0
  191. package/dist/schema/modules/user/classes/user.d.ts +133 -8
  192. package/dist/schema/modules/user/classes/user.js +46 -15
  193. package/dist/schema/modules/user/functions/create-user.js +21 -0
  194. package/dist/schema/modules/user/functions/deactivate-user.js +12 -0
  195. package/dist/schema/modules/user/functions/delete-user.js +12 -0
  196. package/dist/schema/modules/user/functions/deprovision-user.js +14 -0
  197. package/dist/schema/modules/user/functions/index.js +8 -1
  198. package/dist/schema/modules/user/functions/invite-user.js +23 -4
  199. package/dist/schema/modules/user/functions/provision-user.js +25 -0
  200. package/dist/schema/modules/user/functions/reactivate-user.js +12 -0
  201. package/dist/schema/modules/user/functions/update-profile.js +16 -0
  202. package/dist/schema/modules/user/functions/update-user.js +22 -0
  203. package/dist/schema/modules/user/index.d.ts +2 -1
  204. package/dist/schema/modules/user/index.js +2 -1
  205. package/dist/schema/modules/user/legacy/account-properties.js +24 -0
  206. package/dist/schema/modules/user/legacy/functions/index.js +2 -0
  207. package/dist/schema/modules/user/legacy/functions/migrate-accounts.js +23 -0
  208. package/dist/schema/modules/user/legacy/functions/record-profile.js +18 -0
  209. package/dist/schema/modules/user/legacy/index.js +5 -0
  210. package/dist/schema/modules/user/legacy/invite.js +15 -0
  211. package/dist/schema/modules/user/legacy/relaxations.js +37 -0
  212. package/dist/schema/modules/user/policies/describes-subject.d.ts +2 -0
  213. package/dist/schema/modules/user/policies/describes-subject.js +7 -0
  214. package/dist/schema/modules/user/policies/index.d.ts +2 -0
  215. package/dist/schema/modules/user/policies/index.js +2 -0
  216. package/dist/schema/modules/user/policies/is-profile-source.d.ts +2 -0
  217. package/dist/schema/modules/user/policies/is-profile-source.js +6 -0
  218. package/dist/schema/modules/user/types/account.d.ts +12 -0
  219. package/dist/schema/modules/user/types/account.js +12 -0
  220. package/dist/schema/modules/user/types/index.d.ts +1 -1
  221. package/dist/schema/modules/user/types/index.js +1 -1
  222. package/dist/schema/modules/view-access/classes/view-access.d.ts +7 -11
  223. package/dist/schema/modules/view-access/classes/view-access.js +17 -12
  224. package/dist/schema/modules/view-access/index.d.ts +1 -2
  225. package/dist/schema/modules/view-access/index.js +1 -2
  226. package/dist/schema/modules/view-access/legacy/functions/assign-views.js +22 -0
  227. package/dist/schema/modules/view-access/legacy/functions/index.js +1 -0
  228. package/dist/schema/modules/view-access/legacy/index.js +2 -0
  229. package/dist/schema/modules/view-access/legacy/view-assignment.js +24 -0
  230. package/dist/schema/modules/view-access/policies/holds-view-access.d.ts +2 -0
  231. package/dist/schema/modules/view-access/policies/holds-view-access.js +5 -0
  232. package/dist/schema/modules/view-access/policies/index.d.ts +1 -0
  233. package/dist/schema/modules/view-access/policies/index.js +1 -0
  234. package/dist/schema/policies/has-role.d.ts +6 -0
  235. package/dist/schema/policies/has-role.js +9 -0
  236. package/dist/schema/policies/index.d.ts +1 -0
  237. package/dist/schema/policies/index.js +1 -4
  238. package/dist/schema/policies/legacy/administers-shell-class.js +21 -0
  239. package/dist/schema/policies/legacy/index.js +4 -0
  240. package/dist/schema/policies/legacy/is-self.js +9 -0
  241. package/dist/schema/policies/legacy/owns-class.js +12 -0
  242. package/dist/schema/policies/legacy/uses-function.js +9 -0
  243. package/dist/schema/schema.d.ts +1849 -118
  244. package/dist/schema/schema.js +35 -15
  245. package/dist/schema/types/attributes.js +15 -0
  246. package/dist/schema/types/index.js +1 -0
  247. package/dist/utils/attributes/attributes.js +12 -0
  248. package/dist/utils/attributes/index.js +1 -0
  249. package/dist/utils/index.js +3 -0
  250. package/dist/utils/same-json/index.js +1 -0
  251. package/dist/utils/same-json/same-json.js +9 -0
  252. package/package.json +3 -3
  253. package/dist/functions/application/list-entrypoints.js +0 -6
  254. package/dist/functions/user/record-profile.js +0 -18
  255. package/dist/mutations/user/index.js +0 -1
  256. package/dist/queries/application/index.js +0 -1
  257. package/dist/queries/application/read-installed-entrypoints.js +0 -28
  258. package/dist/queries/user/index.js +0 -1
  259. package/dist/queries/user/read-user-profile.js +0 -9
  260. package/dist/schema/modules/application/functions/index.d.ts +0 -1
  261. package/dist/schema/modules/application/functions/index.js +0 -1
  262. package/dist/schema/modules/application/functions/list-entrypoints.d.ts +0 -15
  263. package/dist/schema/modules/application/functions/list-entrypoints.js +0 -16
  264. package/dist/schema/modules/application/index.d.ts +0 -2
  265. package/dist/schema/modules/application/index.js +0 -2
  266. package/dist/schema/modules/application/types/entrypoint-entry.d.ts +0 -8
  267. package/dist/schema/modules/application/types/entrypoint-entry.js +0 -7
  268. package/dist/schema/modules/application/types/index.d.ts +0 -1
  269. package/dist/schema/modules/application/types/index.js +0 -1
  270. package/dist/schema/modules/group/classes/member-of-group.js +0 -12
  271. package/dist/schema/modules/group/core/administrators-group.d.ts +0 -1
  272. package/dist/schema/modules/group/core/administrators-group.js +0 -6
  273. package/dist/schema/modules/group/core/applications-group.d.ts +0 -1
  274. package/dist/schema/modules/group/core/applications-group.js +0 -6
  275. package/dist/schema/modules/group/core/index.d.ts +0 -3
  276. package/dist/schema/modules/group/core/index.js +0 -3
  277. package/dist/schema/modules/group/core/members-group.d.ts +0 -1
  278. package/dist/schema/modules/group/core/members-group.js +0 -6
  279. package/dist/schema/modules/group/functions/assign-member-to-group.js +0 -11
  280. package/dist/schema/modules/group/functions/unassign-member-from-group.js +0 -11
  281. package/dist/schema/modules/group/policies/belongs-to-group.d.ts +0 -1
  282. package/dist/schema/modules/group/policies/belongs-to-group.js +0 -5
  283. package/dist/schema/modules/user/functions/record-profile.js +0 -14
  284. package/dist/schema/modules/user/types/user-profile.d.ts +0 -7
  285. package/dist/schema/modules/user/types/user-profile.js +0 -7
  286. package/dist/schema/modules/view-access/core/index.d.ts +0 -1
  287. package/dist/schema/modules/view-access/core/index.js +0 -1
  288. package/dist/schema/modules/view-access/core/view-only-group.d.ts +0 -5
  289. package/dist/schema/modules/view-access/core/view-only-group.js +0 -10
  290. package/dist/schema/modules/view-access/functions/assign-views.d.ts +0 -16
  291. package/dist/schema/modules/view-access/functions/assign-views.js +0 -17
  292. package/dist/schema/modules/view-access/functions/index.d.ts +0 -1
  293. package/dist/schema/modules/view-access/functions/index.js +0 -1
  294. package/dist/schema/modules/view-access/types/index.js +0 -1
  295. package/dist/schema/modules/view-access/types/view-assignment.js +0 -16
  296. package/dist/schema/policies/administers-shell-class.js +0 -11
  297. package/dist/schema/policies/is-self.js +0 -5
  298. package/dist/schema/policies/owns-class.js +0 -7
  299. package/dist/schema/policies/uses-function.js +0 -5
  300. /package/dist/functions/group/{assign-member-to-group.js → assign-member.js} +0 -0
  301. /package/dist/functions/group/{unassign-member-from-group.js → unassign-member.js} +0 -0
@@ -0,0 +1,30 @@
1
+ import { K, core } from '@astrale-os/sdk/schema';
2
+ import { Role } from '../classes/role.js';
3
+ const role = (name, description) => core.node(() => Role, {
4
+ [K.classes.Named.properties.name.key]: name,
5
+ [K.classes.Descriptable.properties.description.key]: description,
6
+ });
7
+ /**
8
+ * The two profiles a person is given. Their Core keys carry `workspace.` because the keys `admin` and
9
+ * `member` already name the legacy Administrators and Members groups, and the Kernel recreates a
10
+ * Core Node whose Class changes (AM3). Their bundle, member ⊂ admin, is a release binding (AM1): see
11
+ * `domain.ts`. There is no guest profile (AM10): whoever only opens the Views it is given holds
12
+ * Kernel `reader` and its `view_access`.
13
+ */
14
+ export const profileRoles = {
15
+ 'workspace.member': role('member', 'Opens the workspace and sees accounts and groups.'),
16
+ 'workspace.admin': role('admin', 'A member that manages accounts, groups, roles and Domains.'),
17
+ };
18
+ /** The atomic Shell Roles: what a Domain asks for in its release. */
19
+ export const atomicRoles = {
20
+ 'user.reader': role('user.reader', 'May read every account.'),
21
+ 'user.writer': role('user.writer', 'May create, invite, update, deactivate and delete accounts.'),
22
+ 'group.reader': role('group.reader', 'May read every group.'),
23
+ 'group.writer': role('group.writer', 'May create, update and delete groups and change their members.'),
24
+ 'directory.provisioner': role('directory.provisioner', 'May write what a directory provides.'),
25
+ 'user-profile.reader': role('user-profile.reader', 'May read the name, email and image of every person.'),
26
+ 'user-profile.self-writer': role('user-profile.self-writer', 'May change its own name and image, never its email.'),
27
+ 'group-profile.reader': role('group-profile.reader', 'May read the name, description and image of every group.'),
28
+ };
29
+ export const shellRoles = { ...profileRoles, ...atomicRoles };
30
+ export const PROFILE_NAMES = ['member', 'admin'];
@@ -0,0 +1,2 @@
1
+ export { Role } from './classes/index.js';
2
+ export { atomicRoles, profileRoles, shellRoles, PROFILE_NAMES, type ProfileName, } from './core/index.js';
@@ -0,0 +1,2 @@
1
+ export { Role } from './classes/index.js';
2
+ export { atomicRoles, profileRoles, shellRoles, PROFILE_NAMES, } from './core/index.js';
@@ -1 +1,3 @@
1
1
  export { User } from './user.js';
2
+ export { user_profile } from './user-profile-link.js';
3
+ export { UserProfile } from './user-profile.js';
@@ -1 +1,4 @@
1
1
  export { User } from './user.js';
2
+ // The link first: it loads the profile, whose read rule names a policy over the link.
3
+ export { user_profile } from './user-profile-link.js';
4
+ export { UserProfile } from './user-profile.js';
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The profile of one account, one each way. `0..1` on both ends: the Kernel refuses `detach` on a
3
+ * required end, and accounts stored before profiles lack theirs (`legacyMigrateAccounts` creates
4
+ * them). Shell writes and deletes both together.
5
+ */
6
+ export declare const user_profile: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
7
+ readonly depth: 0;
8
+ readonly abstract: false;
9
+ readonly extends: readonly [];
10
+ readonly properties: never;
11
+ readonly source: {
12
+ readonly as: "user";
13
+ readonly accepts: readonly {
14
+ readonly kind: 'node';
15
+ readonly abstract: false;
16
+ readonly depth: 1;
17
+ readonly properties: "attributes" | "claimedEmail" | "claimedName" | "creationKey" | "directory" | "directoryActive" | "email" | "externalId" | "familyName" | "frozen" | "givenName" | "icon" | "iss" | "name" | "sub" | "suspended";
18
+ readonly methods: "create" | "deactivate" | "delete" | "deprovision" | "invite" | "provision" | "reactivate" | "recordProfile" | "update" | "updateProfile";
19
+ }[];
20
+ readonly outgoing: "0..1";
21
+ };
22
+ readonly target: {
23
+ readonly as: "profile";
24
+ readonly accepts: readonly {
25
+ readonly kind: 'node';
26
+ readonly abstract: false;
27
+ readonly depth: 1;
28
+ readonly properties: "email" | "familyName" | "givenName" | "name";
29
+ readonly methods: never;
30
+ }[];
31
+ readonly incoming: "0..1";
32
+ };
33
+ readonly constraints: Record<never, never>;
34
+ readonly effectiveProperties: never;
35
+ }>;
@@ -0,0 +1,22 @@
1
+ import { edgeClass } from '@astrale-os/sdk/schema';
2
+ import { atomicRoles } from '../../role/index.js';
3
+ import { hasRole } from '../../../policies/index.js';
4
+ import { isProfileSource } from '../policies/index.js';
5
+ import { UserProfile } from './user-profile.js';
6
+ import { User } from './user.js';
7
+ /**
8
+ * The profile of one account, one each way. `0..1` on both ends: the Kernel refuses `detach` on a
9
+ * required end, and accounts stored before profiles lack theirs (`legacyMigrateAccounts` creates
10
+ * them). Shell writes and deletes both together.
11
+ */
12
+ export const user_profile = edgeClass.directed({
13
+ inheritance: 'final',
14
+ abstract: false,
15
+ description: 'The profile of this account.',
16
+ source: { as: 'user', accepts: [User], outgoing: '0..1', onDelete: 'detach' },
17
+ target: { as: 'profile', accepts: [UserProfile], incoming: '0..1', onDelete: 'detach' },
18
+ policies: {
19
+ read: ({ anyOf, check, ref, self }) => anyOf(check(hasRole, ref(atomicRoles['user-profile.reader'])), check(hasRole, ref(atomicRoles['user.writer'])), check(isProfileSource, self)),
20
+ traverse: true,
21
+ },
22
+ });
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The shared part of an account: what others see of a person. Its image waits for the SDK to
3
+ * export the blob type (a blob property breaks the Domain's type declarations). Only Shell writes
4
+ * it, through its methods. It reads by `user-profile.reader`, `user.writer`, or the person whose
5
+ * account it describes.
6
+ */
7
+ export declare const UserProfile: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
8
+ readonly icon: import("@astrale-os/sdk/schema").ClassIcon;
9
+ readonly inheritance: "final";
10
+ readonly abstract: false;
11
+ readonly description: "What others see of a person: name and email.";
12
+ readonly extends: readonly [import("@astrale-os/sdk/schema").KernelClass<"Named">];
13
+ readonly properties: {
14
+ givenName: import("@astrale-os/sdk/schema").AuthoredProperty<{
15
+ readonly type: 'string';
16
+ readonly minLength: 1;
17
+ readonly maxLength: number;
18
+ }, {
19
+ readonly required: false;
20
+ }>;
21
+ familyName: import("@astrale-os/sdk/schema").AuthoredProperty<{
22
+ readonly type: 'string';
23
+ readonly minLength: 1;
24
+ readonly maxLength: number;
25
+ }, {
26
+ readonly required: false;
27
+ }>;
28
+ email: import("@astrale-os/sdk/schema").AuthoredProperty<{
29
+ readonly type: "string";
30
+ readonly minLength: 3;
31
+ readonly maxLength: 100;
32
+ }, {
33
+ readonly required: false;
34
+ }>;
35
+ };
36
+ readonly unique: readonly [readonly ["email"]];
37
+ readonly policies: {
38
+ readonly read: ({ anyOf, check, ref, self }: import("@astrale-os/sdk/schema").ClassRuleContext) => import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").ClassRuleObject>;
39
+ readonly traverse: true;
40
+ };
41
+ }>;
@@ -0,0 +1,30 @@
1
+ import { K, classIcon, nodeClass, property } from '@astrale-os/sdk/schema';
2
+ import { UserRound } from '@astrale-os/sdk/schema/icons';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { describesSubject } from '../policies/index.js';
6
+ const text = (maxLength) => ({ type: 'string', minLength: 1, maxLength });
7
+ /**
8
+ * The shared part of an account: what others see of a person. Its image waits for the SDK to
9
+ * export the blob type (a blob property breaks the Domain's type declarations). Only Shell writes
10
+ * it, through its methods. It reads by `user-profile.reader`, `user.writer`, or the person whose
11
+ * account it describes.
12
+ */
13
+ export const UserProfile = nodeClass({
14
+ icon: classIcon.lucide(UserRound),
15
+ inheritance: 'final',
16
+ abstract: false,
17
+ description: 'What others see of a person: name and email.',
18
+ extends: [K.classes.Named],
19
+ properties: {
20
+ givenName: property(text(100), { required: false }),
21
+ familyName: property(text(100), { required: false }),
22
+ // Lower case, unique; to be confirmed until the account has signed in once.
23
+ email: property({ type: 'string', minLength: 3, maxLength: 100 }, { required: false }),
24
+ },
25
+ unique: [['email']],
26
+ policies: {
27
+ read: ({ anyOf, check, ref, self }) => anyOf(check(hasRole, ref(atomicRoles['user-profile.reader'])), check(hasRole, ref(atomicRoles['user.writer'])), check(describesSubject, self)),
28
+ traverse: true,
29
+ },
30
+ });
@@ -1,20 +1,92 @@
1
- import { z } from 'zod';
1
+ /**
2
+ * The account of one person in the workspace. Only Shell writes it, through its methods: the Class
3
+ * declares no write rule. An account reads by `user.reader` or by its holder (U7); every Path
4
+ * walks through it.
5
+ */
2
6
  export declare const User: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
3
7
  readonly icon: import("@astrale-os/sdk/schema").ClassIcon;
4
8
  readonly inheritance: "open";
9
+ readonly abstract: false;
10
+ readonly description: "The account of one person in the workspace.";
11
+ readonly extends: readonly [import("@astrale-os/sdk/schema").KernelClass<"Identity">, import("@astrale-os/sdk/schema").KernelClass<"Iconable">];
12
+ readonly properties: {
13
+ readonly creationKey: import("zod").ZodOptional<import("zod").ZodString>;
14
+ readonly claimedEmail: import("zod").ZodOptional<import("zod").ZodString>;
15
+ readonly claimedName: import("zod").ZodOptional<import("zod").ZodString>;
16
+ readonly suspended: import("zod").ZodOptional<import("zod").ZodBoolean>;
17
+ readonly directoryActive: import("zod").ZodOptional<import("zod").ZodBoolean>;
18
+ readonly name: import("@astrale-os/sdk/schema").AuthoredProperty<{
19
+ readonly type: "string";
20
+ readonly minLength: 1;
21
+ readonly maxLength: 100;
22
+ }, {
23
+ readonly required: false;
24
+ }>;
25
+ readonly email: import("@astrale-os/sdk/schema").AuthoredProperty<{
26
+ readonly type: "string";
27
+ readonly minLength: 3;
28
+ readonly maxLength: 320;
29
+ }, {
30
+ readonly required: false;
31
+ }>;
32
+ readonly givenName: import("@astrale-os/sdk/schema").AuthoredProperty<{
33
+ readonly type: 'string';
34
+ readonly minLength: 1;
35
+ readonly maxLength: number;
36
+ }, {
37
+ readonly required: false;
38
+ }>;
39
+ readonly familyName: import("@astrale-os/sdk/schema").AuthoredProperty<{
40
+ readonly type: 'string';
41
+ readonly minLength: 1;
42
+ readonly maxLength: number;
43
+ }, {
44
+ readonly required: false;
45
+ }>;
46
+ readonly directory: import("@astrale-os/sdk/schema").AuthoredProperty<{
47
+ readonly type: 'string';
48
+ readonly minLength: 1;
49
+ readonly maxLength: number;
50
+ }, {
51
+ readonly required: false;
52
+ }>;
53
+ readonly externalId: import("@astrale-os/sdk/schema").AuthoredProperty<{
54
+ readonly type: 'string';
55
+ readonly minLength: 1;
56
+ readonly maxLength: number;
57
+ }, {
58
+ readonly required: false;
59
+ }>;
60
+ readonly attributes: import("@astrale-os/sdk/schema").AuthoredProperty<{
61
+ readonly type: "object";
62
+ readonly additionalProperties: true;
63
+ readonly maxProperties: 64;
64
+ }, {
65
+ readonly required: false;
66
+ }>;
67
+ };
5
68
  readonly policies: {
6
69
  readonly read: true;
7
- };
8
- readonly extends: readonly [import("@astrale-os/sdk/schema").KernelClass<"Identity">];
9
- readonly properties: {
10
- readonly creationKey: z.ZodOptional<z.ZodString>;
11
- readonly claimedEmail: z.ZodOptional<z.ZodString>;
12
- readonly claimedName: z.ZodOptional<z.ZodString>;
70
+ readonly traverse: true;
13
71
  };
14
72
  readonly methods: {
73
+ readonly create: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
74
+ email: string;
75
+ name: string;
76
+ givenName?: string | undefined;
77
+ familyName?: string | undefined;
78
+ attributes?: Record<string, unknown> | undefined;
79
+ }, {
80
+ readonly mode: 'value';
81
+ readonly value: {
82
+ user: string;
83
+ created: boolean;
84
+ };
85
+ }, "authorized", true, false, undefined, undefined>>;
15
86
  readonly invite: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
87
+ email?: string | undefined;
16
88
  user: string;
17
- email: string;
89
+ profile?: "admin" | "member" | undefined;
18
90
  }, {
19
91
  readonly mode: 'value';
20
92
  readonly value: {
@@ -23,6 +95,59 @@ export declare const User: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
23
95
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
24
96
  };
25
97
  }, "authorized", true, false, undefined, undefined>>;
98
+ readonly update: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
99
+ name?: string | undefined;
100
+ email?: string | undefined;
101
+ givenName?: string | null | undefined;
102
+ familyName?: string | null | undefined;
103
+ icon?: string | null | undefined;
104
+ attributes?: Record<string, unknown> | null | undefined;
105
+ }, {
106
+ readonly mode: 'value';
107
+ readonly value: Record<string, never>;
108
+ }, "authorized", false, false, undefined, undefined>>;
109
+ readonly updateProfile: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
110
+ name?: string | undefined;
111
+ icon?: string | null | undefined;
112
+ }, {
113
+ readonly mode: 'value';
114
+ readonly value: Record<string, never>;
115
+ }, "authorized", false, false, undefined, undefined>>;
116
+ readonly deactivate: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
117
+ readonly mode: 'value';
118
+ readonly value: Record<string, never>;
119
+ }, "authorized", false, false, undefined, undefined>>;
120
+ readonly reactivate: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
121
+ readonly mode: 'value';
122
+ readonly value: Record<string, never>;
123
+ }, "authorized", false, false, undefined, undefined>>;
124
+ readonly delete: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
125
+ readonly mode: 'value';
126
+ readonly value: Record<string, never>;
127
+ }, "authorized", false, false, undefined, undefined>>;
128
+ readonly provision: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
129
+ directory: string;
130
+ externalId: string;
131
+ email: string;
132
+ name: string;
133
+ givenName?: string | undefined;
134
+ familyName?: string | undefined;
135
+ active: boolean;
136
+ }, {
137
+ readonly mode: 'value';
138
+ readonly value: {
139
+ user: string;
140
+ created: boolean;
141
+ adopted: boolean;
142
+ };
143
+ }, "authorized", true, false, undefined, undefined>>;
144
+ readonly deprovision: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
145
+ directory: string;
146
+ externalId: string;
147
+ }, {
148
+ readonly mode: 'value';
149
+ readonly value: Record<string, never>;
150
+ }, "authorized", true, false, undefined, undefined>>;
26
151
  readonly recordProfile: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
27
152
  email?: string | undefined;
28
153
  displayName?: string | undefined;
@@ -1,21 +1,52 @@
1
- import { K, classIcon, nodeClass } from '@astrale-os/sdk/schema';
1
+ import { classIcon, nodeClass, property } from '@astrale-os/sdk/schema';
2
2
  import { UserRound } from '@astrale-os/sdk/schema/icons';
3
- import { z } from 'zod';
4
- import { invite, recordProfile } from '../functions/index.js';
5
- import { userDisplayName, userEmail } from '../types/index.js';
6
- // Correlation for Admin-owned creation; never an authentication credential.
7
- const creationKey = z.string().min(1).max(512).optional();
3
+ import { attributesProperty } from '../../../types/index.js';
4
+ import { create, deactivate, deprovision, invite, provision, reactivate, remove, update, updateProfile, } from '../functions/index.js';
5
+ // Seams L-SHELL-1…5: the relaxations and members existing accounts and callers still need.
6
+ import { LEGACY_ACCOUNT_PROPERTIES_OPTIONAL, LEGACY_USER_EXTENDS, LEGACY_USER_INHERITANCE, LEGACY_USER_READ, legacyAccountProperties, legacyAccountStateProperties, legacyRecordProfile, legacyUserName, } from '../legacy/index.js';
7
+ const text = (maxLength) => ({ type: 'string', minLength: 1, maxLength });
8
+ /**
9
+ * The account of one person in the workspace. Only Shell writes it, through its methods: the Class
10
+ * declares no write rule. An account reads by `user.reader` or by its holder (U7); every Path
11
+ * walks through it.
12
+ */
8
13
  export const User = nodeClass({
9
14
  icon: classIcon.lucide(UserRound),
10
- // Domains that depend on Shell extend it with the accounts they own.
11
- inheritance: 'open',
12
- policies: { read: true },
13
- extends: [K.classes.Identity],
15
+ inheritance: LEGACY_USER_INHERITANCE,
16
+ abstract: false,
17
+ description: 'The account of one person in the workspace.',
18
+ extends: LEGACY_USER_EXTENDS,
14
19
  properties: {
15
- creationKey,
16
- // Named apart from any profile a Domain extending User declares (`email`, `displayName`…).
17
- claimedEmail: userEmail.optional(),
18
- claimedName: userDisplayName.optional(),
20
+ // astrale-disable-next-line NODE-INHERITED -- L-SHELL-2: Named.name until stored accounts have it
21
+ name: legacyUserName,
22
+ // Written in lower case; it binds the first sign-in to the account (U8).
23
+ email: property({ type: 'string', minLength: 3, maxLength: 320 }, LEGACY_ACCOUNT_PROPERTIES_OPTIONAL),
24
+ givenName: property(text(100), { required: false }),
25
+ familyName: property(text(100), { required: false }),
26
+ // The WorkOS directory that provides the account, and its id there. Absent: a local account.
27
+ directory: property(text(200), { required: false }),
28
+ externalId: property(text(200), { required: false }),
29
+ // Free JSON a Domain or an admin attaches to the account (AM11).
30
+ attributes: attributesProperty(),
31
+ ...legacyAccountProperties,
32
+ ...legacyAccountStateProperties,
33
+ },
34
+ // L-SHELL-19: no unique constraint and an open read, as Domains built against the released
35
+ // Shell expect.
36
+ policies: {
37
+ read: LEGACY_USER_READ,
38
+ traverse: true,
39
+ },
40
+ methods: {
41
+ create,
42
+ invite,
43
+ update,
44
+ updateProfile,
45
+ deactivate,
46
+ reactivate,
47
+ delete: remove,
48
+ provision,
49
+ deprovision,
50
+ recordProfile: legacyRecordProfile,
19
51
  },
20
- methods: { invite, recordProfile },
21
52
  });
@@ -0,0 +1,21 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { attributesInput } from '../../../types/index.js';
6
+ import { accountEmailInput, nodeReference, personName } from '../types/index.js';
7
+ /** Create the account of an email, or return the one that already has it (U1). */
8
+ export const create = method({
9
+ static: true,
10
+ description: 'Create the account of an email, or return the account that already has it.',
11
+ auth: 'authorized',
12
+ input: z.strictObject({
13
+ email: accountEmailInput,
14
+ name: personName,
15
+ givenName: personName.optional(),
16
+ familyName: personName.optional(),
17
+ attributes: attributesInput.optional(),
18
+ }),
19
+ output: z.object({ user: nodeReference, created: z.boolean() }),
20
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['user.writer'])),
21
+ });
@@ -0,0 +1,12 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ /** Deactivate this account: it can no longer sign in (U2, U4, U5). */
6
+ export const deactivate = method({
7
+ description: 'Deactivate this account: it can no longer sign in (U2, U4, U5).',
8
+ auth: 'authorized',
9
+ input: z.strictObject({}),
10
+ output: z.object({}),
11
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['user.writer'])),
12
+ });
@@ -0,0 +1,12 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ /** Delete this deactivated account and its memberships (U4, U6). */
6
+ export const remove = method({
7
+ description: 'Delete this deactivated account and its memberships (U4, U6).',
8
+ auth: 'authorized',
9
+ input: z.strictObject({}),
10
+ output: z.object({}),
11
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['user.writer'])),
12
+ });
@@ -0,0 +1,14 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { directoryId, externalId } from '../types/index.js';
6
+ /** The directory deleted the account: it stays, frozen, with its history . */
7
+ export const deprovision = method({
8
+ static: true,
9
+ description: 'Freeze the account a directory deleted, keeping it and its history.',
10
+ auth: 'authorized',
11
+ input: z.strictObject({ directory: directoryId, externalId }),
12
+ output: z.object({}),
13
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['directory.provisioner'])),
14
+ });
@@ -1,2 +1,9 @@
1
+ export { create } from './create-user.js';
1
2
  export { invite } from './invite-user.js';
2
- export { recordProfile } from './record-profile.js';
3
+ export { update } from './update-user.js';
4
+ export { updateProfile } from './update-profile.js';
5
+ export { deactivate } from './deactivate-user.js';
6
+ export { reactivate } from './reactivate-user.js';
7
+ export { remove } from './delete-user.js';
8
+ export { provision } from './provision-user.js';
9
+ export { deprovision } from './deprovision-user.js';
@@ -1,12 +1,31 @@
1
1
  import { method, path } from '@astrale-os/sdk/schema';
2
2
  import { z } from 'zod';
3
- import { ownsClass, administersShellClass } from '../../../policies/index.js';
4
- import { User } from '../classes/index.js';
3
+ import { PROFILE_NAMES, atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { User } from '../classes/user.js';
6
+ import { legacyInviteFields, legacyInviteOwnerAdmission } from '../legacy/index.js';
5
7
  import { invitationSummary } from '../types/index.js';
8
+ /**
9
+ * Grant an account a profile, `member` by default, and have Admin send its invitation to the email
10
+ * the account holds. Only a holder of `workspace.admin` grants `admin`.
11
+ *
12
+ * @deprecated The invitation of Admin and 1Pact before durable invitations: it answers at once and
13
+ * keeps no invitation (L-SHELL-18). Replaced by `Invitation.send`, a durable run that keeps an
14
+ * `Invitation` until it is accepted, cancelled or expired. Removal: Shell major (delivery step 5),
15
+ * once Admin (step 2) and 1Pact (step 4) call `Invitation.send`.
16
+ */
6
17
  export const invite = method({
7
18
  static: true,
19
+ description: 'Grant an account its profile and have Admin send its invitation.',
8
20
  auth: 'authorized',
9
- input: z.object({ user: path(() => User), email: z.string().min(3).max(320) }),
21
+ input: z.strictObject({
22
+ user: path(() => User),
23
+ profile: z.enum(PROFILE_NAMES).optional(),
24
+ // Seam L-SHELL-6: the `{ user, email }` form of callers older than profiles.
25
+ ...legacyInviteFields,
26
+ }),
10
27
  output: invitationSummary,
11
- policy: ({ anyOf, check, input }) => anyOf(check(administersShellClass, input.user), check(ownsClass, input.user)),
28
+ policy: (context) => context.anyOf(context.check(hasRole, context.ref(atomicRoles['user.writer'])),
29
+ // Seam L-SHELL-9: a Domain that extends User invites the accounts of its own Class.
30
+ legacyInviteOwnerAdmission(context, context.input.user)),
12
31
  });
@@ -0,0 +1,25 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { accountEmailInput, directoryId, externalId, nodeReference, personName, } from '../types/index.js';
6
+ /**
7
+ * Write the account a directory provides: create it, adopt the account of its email (A2), or update
8
+ * it. Replaying the same event changes nothing (A3); a conflict refuses it whole (A4).
9
+ */
10
+ export const provision = method({
11
+ static: true,
12
+ description: 'Create, adopt or update the account a directory provides.',
13
+ auth: 'authorized',
14
+ input: z.strictObject({
15
+ directory: directoryId,
16
+ externalId,
17
+ email: accountEmailInput,
18
+ name: personName,
19
+ givenName: personName.optional(),
20
+ familyName: personName.optional(),
21
+ active: z.boolean(),
22
+ }),
23
+ output: z.object({ user: nodeReference, created: z.boolean(), adopted: z.boolean() }),
24
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['directory.provisioner'])),
25
+ });
@@ -0,0 +1,12 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ /** Reactivate this account (U4). */
6
+ export const reactivate = method({
7
+ description: 'Reactivate this account (U4).',
8
+ auth: 'authorized',
9
+ input: z.strictObject({}),
10
+ output: z.object({}),
11
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['user.writer'])),
12
+ });
@@ -0,0 +1,16 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { accountIcon, personName } from '../types/index.js';
6
+ /**
7
+ * The holder changes its own name or icon (U3), once an administrator lets members do so: it holds
8
+ * `user-profile.self-writer` (« Les membres modifient leur profil »).
9
+ */
10
+ export const updateProfile = method({
11
+ description: 'Change your own name or icon.',
12
+ auth: 'authorized',
13
+ input: z.strictObject({ name: personName.optional(), icon: accountIcon.optional() }),
14
+ output: z.object({}),
15
+ policy: ({ allOf, check, ref, self }) => allOf(check(hasRole, self), check(hasRole, ref(atomicRoles['user-profile.self-writer']))),
16
+ });
@@ -0,0 +1,22 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { atomicRoles } from '../../role/index.js';
4
+ import { hasRole } from '../../../policies/index.js';
5
+ import { attributesInput } from '../../../types/index.js';
6
+ import { accountEmailInput, accountIcon, personName } from '../types/index.js';
7
+ /** Change the name, the email, the icon or the attributes of this account (U1, U3, U4, AM11). */
8
+ export const update = method({
9
+ description: 'Change the name, the email, the icon or the attributes of this account.',
10
+ auth: 'authorized',
11
+ input: z.strictObject({
12
+ name: personName.optional(),
13
+ email: accountEmailInput.optional(),
14
+ givenName: personName.nullable().optional(),
15
+ familyName: personName.nullable().optional(),
16
+ icon: accountIcon.optional(),
17
+ // Replaces them all; `null` erases them (AM11).
18
+ attributes: attributesInput.nullable().optional(),
19
+ }),
20
+ output: z.object({}),
21
+ policy: ({ check, ref }) => check(hasRole, ref(atomicRoles['user.writer'])),
22
+ });
@@ -1,2 +1,3 @@
1
- export { User } from './classes/index.js';
1
+ export { User, UserProfile, user_profile } from './classes/index.js';
2
+ export { describesSubject, isProfileSource } from './policies/index.js';
2
3
  export { invitationSummary, type InvitationSummary } from './types/index.js';
@@ -1,2 +1,3 @@
1
- export { User } from './classes/index.js';
1
+ export { User, UserProfile, user_profile } from './classes/index.js';
2
+ export { describesSubject, isProfileSource } from './policies/index.js';
2
3
  export { invitationSummary } from './types/index.js';