@jini-ai/cms 0.1.0

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 (527) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +84 -0
  3. package/dist/content-types/agent-tools.d.ts +65 -0
  4. package/dist/content-types/agent-tools.d.ts.map +1 -0
  5. package/dist/content-types/agent-tools.js +172 -0
  6. package/dist/content-types/agent-tools.js.map +1 -0
  7. package/dist/content-types/cleanup.d.ts +118 -0
  8. package/dist/content-types/cleanup.d.ts.map +1 -0
  9. package/dist/content-types/cleanup.js +65 -0
  10. package/dist/content-types/cleanup.js.map +1 -0
  11. package/dist/content-types/errors.d.ts +90 -0
  12. package/dist/content-types/errors.d.ts.map +1 -0
  13. package/dist/content-types/errors.js +119 -0
  14. package/dist/content-types/errors.js.map +1 -0
  15. package/dist/content-types/field-defs.d.ts +25 -0
  16. package/dist/content-types/field-defs.d.ts.map +1 -0
  17. package/dist/content-types/field-defs.js +155 -0
  18. package/dist/content-types/field-defs.js.map +1 -0
  19. package/dist/content-types/index-provisioning.d.ts +94 -0
  20. package/dist/content-types/index-provisioning.d.ts.map +1 -0
  21. package/dist/content-types/index-provisioning.js +133 -0
  22. package/dist/content-types/index-provisioning.js.map +1 -0
  23. package/dist/content-types/index.d.ts +63 -0
  24. package/dist/content-types/index.d.ts.map +1 -0
  25. package/dist/content-types/index.js +36 -0
  26. package/dist/content-types/index.js.map +1 -0
  27. package/dist/content-types/lifecycle-dispatch.d.ts +38 -0
  28. package/dist/content-types/lifecycle-dispatch.d.ts.map +1 -0
  29. package/dist/content-types/lifecycle-dispatch.js +28 -0
  30. package/dist/content-types/lifecycle-dispatch.js.map +1 -0
  31. package/dist/content-types/lifecycle.d.ts +104 -0
  32. package/dist/content-types/lifecycle.d.ts.map +1 -0
  33. package/dist/content-types/lifecycle.js +143 -0
  34. package/dist/content-types/lifecycle.js.map +1 -0
  35. package/dist/content-types/list.d.ts +44 -0
  36. package/dist/content-types/list.d.ts.map +1 -0
  37. package/dist/content-types/list.js +13 -0
  38. package/dist/content-types/list.js.map +1 -0
  39. package/dist/content-types/repo.memory.d.ts +72 -0
  40. package/dist/content-types/repo.memory.d.ts.map +1 -0
  41. package/dist/content-types/repo.memory.js +71 -0
  42. package/dist/content-types/repo.memory.js.map +1 -0
  43. package/dist/content-types/tool-registrations.d.ts +65 -0
  44. package/dist/content-types/tool-registrations.d.ts.map +1 -0
  45. package/dist/content-types/tool-registrations.js +180 -0
  46. package/dist/content-types/tool-registrations.js.map +1 -0
  47. package/dist/content-types/types.d.ts +78 -0
  48. package/dist/content-types/types.d.ts.map +1 -0
  49. package/dist/content-types/types.js +32 -0
  50. package/dist/content-types/types.js.map +1 -0
  51. package/dist/content-types/write-service.d.ts +141 -0
  52. package/dist/content-types/write-service.d.ts.map +1 -0
  53. package/dist/content-types/write-service.js +180 -0
  54. package/dist/content-types/write-service.js.map +1 -0
  55. package/dist/core/commands/change-set.d.ts +98 -0
  56. package/dist/core/commands/change-set.d.ts.map +1 -0
  57. package/dist/core/commands/change-set.js +2 -0
  58. package/dist/core/commands/change-set.js.map +1 -0
  59. package/dist/core/commands/command.d.ts +168 -0
  60. package/dist/core/commands/command.d.ts.map +1 -0
  61. package/dist/core/commands/command.js +173 -0
  62. package/dist/core/commands/command.js.map +1 -0
  63. package/dist/core/index.d.ts +45 -0
  64. package/dist/core/index.d.ts.map +1 -0
  65. package/dist/core/index.js +43 -0
  66. package/dist/core/index.js.map +1 -0
  67. package/dist/core/ports.d.ts +139 -0
  68. package/dist/core/ports.d.ts.map +1 -0
  69. package/dist/core/ports.js +2 -0
  70. package/dist/core/ports.js.map +1 -0
  71. package/dist/core/tools/registration-kit.d.ts +308 -0
  72. package/dist/core/tools/registration-kit.d.ts.map +1 -0
  73. package/dist/core/tools/registration-kit.js +381 -0
  74. package/dist/core/tools/registration-kit.js.map +1 -0
  75. package/dist/entries/agent-tools.d.ts +78 -0
  76. package/dist/entries/agent-tools.d.ts.map +1 -0
  77. package/dist/entries/agent-tools.js +158 -0
  78. package/dist/entries/agent-tools.js.map +1 -0
  79. package/dist/entries/errors.d.ts +43 -0
  80. package/dist/entries/errors.d.ts.map +1 -0
  81. package/dist/entries/errors.js +59 -0
  82. package/dist/entries/errors.js.map +1 -0
  83. package/dist/entries/field-validation.d.ts +70 -0
  84. package/dist/entries/field-validation.d.ts.map +1 -0
  85. package/dist/entries/field-validation.js +87 -0
  86. package/dist/entries/field-validation.js.map +1 -0
  87. package/dist/entries/index.d.ts +55 -0
  88. package/dist/entries/index.d.ts.map +1 -0
  89. package/dist/entries/index.js +38 -0
  90. package/dist/entries/index.js.map +1 -0
  91. package/dist/entries/lifecycle-dispatch.d.ts +15 -0
  92. package/dist/entries/lifecycle-dispatch.d.ts.map +1 -0
  93. package/dist/entries/lifecycle-dispatch.js +16 -0
  94. package/dist/entries/lifecycle-dispatch.js.map +1 -0
  95. package/dist/entries/list.d.ts +47 -0
  96. package/dist/entries/list.d.ts.map +1 -0
  97. package/dist/entries/list.js +12 -0
  98. package/dist/entries/list.js.map +1 -0
  99. package/dist/entries/repo.memory.d.ts +64 -0
  100. package/dist/entries/repo.memory.d.ts.map +1 -0
  101. package/dist/entries/repo.memory.js +73 -0
  102. package/dist/entries/repo.memory.js.map +1 -0
  103. package/dist/entries/tool-registrations.d.ts +52 -0
  104. package/dist/entries/tool-registrations.d.ts.map +1 -0
  105. package/dist/entries/tool-registrations.js +141 -0
  106. package/dist/entries/tool-registrations.js.map +1 -0
  107. package/dist/entries/types.d.ts +55 -0
  108. package/dist/entries/types.d.ts.map +1 -0
  109. package/dist/entries/types.js +2 -0
  110. package/dist/entries/types.js.map +1 -0
  111. package/dist/entries/write-service.d.ts +202 -0
  112. package/dist/entries/write-service.d.ts.map +1 -0
  113. package/dist/entries/write-service.js +204 -0
  114. package/dist/entries/write-service.js.map +1 -0
  115. package/dist/identity/admin-crud-service.d.ts +252 -0
  116. package/dist/identity/admin-crud-service.d.ts.map +1 -0
  117. package/dist/identity/admin-crud-service.js +437 -0
  118. package/dist/identity/admin-crud-service.js.map +1 -0
  119. package/dist/identity/agent-tool-input.d.ts +58 -0
  120. package/dist/identity/agent-tool-input.d.ts.map +1 -0
  121. package/dist/identity/agent-tool-input.js +126 -0
  122. package/dist/identity/agent-tool-input.js.map +1 -0
  123. package/dist/identity/agent-tools.d.ts +101 -0
  124. package/dist/identity/agent-tools.d.ts.map +1 -0
  125. package/dist/identity/agent-tools.js +290 -0
  126. package/dist/identity/agent-tools.js.map +1 -0
  127. package/dist/identity/auth-service.d.ts +87 -0
  128. package/dist/identity/auth-service.d.ts.map +1 -0
  129. package/dist/identity/auth-service.js +141 -0
  130. package/dist/identity/auth-service.js.map +1 -0
  131. package/dist/identity/authorize.d.ts +90 -0
  132. package/dist/identity/authorize.d.ts.map +1 -0
  133. package/dist/identity/authorize.js +94 -0
  134. package/dist/identity/authorize.js.map +1 -0
  135. package/dist/identity/grant-service.d.ts +198 -0
  136. package/dist/identity/grant-service.d.ts.map +1 -0
  137. package/dist/identity/grant-service.js +361 -0
  138. package/dist/identity/grant-service.js.map +1 -0
  139. package/dist/identity/hasher.d.ts +39 -0
  140. package/dist/identity/hasher.d.ts.map +1 -0
  141. package/dist/identity/hasher.js +39 -0
  142. package/dist/identity/hasher.js.map +1 -0
  143. package/dist/identity/index.d.ts +59 -0
  144. package/dist/identity/index.d.ts.map +1 -0
  145. package/dist/identity/index.js +51 -0
  146. package/dist/identity/index.js.map +1 -0
  147. package/dist/identity/password-policy.d.ts +58 -0
  148. package/dist/identity/password-policy.d.ts.map +1 -0
  149. package/dist/identity/password-policy.js +67 -0
  150. package/dist/identity/password-policy.js.map +1 -0
  151. package/dist/identity/permission-migrations.d.ts +86 -0
  152. package/dist/identity/permission-migrations.d.ts.map +1 -0
  153. package/dist/identity/permission-migrations.js +67 -0
  154. package/dist/identity/permission-migrations.js.map +1 -0
  155. package/dist/identity/permissions.d.ts +35 -0
  156. package/dist/identity/permissions.d.ts.map +1 -0
  157. package/dist/identity/permissions.js +603 -0
  158. package/dist/identity/permissions.js.map +1 -0
  159. package/dist/identity/ports.d.ts +201 -0
  160. package/dist/identity/ports.d.ts.map +1 -0
  161. package/dist/identity/ports.js +2 -0
  162. package/dist/identity/ports.js.map +1 -0
  163. package/dist/identity/repo.memory.d.ts +164 -0
  164. package/dist/identity/repo.memory.d.ts.map +1 -0
  165. package/dist/identity/repo.memory.js +224 -0
  166. package/dist/identity/repo.memory.js.map +1 -0
  167. package/dist/identity/seed.d.ts +42 -0
  168. package/dist/identity/seed.d.ts.map +1 -0
  169. package/dist/identity/seed.js +277 -0
  170. package/dist/identity/seed.js.map +1 -0
  171. package/dist/identity/tool-registrations.d.ts +50 -0
  172. package/dist/identity/tool-registrations.d.ts.map +1 -0
  173. package/dist/identity/tool-registrations.js +419 -0
  174. package/dist/identity/tool-registrations.js.map +1 -0
  175. package/dist/identity/types.d.ts +185 -0
  176. package/dist/identity/types.d.ts.map +1 -0
  177. package/dist/identity/types.js +64 -0
  178. package/dist/identity/types.js.map +1 -0
  179. package/dist/identity/username.d.ts +12 -0
  180. package/dist/identity/username.d.ts.map +1 -0
  181. package/dist/identity/username.js +14 -0
  182. package/dist/identity/username.js.map +1 -0
  183. package/dist/media/agent-tools.d.ts +66 -0
  184. package/dist/media/agent-tools.d.ts.map +1 -0
  185. package/dist/media/agent-tools.js +131 -0
  186. package/dist/media/agent-tools.js.map +1 -0
  187. package/dist/media/blob-gc-lock.d.ts +37 -0
  188. package/dist/media/blob-gc-lock.d.ts.map +1 -0
  189. package/dist/media/blob-gc-lock.js +55 -0
  190. package/dist/media/blob-gc-lock.js.map +1 -0
  191. package/dist/media/blob-gc.d.ts +246 -0
  192. package/dist/media/blob-gc.d.ts.map +1 -0
  193. package/dist/media/blob-gc.js +254 -0
  194. package/dist/media/blob-gc.js.map +1 -0
  195. package/dist/media/blob-key.d.ts +28 -0
  196. package/dist/media/blob-key.d.ts.map +1 -0
  197. package/dist/media/blob-key.js +11 -0
  198. package/dist/media/blob-key.js.map +1 -0
  199. package/dist/media/blob-store.fs.d.ts +23 -0
  200. package/dist/media/blob-store.fs.d.ts.map +1 -0
  201. package/dist/media/blob-store.fs.js +48 -0
  202. package/dist/media/blob-store.fs.js.map +1 -0
  203. package/dist/media/blob-store.memory.d.ts +22 -0
  204. package/dist/media/blob-store.memory.d.ts.map +1 -0
  205. package/dist/media/blob-store.memory.js +23 -0
  206. package/dist/media/blob-store.memory.js.map +1 -0
  207. package/dist/media/content-type-sniffer.d.ts +49 -0
  208. package/dist/media/content-type-sniffer.d.ts.map +1 -0
  209. package/dist/media/content-type-sniffer.js +141 -0
  210. package/dist/media/content-type-sniffer.js.map +1 -0
  211. package/dist/media/image-transformer.d.ts +45 -0
  212. package/dist/media/image-transformer.d.ts.map +1 -0
  213. package/dist/media/image-transformer.js +23 -0
  214. package/dist/media/image-transformer.js.map +1 -0
  215. package/dist/media/image-transformer.sharp.d.ts +26 -0
  216. package/dist/media/image-transformer.sharp.d.ts.map +1 -0
  217. package/dist/media/image-transformer.sharp.js +91 -0
  218. package/dist/media/image-transformer.sharp.js.map +1 -0
  219. package/dist/media/index.d.ts +43 -0
  220. package/dist/media/index.d.ts.map +1 -0
  221. package/dist/media/index.js +31 -0
  222. package/dist/media/index.js.map +1 -0
  223. package/dist/media/media-service.d.ts +244 -0
  224. package/dist/media/media-service.d.ts.map +1 -0
  225. package/dist/media/media-service.js +345 -0
  226. package/dist/media/media-service.js.map +1 -0
  227. package/dist/media/ports.d.ts +142 -0
  228. package/dist/media/ports.d.ts.map +1 -0
  229. package/dist/media/ports.js +2 -0
  230. package/dist/media/ports.js.map +1 -0
  231. package/dist/media/rendition-service.d.ts +66 -0
  232. package/dist/media/rendition-service.d.ts.map +1 -0
  233. package/dist/media/rendition-service.js +135 -0
  234. package/dist/media/rendition-service.js.map +1 -0
  235. package/dist/media/repo.memory.d.ts +107 -0
  236. package/dist/media/repo.memory.d.ts.map +1 -0
  237. package/dist/media/repo.memory.js +131 -0
  238. package/dist/media/repo.memory.js.map +1 -0
  239. package/dist/media/tool-registrations.d.ts +42 -0
  240. package/dist/media/tool-registrations.d.ts.map +1 -0
  241. package/dist/media/tool-registrations.js +121 -0
  242. package/dist/media/tool-registrations.js.map +1 -0
  243. package/dist/media/transform-lock.d.ts +36 -0
  244. package/dist/media/transform-lock.d.ts.map +1 -0
  245. package/dist/media/transform-lock.js +50 -0
  246. package/dist/media/transform-lock.js.map +1 -0
  247. package/dist/media/transform-registry.d.ts +103 -0
  248. package/dist/media/transform-registry.d.ts.map +1 -0
  249. package/dist/media/transform-registry.js +87 -0
  250. package/dist/media/transform-registry.js.map +1 -0
  251. package/dist/media/transform-types.d.ts +82 -0
  252. package/dist/media/transform-types.d.ts.map +1 -0
  253. package/dist/media/transform-types.js +47 -0
  254. package/dist/media/transform-types.js.map +1 -0
  255. package/dist/media/types.d.ts +150 -0
  256. package/dist/media/types.d.ts.map +1 -0
  257. package/dist/media/types.js +26 -0
  258. package/dist/media/types.js.map +1 -0
  259. package/dist/navigation/agent-tools.d.ts +90 -0
  260. package/dist/navigation/agent-tools.d.ts.map +1 -0
  261. package/dist/navigation/agent-tools.js +225 -0
  262. package/dist/navigation/agent-tools.js.map +1 -0
  263. package/dist/navigation/contracts.d.ts +98 -0
  264. package/dist/navigation/contracts.d.ts.map +1 -0
  265. package/dist/navigation/contracts.js +70 -0
  266. package/dist/navigation/contracts.js.map +1 -0
  267. package/dist/navigation/index.d.ts +39 -0
  268. package/dist/navigation/index.d.ts.map +1 -0
  269. package/dist/navigation/index.js +30 -0
  270. package/dist/navigation/index.js.map +1 -0
  271. package/dist/navigation/menu-service.d.ts +256 -0
  272. package/dist/navigation/menu-service.d.ts.map +1 -0
  273. package/dist/navigation/menu-service.js +382 -0
  274. package/dist/navigation/menu-service.js.map +1 -0
  275. package/dist/navigation/ports.d.ts +147 -0
  276. package/dist/navigation/ports.d.ts.map +1 -0
  277. package/dist/navigation/ports.js +2 -0
  278. package/dist/navigation/ports.js.map +1 -0
  279. package/dist/navigation/read-model.d.ts +11 -0
  280. package/dist/navigation/read-model.d.ts.map +1 -0
  281. package/dist/navigation/read-model.js +27 -0
  282. package/dist/navigation/read-model.js.map +1 -0
  283. package/dist/navigation/reconcile.d.ts +57 -0
  284. package/dist/navigation/reconcile.d.ts.map +1 -0
  285. package/dist/navigation/reconcile.js +33 -0
  286. package/dist/navigation/reconcile.js.map +1 -0
  287. package/dist/navigation/repo.memory.d.ts +137 -0
  288. package/dist/navigation/repo.memory.d.ts.map +1 -0
  289. package/dist/navigation/repo.memory.js +95 -0
  290. package/dist/navigation/repo.memory.js.map +1 -0
  291. package/dist/navigation/resolver.d.ts +110 -0
  292. package/dist/navigation/resolver.d.ts.map +1 -0
  293. package/dist/navigation/resolver.js +131 -0
  294. package/dist/navigation/resolver.js.map +1 -0
  295. package/dist/navigation/tool-registrations.d.ts +43 -0
  296. package/dist/navigation/tool-registrations.d.ts.map +1 -0
  297. package/dist/navigation/tool-registrations.js +126 -0
  298. package/dist/navigation/tool-registrations.js.map +1 -0
  299. package/dist/navigation/types.d.ts +207 -0
  300. package/dist/navigation/types.d.ts.map +1 -0
  301. package/dist/navigation/types.js +14 -0
  302. package/dist/navigation/types.js.map +1 -0
  303. package/dist/presentation/index.d.ts +15 -0
  304. package/dist/presentation/index.d.ts.map +1 -0
  305. package/dist/presentation/index.js +15 -0
  306. package/dist/presentation/index.js.map +1 -0
  307. package/dist/presentation/presentation.d.ts +72 -0
  308. package/dist/presentation/presentation.d.ts.map +1 -0
  309. package/dist/presentation/presentation.js +51 -0
  310. package/dist/presentation/presentation.js.map +1 -0
  311. package/dist/presentation/repo.memory.d.ts +9 -0
  312. package/dist/presentation/repo.memory.d.ts.map +1 -0
  313. package/dist/presentation/repo.memory.js +21 -0
  314. package/dist/presentation/repo.memory.js.map +1 -0
  315. package/dist/server/index.d.ts +28 -0
  316. package/dist/server/index.d.ts.map +1 -0
  317. package/dist/server/index.js +28 -0
  318. package/dist/server/index.js.map +1 -0
  319. package/dist/settings/agent-tools.d.ts +83 -0
  320. package/dist/settings/agent-tools.d.ts.map +1 -0
  321. package/dist/settings/agent-tools.js +200 -0
  322. package/dist/settings/agent-tools.js.map +1 -0
  323. package/dist/settings/agent-writable-preferences.d.ts +67 -0
  324. package/dist/settings/agent-writable-preferences.d.ts.map +1 -0
  325. package/dist/settings/agent-writable-preferences.js +144 -0
  326. package/dist/settings/agent-writable-preferences.js.map +1 -0
  327. package/dist/settings/change-feed.d.ts +74 -0
  328. package/dist/settings/change-feed.d.ts.map +1 -0
  329. package/dist/settings/change-feed.js +61 -0
  330. package/dist/settings/change-feed.js.map +1 -0
  331. package/dist/settings/definitions-dispatch.d.ts +51 -0
  332. package/dist/settings/definitions-dispatch.d.ts.map +1 -0
  333. package/dist/settings/definitions-dispatch.js +86 -0
  334. package/dist/settings/definitions-dispatch.js.map +1 -0
  335. package/dist/settings/dictionaries/index.d.ts +45 -0
  336. package/dist/settings/dictionaries/index.d.ts.map +1 -0
  337. package/dist/settings/dictionaries/index.js +69 -0
  338. package/dist/settings/dictionaries/index.js.map +1 -0
  339. package/dist/settings/dictionaries/settings-dialog.ar.d.ts +3 -0
  340. package/dist/settings/dictionaries/settings-dialog.ar.d.ts.map +1 -0
  341. package/dist/settings/dictionaries/settings-dialog.ar.js +28 -0
  342. package/dist/settings/dictionaries/settings-dialog.ar.js.map +1 -0
  343. package/dist/settings/dictionaries/settings-dialog.bn.d.ts +3 -0
  344. package/dist/settings/dictionaries/settings-dialog.bn.d.ts.map +1 -0
  345. package/dist/settings/dictionaries/settings-dialog.bn.js +28 -0
  346. package/dist/settings/dictionaries/settings-dialog.bn.js.map +1 -0
  347. package/dist/settings/dictionaries/settings-dialog.de.d.ts +3 -0
  348. package/dist/settings/dictionaries/settings-dialog.de.d.ts.map +1 -0
  349. package/dist/settings/dictionaries/settings-dialog.de.js +28 -0
  350. package/dist/settings/dictionaries/settings-dialog.de.js.map +1 -0
  351. package/dist/settings/dictionaries/settings-dialog.es.d.ts +3 -0
  352. package/dist/settings/dictionaries/settings-dialog.es.d.ts.map +1 -0
  353. package/dist/settings/dictionaries/settings-dialog.es.js +28 -0
  354. package/dist/settings/dictionaries/settings-dialog.es.js.map +1 -0
  355. package/dist/settings/dictionaries/settings-dialog.fa.d.ts +3 -0
  356. package/dist/settings/dictionaries/settings-dialog.fa.d.ts.map +1 -0
  357. package/dist/settings/dictionaries/settings-dialog.fa.js +28 -0
  358. package/dist/settings/dictionaries/settings-dialog.fa.js.map +1 -0
  359. package/dist/settings/dictionaries/settings-dialog.fr.d.ts +3 -0
  360. package/dist/settings/dictionaries/settings-dialog.fr.d.ts.map +1 -0
  361. package/dist/settings/dictionaries/settings-dialog.fr.js +28 -0
  362. package/dist/settings/dictionaries/settings-dialog.fr.js.map +1 -0
  363. package/dist/settings/dictionaries/settings-dialog.hi.d.ts +3 -0
  364. package/dist/settings/dictionaries/settings-dialog.hi.d.ts.map +1 -0
  365. package/dist/settings/dictionaries/settings-dialog.hi.js +28 -0
  366. package/dist/settings/dictionaries/settings-dialog.hi.js.map +1 -0
  367. package/dist/settings/dictionaries/settings-dialog.hu.d.ts +3 -0
  368. package/dist/settings/dictionaries/settings-dialog.hu.d.ts.map +1 -0
  369. package/dist/settings/dictionaries/settings-dialog.hu.js +28 -0
  370. package/dist/settings/dictionaries/settings-dialog.hu.js.map +1 -0
  371. package/dist/settings/dictionaries/settings-dialog.id.d.ts +3 -0
  372. package/dist/settings/dictionaries/settings-dialog.id.d.ts.map +1 -0
  373. package/dist/settings/dictionaries/settings-dialog.id.js +28 -0
  374. package/dist/settings/dictionaries/settings-dialog.id.js.map +1 -0
  375. package/dist/settings/dictionaries/settings-dialog.it.d.ts +3 -0
  376. package/dist/settings/dictionaries/settings-dialog.it.d.ts.map +1 -0
  377. package/dist/settings/dictionaries/settings-dialog.it.js +28 -0
  378. package/dist/settings/dictionaries/settings-dialog.it.js.map +1 -0
  379. package/dist/settings/dictionaries/settings-dialog.ja.d.ts +3 -0
  380. package/dist/settings/dictionaries/settings-dialog.ja.d.ts.map +1 -0
  381. package/dist/settings/dictionaries/settings-dialog.ja.js +28 -0
  382. package/dist/settings/dictionaries/settings-dialog.ja.js.map +1 -0
  383. package/dist/settings/dictionaries/settings-dialog.ko.d.ts +3 -0
  384. package/dist/settings/dictionaries/settings-dialog.ko.d.ts.map +1 -0
  385. package/dist/settings/dictionaries/settings-dialog.ko.js +28 -0
  386. package/dist/settings/dictionaries/settings-dialog.ko.js.map +1 -0
  387. package/dist/settings/dictionaries/settings-dialog.pl.d.ts +3 -0
  388. package/dist/settings/dictionaries/settings-dialog.pl.d.ts.map +1 -0
  389. package/dist/settings/dictionaries/settings-dialog.pl.js +28 -0
  390. package/dist/settings/dictionaries/settings-dialog.pl.js.map +1 -0
  391. package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts +3 -0
  392. package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts.map +1 -0
  393. package/dist/settings/dictionaries/settings-dialog.pt-BR.js +28 -0
  394. package/dist/settings/dictionaries/settings-dialog.pt-BR.js.map +1 -0
  395. package/dist/settings/dictionaries/settings-dialog.ru.d.ts +3 -0
  396. package/dist/settings/dictionaries/settings-dialog.ru.d.ts.map +1 -0
  397. package/dist/settings/dictionaries/settings-dialog.ru.js +28 -0
  398. package/dist/settings/dictionaries/settings-dialog.ru.js.map +1 -0
  399. package/dist/settings/dictionaries/settings-dialog.th.d.ts +3 -0
  400. package/dist/settings/dictionaries/settings-dialog.th.d.ts.map +1 -0
  401. package/dist/settings/dictionaries/settings-dialog.th.js +28 -0
  402. package/dist/settings/dictionaries/settings-dialog.th.js.map +1 -0
  403. package/dist/settings/dictionaries/settings-dialog.tr.d.ts +3 -0
  404. package/dist/settings/dictionaries/settings-dialog.tr.d.ts.map +1 -0
  405. package/dist/settings/dictionaries/settings-dialog.tr.js +28 -0
  406. package/dist/settings/dictionaries/settings-dialog.tr.js.map +1 -0
  407. package/dist/settings/dictionaries/settings-dialog.uk.d.ts +3 -0
  408. package/dist/settings/dictionaries/settings-dialog.uk.d.ts.map +1 -0
  409. package/dist/settings/dictionaries/settings-dialog.uk.js +28 -0
  410. package/dist/settings/dictionaries/settings-dialog.uk.js.map +1 -0
  411. package/dist/settings/dictionaries/settings-dialog.ur.d.ts +3 -0
  412. package/dist/settings/dictionaries/settings-dialog.ur.d.ts.map +1 -0
  413. package/dist/settings/dictionaries/settings-dialog.ur.js +28 -0
  414. package/dist/settings/dictionaries/settings-dialog.ur.js.map +1 -0
  415. package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts +3 -0
  416. package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts.map +1 -0
  417. package/dist/settings/dictionaries/settings-dialog.zh-CN.js +28 -0
  418. package/dist/settings/dictionaries/settings-dialog.zh-CN.js.map +1 -0
  419. package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts +3 -0
  420. package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts.map +1 -0
  421. package/dist/settings/dictionaries/settings-dialog.zh-TW.js +28 -0
  422. package/dist/settings/dictionaries/settings-dialog.zh-TW.js.map +1 -0
  423. package/dist/settings/ensure-definitions.d.ts +88 -0
  424. package/dist/settings/ensure-definitions.d.ts.map +1 -0
  425. package/dist/settings/ensure-definitions.js +91 -0
  426. package/dist/settings/ensure-definitions.js.map +1 -0
  427. package/dist/settings/errors.d.ts +36 -0
  428. package/dist/settings/errors.d.ts.map +1 -0
  429. package/dist/settings/errors.js +40 -0
  430. package/dist/settings/errors.js.map +1 -0
  431. package/dist/settings/index.d.ts +37 -0
  432. package/dist/settings/index.d.ts.map +1 -0
  433. package/dist/settings/index.js +36 -0
  434. package/dist/settings/index.js.map +1 -0
  435. package/dist/settings/ports.d.ts +117 -0
  436. package/dist/settings/ports.d.ts.map +1 -0
  437. package/dist/settings/ports.js +2 -0
  438. package/dist/settings/ports.js.map +1 -0
  439. package/dist/settings/purge-service.d.ts +53 -0
  440. package/dist/settings/purge-service.d.ts.map +1 -0
  441. package/dist/settings/purge-service.js +105 -0
  442. package/dist/settings/purge-service.js.map +1 -0
  443. package/dist/settings/repo.memory.d.ts +119 -0
  444. package/dist/settings/repo.memory.d.ts.map +1 -0
  445. package/dist/settings/repo.memory.js +199 -0
  446. package/dist/settings/repo.memory.js.map +1 -0
  447. package/dist/settings/settings.d.ts +124 -0
  448. package/dist/settings/settings.d.ts.map +1 -0
  449. package/dist/settings/settings.js +238 -0
  450. package/dist/settings/settings.js.map +1 -0
  451. package/dist/settings/tool-registrations.d.ts +56 -0
  452. package/dist/settings/tool-registrations.d.ts.map +1 -0
  453. package/dist/settings/tool-registrations.js +240 -0
  454. package/dist/settings/tool-registrations.js.map +1 -0
  455. package/dist/settings/types.d.ts +125 -0
  456. package/dist/settings/types.d.ts.map +1 -0
  457. package/dist/settings/types.js +3 -0
  458. package/dist/settings/types.js.map +1 -0
  459. package/dist/settings/ui-tab-definitions.d.ts +41 -0
  460. package/dist/settings/ui-tab-definitions.d.ts.map +1 -0
  461. package/dist/settings/ui-tab-definitions.js +148 -0
  462. package/dist/settings/ui-tab-definitions.js.map +1 -0
  463. package/dist/settings/write-service.d.ts +314 -0
  464. package/dist/settings/write-service.d.ts.map +1 -0
  465. package/dist/settings/write-service.js +677 -0
  466. package/dist/settings/write-service.js.map +1 -0
  467. package/dist/taxonomy/agent-tools.d.ts +76 -0
  468. package/dist/taxonomy/agent-tools.d.ts.map +1 -0
  469. package/dist/taxonomy/agent-tools.js +178 -0
  470. package/dist/taxonomy/agent-tools.js.map +1 -0
  471. package/dist/taxonomy/content-lookup.d.ts +45 -0
  472. package/dist/taxonomy/content-lookup.d.ts.map +1 -0
  473. package/dist/taxonomy/content-lookup.js +9 -0
  474. package/dist/taxonomy/content-lookup.js.map +1 -0
  475. package/dist/taxonomy/index.d.ts +38 -0
  476. package/dist/taxonomy/index.d.ts.map +1 -0
  477. package/dist/taxonomy/index.js +38 -0
  478. package/dist/taxonomy/index.js.map +1 -0
  479. package/dist/taxonomy/list.d.ts +39 -0
  480. package/dist/taxonomy/list.d.ts.map +1 -0
  481. package/dist/taxonomy/list.js +19 -0
  482. package/dist/taxonomy/list.js.map +1 -0
  483. package/dist/taxonomy/merge-term.d.ts +94 -0
  484. package/dist/taxonomy/merge-term.d.ts.map +1 -0
  485. package/dist/taxonomy/merge-term.js +65 -0
  486. package/dist/taxonomy/merge-term.js.map +1 -0
  487. package/dist/taxonomy/repo.memory.d.ts +160 -0
  488. package/dist/taxonomy/repo.memory.d.ts.map +1 -0
  489. package/dist/taxonomy/repo.memory.js +171 -0
  490. package/dist/taxonomy/repo.memory.js.map +1 -0
  491. package/dist/taxonomy/validation-chain.d.ts +114 -0
  492. package/dist/taxonomy/validation-chain.d.ts.map +1 -0
  493. package/dist/taxonomy/validation-chain.js +152 -0
  494. package/dist/taxonomy/validation-chain.js.map +1 -0
  495. package/dist/taxonomy/write-service.d.ts +387 -0
  496. package/dist/taxonomy/write-service.d.ts.map +1 -0
  497. package/dist/taxonomy/write-service.js +350 -0
  498. package/dist/taxonomy/write-service.js.map +1 -0
  499. package/dist/workspace/agent-tools.d.ts +67 -0
  500. package/dist/workspace/agent-tools.d.ts.map +1 -0
  501. package/dist/workspace/agent-tools.js +103 -0
  502. package/dist/workspace/agent-tools.js.map +1 -0
  503. package/dist/workspace/create.d.ts +116 -0
  504. package/dist/workspace/create.d.ts.map +1 -0
  505. package/dist/workspace/create.js +69 -0
  506. package/dist/workspace/create.js.map +1 -0
  507. package/dist/workspace/delete.d.ts +50 -0
  508. package/dist/workspace/delete.d.ts.map +1 -0
  509. package/dist/workspace/delete.js +24 -0
  510. package/dist/workspace/delete.js.map +1 -0
  511. package/dist/workspace/index.d.ts +27 -0
  512. package/dist/workspace/index.d.ts.map +1 -0
  513. package/dist/workspace/index.js +27 -0
  514. package/dist/workspace/index.js.map +1 -0
  515. package/dist/workspace/repo.memory.d.ts +34 -0
  516. package/dist/workspace/repo.memory.d.ts.map +1 -0
  517. package/dist/workspace/repo.memory.js +50 -0
  518. package/dist/workspace/repo.memory.js.map +1 -0
  519. package/dist/workspace/tool-registrations.d.ts +38 -0
  520. package/dist/workspace/tool-registrations.d.ts.map +1 -0
  521. package/dist/workspace/tool-registrations.js +71 -0
  522. package/dist/workspace/tool-registrations.js.map +1 -0
  523. package/dist/workspace/update.d.ts +52 -0
  524. package/dist/workspace/update.d.ts.map +1 -0
  525. package/dist/workspace/update.js +41 -0
  526. package/dist/workspace/update.js.map +1 -0
  527. package/package.json +149 -0
@@ -0,0 +1,361 @@
1
+ import { authorize, resolveEffectivePermissions } from "./authorize.js";
2
+ import { GrantExceedsIssuerError, IdentityConflictError, IdentityForbiddenError, IdentityNotFoundError, IdentityValidationError, } from "./types.js";
3
+ import { normalizeUsername } from "./username.js";
4
+ import { validatePasswordPolicy } from "./password-policy.js";
5
+ /**
6
+ * @file Human grant-writing transitions (state.spec.md §3): `CREATE_USER`,
7
+ * `CREATE_ROLE`, `CREATE_POLICY`, `ASSIGN_ROLE`, `ATTACH_POLICY`.
8
+ *
9
+ * Purpose:
10
+ * The only usable identity principal before this file was the seeded owner —
11
+ * there was no API path to create a second user or grant/change permissions.
12
+ * These five functions are that path, following `auth-service.ts`'s exact
13
+ * shape (`{ deps: AuthServiceDeps, input: {...} }`, one exported async
14
+ * function per transition, plain `Error` subclasses for control flow).
15
+ *
16
+ * Out of scope (deferred, see the dispatch directive): `ISSUE_API_KEY`,
17
+ * `CREATE_PRINCIPAL` (api_key/agent principal creation), agent/api_key
18
+ * delegation, `WRITE_POLICY_PERMISSION`, `DISABLE_PRINCIPAL`.
19
+ *
20
+ * Architectural role:
21
+ * Ordinary core functions, not ports (mirrors `auth-service.ts`'s reasoning —
22
+ * grant-writing logic has one implementation). Each function calls
23
+ * `authorize()`/`resolveEffectivePermissions()` from `authorize.ts` itself
24
+ * (rather than pushing the gate into the route layer, the way
25
+ * `members/disable.ts`'s route does) so the caller-permission gate and the
26
+ * INV-07 clamp are exercised directly by unit tests, no HTTP harness needed.
27
+ */
28
+ /**
29
+ * Assemble the `AuthorizeDeps` bag `authorize()`/`resolveEffectivePermissions()` expect from the
30
+ * flat `IdentityRepos` bag. Exported so `admin-crud-service.ts`'s new transitions
31
+ * (`ENABLE_PRINCIPAL`/`UPDATE_USER`/`RESET_USER_PASSWORD`/`UPDATE_ROLE`/`UPDATE_POLICY`/
32
+ * `DELETE_ROLE`/`DELETE_POLICY`/`WRITE_POLICY_PERMISSION`/`DISABLE_PRINCIPAL`) reuse the identical
33
+ * gate/clamp logic rather than duplicating it — same file-split reasoning `auth-service.ts` and
34
+ * `grant-service.ts` already use (one shared helper set, two transition files).
35
+ */
36
+ export function authorizeDepsFrom(repos) {
37
+ return {
38
+ principals: repos.principals,
39
+ principalRoles: repos.principalRoles,
40
+ rolePolicies: repos.rolePolicies,
41
+ principalPolicies: repos.principalPolicies,
42
+ policyPermissions: repos.policyPermissions,
43
+ };
44
+ }
45
+ /**
46
+ * Fail-closed caller-permission gate shared by every transition in this file.
47
+ * Throws `IdentityForbiddenError` (403 `FORBIDDEN`) unless the caller holds
48
+ * at least one of `permissions` (an OR gate — `CREATE_USER` accepts either
49
+ * `user.manage` or `member.manage`, state.spec §3).
50
+ *
51
+ * @complexity O(p) `authorize()` calls, p = `permissions.length` (1 or 2 in
52
+ * every caller this pass) — each itself O(resolveEffectivePermissions), see
53
+ * that function's doc.
54
+ * @overallScore 100
55
+ */
56
+ export async function assertCallerHasAnyPermission(required) {
57
+ const { deps, workspaceId, callerPrincipalId, permissions } = required;
58
+ let lastReason = "no_grant";
59
+ for (const permission of permissions) {
60
+ const result = await authorize({
61
+ deps: authorizeDepsFrom(deps.repos),
62
+ principalId: callerPrincipalId,
63
+ permission,
64
+ context: { workspaceId },
65
+ });
66
+ if (result.allowed)
67
+ return;
68
+ lastReason = result.reason;
69
+ }
70
+ throw new IdentityForbiddenError(`principal '${callerPrincipalId}' is not authorized for any of [${permissions.join(", ")}]`, permissions.join("|"), lastReason);
71
+ }
72
+ /** True iff `effectiveRows` contains an unconstrained hold of `permission` — an exact match with
73
+ * `resourceType`/`constraintJson` both null, or the owner wildcard `*` (which counts as an
74
+ * unconstrained hold of every permission, INV-07). */
75
+ function holdsUnconstrained(effectiveRows, permission) {
76
+ const hasWildcard = effectiveRows.some((row) => row.permission === "*" && row.resourceType == null && row.constraintJson == null);
77
+ if (hasWildcard)
78
+ return true;
79
+ return effectiveRows.some((row) => row.permission === permission && row.resourceType == null && row.constraintJson == null);
80
+ }
81
+ /**
82
+ * The INV-07 grant-authority clamp (feature.spec.md, state.spec §3
83
+ * `ASSIGN_ROLE`/`ATTACH_POLICY` rows): every permission in `conferredPermissions`
84
+ * must be a matching effective row the caller holds unconstrained
85
+ * (`resourceType`/`constraintJson` both null; owner's `*` qualifies for all).
86
+ * A permission held only conditionally (resource-scoped or constraint-bound)
87
+ * cannot be delegated. Throws `GrantExceedsIssuerError` (403
88
+ * `GRANT_EXCEEDS_ISSUER`) naming every offending permission, and writes no
89
+ * grant row (caller does the write only after this resolves).
90
+ *
91
+ * @complexity O(resolveEffectivePermissions) + O(k) local filtering, k =
92
+ * `conferredPermissions.length` (bounded by one role's/policy's permission
93
+ * rows — a handful, per `identity/INFO.md`'s scale assumptions).
94
+ * @overallScore 100
95
+ */
96
+ export async function assertGrantClamp(required) {
97
+ const { deps, workspaceId, callerPrincipalId, conferredPermissions } = required;
98
+ const distinctPermissions = [...new Set(conferredPermissions)];
99
+ if (distinctPermissions.length === 0)
100
+ return;
101
+ const effectiveRows = await resolveEffectivePermissions({
102
+ deps: authorizeDepsFrom(deps.repos),
103
+ principalId: callerPrincipalId,
104
+ workspaceId,
105
+ });
106
+ const offendingPermissions = distinctPermissions.filter((permission) => !holdsUnconstrained(effectiveRows, permission));
107
+ if (offendingPermissions.length > 0) {
108
+ throw new GrantExceedsIssuerError(`principal '${callerPrincipalId}' cannot grant permission(s) it does not hold unconstrained: ${offendingPermissions.join(", ")}`, offendingPermissions);
109
+ }
110
+ }
111
+ /**
112
+ * `ASSIGN_ROLE`/`ATTACH_POLICY`'s shared human-target-only rule (AC-25b):
113
+ * machine (`api_key`/`system`) principal authority is set solely at
114
+ * issuance, never mutated by a later human-grant transition. Throws
115
+ * `IdentityValidationError` (400 `VALIDATION_ERROR`) for a non-`user` or
116
+ * missing target — this check runs *before* the INV-07 clamp (AC-25's note:
117
+ * "does not reach this clamp").
118
+ */
119
+ async function findAssignableTargetOrThrow(required) {
120
+ const { deps, workspaceId, principalId, transitionName } = required;
121
+ const target = await deps.repos.principals.findById({ workspaceId, id: principalId });
122
+ if (!target) {
123
+ throw new IdentityNotFoundError(`principal '${principalId}' was not found`);
124
+ }
125
+ if (target.kind !== "user") {
126
+ throw new IdentityValidationError(`${transitionName} target must be a human (kind='user') principal, got kind='${target.kind}'`);
127
+ }
128
+ return target;
129
+ }
130
+ /**
131
+ * `CREATE_USER` (state.spec §3, REQ-01/MF-1). Atomically mints a NEW
132
+ * `kind='user'` principal and its `users` row — the `principalId` is always
133
+ * generated here, never caller-supplied, so this transition can never attach
134
+ * a credential to a pre-existing principal (the MF-1 privilege-escalation
135
+ * class: an earlier draft let an admin bind a password to the seeded owner
136
+ * principal and log in as owner). Gated by `user.manage` OR `member.manage`
137
+ * (admin onboarding, AC-22).
138
+ *
139
+ * "Atomically" here means structurally, not via a DB transaction — the
140
+ * in-memory adapters have no cross-repo transaction (same disclosed gap as
141
+ * `seed.ts`/`executeCommand`'s compensating-rollback path). The invariant
142
+ * that actually matters (no credential ever attaches to an existing
143
+ * principal) holds regardless, because `principalId` is generated inline and
144
+ * the password is hashed before either row is written, so a hashing failure
145
+ * leaves no orphan principal. A future SQLite adapter wraps both writes in
146
+ * one real transaction (port/adapter rule-of-two) without changing this contract.
147
+ *
148
+ * @complexity O(1) — one permission check, one username lookup, one hash,
149
+ * two saves.
150
+ * @overallScore 100
151
+ */
152
+ export async function createUser(required) {
153
+ const { deps, input } = required;
154
+ await assertCallerHasAnyPermission({
155
+ deps,
156
+ workspaceId: input.workspaceId,
157
+ callerPrincipalId: input.callerPrincipalId,
158
+ permissions: ["user.manage", "member.manage"],
159
+ });
160
+ const username = normalizeUsername(input.username ?? "");
161
+ if (!username || !input.password) {
162
+ throw new IdentityValidationError("username and password are required");
163
+ }
164
+ // NIST SP 800-63B length-only policy (MSG-04) — never reaches seed.ts's owner password, see
165
+ // password-policy.ts's own header for why that separation is deliberate.
166
+ const passwordError = validatePasswordPolicy(input.password);
167
+ if (passwordError) {
168
+ throw new IdentityValidationError(passwordError);
169
+ }
170
+ const existingUser = await deps.repos.users.findByUsername({ workspaceId: input.workspaceId, username });
171
+ if (existingUser) {
172
+ throw new IdentityConflictError(`username '${username}' is already in use`);
173
+ }
174
+ const passwordHash = await deps.hasher.hash(input.password);
175
+ const nowIso = deps.clock.nowIso();
176
+ const principalId = deps.idGen.newId();
177
+ const principal = {
178
+ id: principalId,
179
+ workspaceId: input.workspaceId,
180
+ kind: "user",
181
+ displayName: username,
182
+ status: "active",
183
+ createdAt: nowIso,
184
+ };
185
+ const user = {
186
+ principalId,
187
+ workspaceId: input.workspaceId,
188
+ username,
189
+ email: input.email,
190
+ passwordHash,
191
+ };
192
+ await deps.repos.principals.save(principal);
193
+ await deps.repos.users.save(user);
194
+ return { principal, user };
195
+ }
196
+ /**
197
+ * `CREATE_ROLE` (state.spec §3). Gated by `role.manage`. Always mints
198
+ * `isBuiltin=false` — built-ins are SEED-only and immutable (INV-06).
199
+ *
200
+ * Deviation from the state.spec §3 table (disclosed): that row lists
201
+ * `name`, `description?` jointly for `CREATE_ROLE`/`CREATE_POLICY`, but
202
+ * `RoleRecord` (types.ts, frozen before this task) has no `description`
203
+ * field — only `PolicyRecord` does. `createRole` therefore takes `name`
204
+ * only; `createPolicy` below takes both.
205
+ *
206
+ * @complexity O(1) — one permission check, one save.
207
+ * @overallScore 100
208
+ */
209
+ export async function createRole(required) {
210
+ const { deps, input } = required;
211
+ await assertCallerHasAnyPermission({
212
+ deps,
213
+ workspaceId: input.workspaceId,
214
+ callerPrincipalId: input.callerPrincipalId,
215
+ permissions: ["role.manage"],
216
+ });
217
+ const name = (input.name ?? "").trim();
218
+ if (!name) {
219
+ throw new IdentityValidationError("role name is required");
220
+ }
221
+ const role = {
222
+ id: deps.idGen.newId(),
223
+ workspaceId: input.workspaceId,
224
+ name,
225
+ isBuiltin: false,
226
+ };
227
+ await deps.repos.roles.save(role);
228
+ return { role };
229
+ }
230
+ /**
231
+ * `CREATE_POLICY` (state.spec §3). Gated by `role.manage`. Always mints
232
+ * `isBuiltin=false` and `isFrozen=false` — only the (out-of-scope this pass)
233
+ * `ISSUE_API_KEY` transition ever mints `isFrozen=true` policies.
234
+ *
235
+ * @complexity O(1) — one permission check, one save.
236
+ * @overallScore 100
237
+ */
238
+ export async function createPolicy(required) {
239
+ const { deps, input } = required;
240
+ await assertCallerHasAnyPermission({
241
+ deps,
242
+ workspaceId: input.workspaceId,
243
+ callerPrincipalId: input.callerPrincipalId,
244
+ permissions: ["role.manage"],
245
+ });
246
+ const name = (input.name ?? "").trim();
247
+ if (!name) {
248
+ throw new IdentityValidationError("policy name is required");
249
+ }
250
+ const policy = {
251
+ id: deps.idGen.newId(),
252
+ workspaceId: input.workspaceId,
253
+ name,
254
+ description: input.description,
255
+ isBuiltin: false,
256
+ isFrozen: false,
257
+ };
258
+ await deps.repos.policies.save(policy);
259
+ return { policy };
260
+ }
261
+ /**
262
+ * `ASSIGN_ROLE` (state.spec §3, REQ-02, AC-24/AC-25). Gated by `role.manage`;
263
+ * target must be a `kind='user'` principal (AC-25b); the INV-07 clamp must
264
+ * pass over every permission carried by the role's policies (AC-24) — so
265
+ * assigning the built-in `owner` role requires the caller to already hold
266
+ * the wildcard `*` (owner-only). No row is written on any rejection.
267
+ *
268
+ * @complexity O(resolveEffectivePermissions) + O(role's rolePolicy count)
269
+ * round trips to gather conferred permissions — both bounded by the small,
270
+ * hand-authored grant graph this system assumes (see `identity/INFO.md`).
271
+ * @overallScore 100
272
+ */
273
+ export async function assignRole(required) {
274
+ const { deps, input } = required;
275
+ await assertCallerHasAnyPermission({
276
+ deps,
277
+ workspaceId: input.workspaceId,
278
+ callerPrincipalId: input.callerPrincipalId,
279
+ permissions: ["role.manage"],
280
+ });
281
+ await findAssignableTargetOrThrow({
282
+ deps,
283
+ workspaceId: input.workspaceId,
284
+ principalId: input.principalId,
285
+ transitionName: "ASSIGN_ROLE",
286
+ });
287
+ const role = await deps.repos.roles.findById({ workspaceId: input.workspaceId, id: input.roleId });
288
+ if (!role) {
289
+ throw new IdentityNotFoundError(`role '${input.roleId}' was not found`);
290
+ }
291
+ const rolePolicyLinks = await deps.repos.rolePolicies.listByRoleId({
292
+ workspaceId: input.workspaceId,
293
+ roleId: input.roleId,
294
+ });
295
+ const policyPermissionGroups = await Promise.all(rolePolicyLinks.map((link) => deps.repos.policyPermissions.listByPolicyId({ workspaceId: input.workspaceId, policyId: link.policyId })));
296
+ const conferredPermissions = policyPermissionGroups.flat().map((row) => row.permission);
297
+ await assertGrantClamp({
298
+ deps,
299
+ workspaceId: input.workspaceId,
300
+ callerPrincipalId: input.callerPrincipalId,
301
+ conferredPermissions,
302
+ });
303
+ const assignment = {
304
+ id: deps.idGen.newId(),
305
+ workspaceId: input.workspaceId,
306
+ principalId: input.principalId,
307
+ roleId: input.roleId,
308
+ };
309
+ await deps.repos.principalRoles.save(assignment);
310
+ return { assignment };
311
+ }
312
+ /**
313
+ * `ATTACH_POLICY` (state.spec §3, REQ-02, AC-24/AC-25). Gated by
314
+ * `role.manage`; target must be a `kind='user'` principal (AC-25b); the
315
+ * INV-07 clamp must pass over every permission the policy carries (AC-24) —
316
+ * attaching the built-in `owner` policy requires the caller to already hold
317
+ * `*` (owner-only). No row is written on any rejection.
318
+ *
319
+ * @complexity O(resolveEffectivePermissions) + O(policy's permission row
320
+ * count) — both bounded, see `assignRole`'s doc.
321
+ * @overallScore 100
322
+ */
323
+ export async function attachPolicy(required) {
324
+ const { deps, input } = required;
325
+ await assertCallerHasAnyPermission({
326
+ deps,
327
+ workspaceId: input.workspaceId,
328
+ callerPrincipalId: input.callerPrincipalId,
329
+ permissions: ["role.manage"],
330
+ });
331
+ await findAssignableTargetOrThrow({
332
+ deps,
333
+ workspaceId: input.workspaceId,
334
+ principalId: input.principalId,
335
+ transitionName: "ATTACH_POLICY",
336
+ });
337
+ const policy = await deps.repos.policies.findById({ workspaceId: input.workspaceId, id: input.policyId });
338
+ if (!policy) {
339
+ throw new IdentityNotFoundError(`policy '${input.policyId}' was not found`);
340
+ }
341
+ const permissionRows = await deps.repos.policyPermissions.listByPolicyId({
342
+ workspaceId: input.workspaceId,
343
+ policyId: input.policyId,
344
+ });
345
+ const conferredPermissions = permissionRows.map((row) => row.permission);
346
+ await assertGrantClamp({
347
+ deps,
348
+ workspaceId: input.workspaceId,
349
+ callerPrincipalId: input.callerPrincipalId,
350
+ conferredPermissions,
351
+ });
352
+ const attachment = {
353
+ id: deps.idGen.newId(),
354
+ workspaceId: input.workspaceId,
355
+ principalId: input.principalId,
356
+ policyId: input.policyId,
357
+ };
358
+ await deps.repos.principalPolicies.save(attachment);
359
+ return { attachment };
360
+ }
361
+ //# sourceMappingURL=grant-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grant-service.js","sourceRoot":"","sources":["../../src/identity/grant-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { PasswordHasherPort } from "./ports.js";
2
+ /**
3
+ * @file argon2id password hashing (INV-05).
4
+ *
5
+ * Purpose:
6
+ * The one real `PasswordHasherPort` adapter this pass — native argon2
7
+ * bindings, verified installable/buildable in this environment (see the
8
+ * Programmer handoff). Raw passwords are never stored or logged; only the
9
+ * hash produced here is persisted (`users.passwordHash`).
10
+ *
11
+ * Architectural role:
12
+ * Rule-of-two candidate per feature.spec's Dependencies table — only one
13
+ * adapter exists this pass, matching the spec's own "candidate" framing.
14
+ */
15
+ /** Tunable cost parameters, defaulted to OWASP's current argon2id minimums. */
16
+ export interface Argon2PasswordHasherOptions {
17
+ /** KiB. OWASP minimum recommendation is 19456 (~19 MiB). */
18
+ memoryCost?: number;
19
+ /** Iteration count. OWASP minimum recommendation is 2 at this memory cost. */
20
+ timeCost?: number;
21
+ /** Degree of parallelism. */
22
+ parallelism?: number;
23
+ }
24
+ /**
25
+ * argon2id-backed `PasswordHasherPort`. `verify` never throws on a malformed
26
+ * or foreign hash — it resolves `false`, so a corrupted `passwordHash` row
27
+ * degrades to "wrong password," never to a 500 or an authentication bypass.
28
+ *
29
+ * @complexity O(1) calls into the native binding; cost is tuned by
30
+ * `memoryCost`/`timeCost`/`parallelism`, not by input size.
31
+ * @overallScore 100
32
+ */
33
+ export declare class Argon2PasswordHasher implements PasswordHasherPort {
34
+ private readonly options;
35
+ constructor(options?: Argon2PasswordHasherOptions);
36
+ hash(password: string): Promise<string>;
37
+ verify(hash: string, password: string): Promise<boolean>;
38
+ }
39
+ //# sourceMappingURL=hasher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.d.ts","sourceRoot":"","sources":["../../src/identity/hasher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;;;;;GAYG;AAEH,+EAA+E;AAC/E,MAAM,WAAW,2BAA2B;IAC1C,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD;;;;;;;;GAQG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;gBAEpD,OAAO,GAAE,2BAAgC;IAI/C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASvC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAQ/D"}
@@ -0,0 +1,39 @@
1
+ import * as argon2 from "argon2";
2
+ const DEFAULT_OPTIONS = {
3
+ memoryCost: 19456,
4
+ timeCost: 2,
5
+ parallelism: 1,
6
+ };
7
+ /**
8
+ * argon2id-backed `PasswordHasherPort`. `verify` never throws on a malformed
9
+ * or foreign hash — it resolves `false`, so a corrupted `passwordHash` row
10
+ * degrades to "wrong password," never to a 500 or an authentication bypass.
11
+ *
12
+ * @complexity O(1) calls into the native binding; cost is tuned by
13
+ * `memoryCost`/`timeCost`/`parallelism`, not by input size.
14
+ * @overallScore 100
15
+ */
16
+ export class Argon2PasswordHasher {
17
+ options;
18
+ constructor(options = {}) {
19
+ this.options = { ...DEFAULT_OPTIONS, ...options };
20
+ }
21
+ async hash(password) {
22
+ return argon2.hash(password, {
23
+ type: argon2.argon2id,
24
+ memoryCost: this.options.memoryCost,
25
+ timeCost: this.options.timeCost,
26
+ parallelism: this.options.parallelism,
27
+ });
28
+ }
29
+ async verify(hash, password) {
30
+ try {
31
+ return await argon2.verify(hash, password);
32
+ }
33
+ catch {
34
+ // Malformed/foreign hash (e.g. a hand-edited row) — fail closed, not 500.
35
+ return false;
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=hasher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.js","sourceRoot":"","sources":["../../src/identity/hasher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AA4BjC,MAAM,eAAe,GAA0C;IAC7D,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,CAAC;IACX,WAAW,EAAE,CAAC;CACf,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,OAAO,oBAAoB;IACd,OAAO,CAAwC;IAEhE,YAAY,UAAuC,EAAE;QACnD,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB;QACzB,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC3B,IAAI,EAAE,MAAM,CAAC,QAAQ;YACrB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YACnC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC/B,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,QAAgB;QACzC,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @file Public surface (barrel) for the `identity` library.
3
+ *
4
+ * A module's public contract is its `index.ts` — deep imports
5
+ * from outside this directory should go through here.
6
+ */
7
+ export type { PrincipalKind, PrincipalStatus, PrincipalRecord, UserRecord, SessionRecord, RoleRecord, PolicyRecord, PolicyPermissionRecord, RolePolicyRecord, PrincipalRoleRecord, PrincipalPolicyRecord, } from "./types.js";
8
+ export { IdentityValidationError, IdentityNotFoundError, IdentityConflictError, AuthInvalidCredentialsError, IdentityForbiddenError, GrantExceedsIssuerError, OwnerRequiredError, PermissionUnknownError, } from "./types.js";
9
+ export type { PrincipalRepoPort, UserRepoPort, SessionRepoPort, RoleRepoPort, PolicyRepoPort, PolicyPermissionRepoPort, RolePolicyRepoPort, PrincipalRoleRepoPort, PrincipalPolicyRepoPort, IdentityRepos, PasswordHasherPort, } from "./ports.js";
10
+ export { InMemoryPrincipalRepo, InMemoryUserRepo, InMemorySessionRepo, InMemoryRoleRepo, InMemoryPolicyRepo, InMemoryPolicyPermissionRepo, InMemoryRolePolicyRepo, InMemoryPrincipalRoleRepo, InMemoryPrincipalPolicyRepo, } from "./repo.memory.js";
11
+ /**
12
+ * No concrete `PasswordHasherPort` implementation is exported here, deliberately. The reference
13
+ * adapter is argon2id, a native module: shipping it from this entry point would make a compiled
14
+ * binary a hard requirement of importing the identity domain — including for a host that only
15
+ * wants the types, the authorization rules, or the in-memory repositories. Hosts construct their
16
+ * own hasher and pass it as `deps.hasher`; the port is the contract, not the algorithm. A shared
17
+ * argon2 adapter belongs in `../server` once that layer exists.
18
+ */
19
+ export { authorize, resolveEffectivePermissions, type AuthorizeContext, type AuthorizeResult, type AuthorizeDeps, } from "./authorize.js";
20
+ export { login, logout, validateSession, getEffectivePermissions, SESSION_TTL_MS, type AuthServiceDeps, } from "./auth-service.js";
21
+ export { seedIdentity, type SeedIdentityDeps, type SeedIdentityInput, type SeedIdentityResult } from "./seed.js";
22
+ export { createUser, createRole, createPolicy, assignRole, attachPolicy,
23
+ /** Exported so the assistant's read-only identity tools gate on the SAME caller-permission
24
+ * helper the mutating transitions use, rather than re-implementing the OR gate. */
25
+ assertCallerHasAnyPermission, } from "./grant-service.js";
26
+ /** The agent-tool surface for this domain (see `agent-tools.ts` for what is deliberately omitted). */
27
+ export { identityAgentToolCatalog, type AgentToolDefinition as IdentityAgentToolDefinition, type AgentToolSideEffect as IdentityAgentToolSideEffect, } from "./agent-tools.js";
28
+ export { parseIdentityToolInput, type IdentityToolInputResult } from "./agent-tool-input.js";
29
+ /** The users/roles/policies admin CRUD-completion amendment. */
30
+ export { disablePrincipal, enablePrincipal, updateUser, resetUserPassword, updateRole, updatePolicy, deleteRole, deletePolicy, writePolicyPermission,
31
+ /** OQ-10 — the inverse of `writePolicyPermission`; without it a policy's permission set was
32
+ * append-only (shrinking it meant `deletePolicy` + recreate, which INV-09 blocks once the
33
+ * policy is referenced). */
34
+ removePolicyPermission, } from "./admin-crud-service.js";
35
+ /**
36
+ * There is no wiring/composition export here, deliberately. Assembling concrete repositories into
37
+ * a dependency bag names a specific database handle, which would put one host's persistence choice
38
+ * on this library's public contract and drag that host's schema into every consumer's dependency
39
+ * closure. Hosts compose their own; this entry point exports the ports they compose against.
40
+ */
41
+ export { normalizeUsername } from "./username.js";
42
+ export { registerPermission, listPermissions, isKnownPermission, permissionCatalog, type PermissionDescriptor, } from "./permissions.js";
43
+ /**
44
+ * The shared deprecate-old/grant-new permission migration
45
+ * mechanism (see `docs/decisions/permission-catalog-migration.md`). Sibling
46
+ * remediation efforts (Members/Analytics/Integrations)
47
+ * register their own `{from, to}` pair via `registerPermissionMigration`
48
+ * rather than hand-rolling a divergent copy.
49
+ */
50
+ export { registerPermissionMigration, listPermissionMigrations, migrateDeprecatedPermissionGrants, type PermissionMigration, type MigrateDeprecatedPermissionGrantsDeps, type MigrateDeprecatedPermissionGrantsResult, } from "./permission-migrations.js";
51
+ /**
52
+ * The agent-tool wiring for this domain.
53
+ *
54
+ * `IdentityToolDeps` is declared structurally rather than derived from any host's request-scoped
55
+ * dependency bag, which is what lets a host satisfy it by passing whatever object it already has —
56
+ * the shape is the contract, so no host type needs to be named here.
57
+ */
58
+ export { buildIdentityRegistrations, identityDerivedRisk, type IdentityToolDeps, } from "./tool-registrations.js";
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,4BAA4B,EAC5B,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;GAOG;AAEH,OAAO,EACL,SAAS,EACT,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,EACL,MAAM,EACN,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEjH,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY;AACZ;mFACmF;AACnF,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,sGAAsG;AACtG,OAAO,EACL,wBAAwB,EACxB,KAAK,mBAAmB,IAAI,2BAA2B,EACvD,KAAK,mBAAmB,IAAI,2BAA2B,GACxD,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAE7F,gEAAgE;AAChE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,qBAAqB;AACrB;;6BAE6B;AAC7B,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,iCAAiC,EACjC,KAAK,mBAAmB,EACxB,KAAK,qCAAqC,EAC1C,KAAK,uCAAuC,GAC7C,MAAM,4BAA4B,CAAC;AAEpC;;;;;;GAMG;AACH,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,gBAAgB,GACtB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,51 @@
1
+ export { IdentityValidationError, IdentityNotFoundError, IdentityConflictError, AuthInvalidCredentialsError, IdentityForbiddenError, GrantExceedsIssuerError, OwnerRequiredError, PermissionUnknownError, } from "./types.js";
2
+ export { InMemoryPrincipalRepo, InMemoryUserRepo, InMemorySessionRepo, InMemoryRoleRepo, InMemoryPolicyRepo, InMemoryPolicyPermissionRepo, InMemoryRolePolicyRepo, InMemoryPrincipalRoleRepo, InMemoryPrincipalPolicyRepo, } from "./repo.memory.js";
3
+ /**
4
+ * No concrete `PasswordHasherPort` implementation is exported here, deliberately. The reference
5
+ * adapter is argon2id, a native module: shipping it from this entry point would make a compiled
6
+ * binary a hard requirement of importing the identity domain — including for a host that only
7
+ * wants the types, the authorization rules, or the in-memory repositories. Hosts construct their
8
+ * own hasher and pass it as `deps.hasher`; the port is the contract, not the algorithm. A shared
9
+ * argon2 adapter belongs in `../server` once that layer exists.
10
+ */
11
+ export { authorize, resolveEffectivePermissions, } from "./authorize.js";
12
+ export { login, logout, validateSession, getEffectivePermissions, SESSION_TTL_MS, } from "./auth-service.js";
13
+ export { seedIdentity } from "./seed.js";
14
+ export { createUser, createRole, createPolicy, assignRole, attachPolicy,
15
+ /** Exported so the assistant's read-only identity tools gate on the SAME caller-permission
16
+ * helper the mutating transitions use, rather than re-implementing the OR gate. */
17
+ assertCallerHasAnyPermission, } from "./grant-service.js";
18
+ /** The agent-tool surface for this domain (see `agent-tools.ts` for what is deliberately omitted). */
19
+ export { identityAgentToolCatalog, } from "./agent-tools.js";
20
+ export { parseIdentityToolInput } from "./agent-tool-input.js";
21
+ /** The users/roles/policies admin CRUD-completion amendment. */
22
+ export { disablePrincipal, enablePrincipal, updateUser, resetUserPassword, updateRole, updatePolicy, deleteRole, deletePolicy, writePolicyPermission,
23
+ /** OQ-10 — the inverse of `writePolicyPermission`; without it a policy's permission set was
24
+ * append-only (shrinking it meant `deletePolicy` + recreate, which INV-09 blocks once the
25
+ * policy is referenced). */
26
+ removePolicyPermission, } from "./admin-crud-service.js";
27
+ /**
28
+ * There is no wiring/composition export here, deliberately. Assembling concrete repositories into
29
+ * a dependency bag names a specific database handle, which would put one host's persistence choice
30
+ * on this library's public contract and drag that host's schema into every consumer's dependency
31
+ * closure. Hosts compose their own; this entry point exports the ports they compose against.
32
+ */
33
+ export { normalizeUsername } from "./username.js";
34
+ export { registerPermission, listPermissions, isKnownPermission, permissionCatalog, } from "./permissions.js";
35
+ /**
36
+ * The shared deprecate-old/grant-new permission migration
37
+ * mechanism (see `docs/decisions/permission-catalog-migration.md`). Sibling
38
+ * remediation efforts (Members/Analytics/Integrations)
39
+ * register their own `{from, to}` pair via `registerPermissionMigration`
40
+ * rather than hand-rolling a divergent copy.
41
+ */
42
+ export { registerPermissionMigration, listPermissionMigrations, migrateDeprecatedPermissionGrants, } from "./permission-migrations.js";
43
+ /**
44
+ * The agent-tool wiring for this domain.
45
+ *
46
+ * `IdentityToolDeps` is declared structurally rather than derived from any host's request-scoped
47
+ * dependency bag, which is what lets a host satisfy it by passing whatever object it already has —
48
+ * the shape is the contract, so no host type needs to be named here.
49
+ */
50
+ export { buildIdentityRegistrations, identityDerivedRisk, } from "./tool-registrations.js";
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAgBpB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,4BAA4B,EAC5B,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;GAOG;AAEH,OAAO,EACL,SAAS,EACT,2BAA2B,GAI5B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,EACL,MAAM,EACN,eAAe,EACf,uBAAuB,EACvB,cAAc,GAEf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAA0E,MAAM,WAAW,CAAC;AAEjH,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY;AACZ;mFACmF;AACnF,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,sGAAsG;AACtG,OAAO,EACL,wBAAwB,GAGzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAgC,MAAM,uBAAuB,CAAC;AAE7F,gEAAgE;AAChE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,qBAAqB;AACrB;;6BAE6B;AAC7B,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,iCAAiC,GAIlC,MAAM,4BAA4B,CAAC;AAEpC;;;;;;GAMG;AACH,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,GAEpB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @file Password policy (NIST SP 800-63B aligned): a length floor only, no composition rules.
3
+ *
4
+ * NIST SP 800-63B — the current published memorized-secret guidance — recommends a minimum
5
+ * length requirement and explicitly recommends AGAINST composition rules (mandatory uppercase,
6
+ * digit, or symbol). Composition rules measurably push people toward predictable, guessable
7
+ * patterns ("Password1!") rather than genuinely stronger secrets, which is why this module
8
+ * enforces length only.
9
+ *
10
+ * `createUser` (`grant-service.ts`) and `resetUserPassword` (`admin-crud-service.ts`) are the
11
+ * identity system's only two write paths that ever set a password, confirmed by tracing the
12
+ * whole call graph — both call this module.
13
+ *
14
+ * Two things this deliberately does NOT do, both load-bearing:
15
+ * - Never reaches `seed.ts`'s first-boot owner password. `seedIdentity` hashes it directly
16
+ * (`deps.hasher.hash(ownerPassword)`, `seed.ts:317`) and calls neither `createUser` nor
17
+ * `resetUserPassword` — confirmed before writing this module. That separation is intentional
18
+ * to preserve here: the host chooses the first-boot owner password (`SeedIdentityInput` requires
19
+ * it and supplies no default), and an existing installation is already authenticating with
20
+ * whatever it chose. Enforcing this policy on that path would lock out every such installation
21
+ * whose chosen value predates the policy.
22
+ * - Never re-validates at login. This is a write-time policy — `login`/`verify` never call it.
23
+ * An account whose password predates this policy (or was seeded) must keep authenticating; NIST
24
+ * 800-63B's own guidance is that length rules apply when a secret is *chosen*, not retroactively
25
+ * to secrets already in use.
26
+ */
27
+ /** NIST SP 800-63B's recommended floor. */
28
+ export declare const MIN_PASSWORD_LENGTH = 12;
29
+ /**
30
+ * Generous upper bound — not itself a security requirement (argon2id's cost is tuned by its
31
+ * `memoryCost`/`timeCost`/`parallelism` parameters, not by input size — see `hasher.ts`'s own
32
+ * `@complexity` note), but a defense-in-depth cap on how large a string this service will accept
33
+ * and pass to the hasher at all, independent of whatever limit (if any) sits in front of it at
34
+ * the HTTP layer. Comfortably above any realistic human-typed passphrase.
35
+ */
36
+ export declare const MAX_PASSWORD_LENGTH = 512;
37
+ /**
38
+ * Validates `password` against the length-only policy.
39
+ *
40
+ * Measures length in Unicode CODE POINTS (`[...password].length`), not UTF-16 code units
41
+ * (`password.length`): a passphrase built from astral-plane characters (many emoji, some
42
+ * CJK/historic scripts) is represented as a surrogate pair per character in a JS string, so plain
43
+ * `.length` overcounts those characters relative to what a human typing them perceives as "12
44
+ * characters" — silently misjudging the exact floor this function states. No trimming, no
45
+ * character allowlist: every printable character, including leading/trailing spaces and full
46
+ * Unicode, is accepted as typed. Silently altering the input (trimming, stripping) would make the
47
+ * stored credential differ from the secret the operator actually chose.
48
+ *
49
+ * @returns `null` if `password` satisfies the policy, otherwise an operator-facing message
50
+ * stating the requirement plainly — used verbatim as the thrown `IdentityValidationError`'s
51
+ * message by both call sites, and rendered as-is through the admin's `describeApiError` layer.
52
+ *
53
+ * @complexity O(n) in the password's length — spreading a string into code points is a single
54
+ * linear pass, which is the minimum work a correct (non-UTF-16-code-unit) count requires.
55
+ * @overallScore 100
56
+ */
57
+ export declare function validatePasswordPolicy(password: string): string | null;
58
+ //# sourceMappingURL=password-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-policy.d.ts","sourceRoot":"","sources":["../../src/identity/password-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,2CAA2C;AAC3C,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAStE"}