libre-webui 0.22.1 → 0.23.1

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 (237) hide show
  1. package/backend/dist/index.d.ts.map +1 -1
  2. package/backend/dist/index.js +8 -0
  3. package/backend/dist/index.js.map +1 -1
  4. package/backend/dist/middleware/auth.d.ts +15 -1
  5. package/backend/dist/middleware/auth.d.ts.map +1 -1
  6. package/backend/dist/middleware/auth.js +153 -33
  7. package/backend/dist/middleware/auth.js.map +1 -1
  8. package/backend/dist/persistence/index.d.ts +1 -0
  9. package/backend/dist/persistence/index.d.ts.map +1 -1
  10. package/backend/dist/persistence/index.js.map +1 -1
  11. package/backend/dist/persistence/postgresMigrationRegistry.d.ts.map +1 -1
  12. package/backend/dist/persistence/postgresMigrationRegistry.js +2 -0
  13. package/backend/dist/persistence/postgresMigrationRegistry.js.map +1 -1
  14. package/backend/dist/persistence/postgresPersistence.d.ts.map +1 -1
  15. package/backend/dist/persistence/postgresPersistence.js +4 -0
  16. package/backend/dist/persistence/postgresPersistence.js.map +1 -1
  17. package/backend/dist/persistence/postgresSecurityRepositories.d.ts +7 -0
  18. package/backend/dist/persistence/postgresSecurityRepositories.d.ts.map +1 -0
  19. package/backend/dist/persistence/postgresSecurityRepositories.js +435 -0
  20. package/backend/dist/persistence/postgresSecurityRepositories.js.map +1 -0
  21. package/backend/dist/persistence/postgresTrustFoundationMigration.d.ts +8 -0
  22. package/backend/dist/persistence/postgresTrustFoundationMigration.d.ts.map +1 -0
  23. package/backend/dist/persistence/postgresTrustFoundationMigration.js +151 -0
  24. package/backend/dist/persistence/postgresTrustFoundationMigration.js.map +1 -0
  25. package/backend/dist/persistence/securityTypes.d.ts +196 -0
  26. package/backend/dist/persistence/securityTypes.d.ts.map +1 -0
  27. package/backend/dist/persistence/securityTypes.js +18 -0
  28. package/backend/dist/persistence/securityTypes.js.map +1 -0
  29. package/backend/dist/persistence/sqliteMigrations.d.ts +1 -0
  30. package/backend/dist/persistence/sqliteMigrations.d.ts.map +1 -1
  31. package/backend/dist/persistence/sqliteMigrations.js +311 -0
  32. package/backend/dist/persistence/sqliteMigrations.js.map +1 -1
  33. package/backend/dist/persistence/sqlitePersistence.d.ts.map +1 -1
  34. package/backend/dist/persistence/sqlitePersistence.js +3 -0
  35. package/backend/dist/persistence/sqlitePersistence.js.map +1 -1
  36. package/backend/dist/persistence/sqliteSecurityRepositories.d.ts +6 -0
  37. package/backend/dist/persistence/sqliteSecurityRepositories.d.ts.map +1 -0
  38. package/backend/dist/persistence/sqliteSecurityRepositories.js +497 -0
  39. package/backend/dist/persistence/sqliteSecurityRepositories.js.map +1 -0
  40. package/backend/dist/persistence/sqliteToPostgresMigration.d.ts.map +1 -1
  41. package/backend/dist/persistence/sqliteToPostgresMigration.js +55 -0
  42. package/backend/dist/persistence/sqliteToPostgresMigration.js.map +1 -1
  43. package/backend/dist/persistence/types.d.ts +4 -0
  44. package/backend/dist/persistence/types.d.ts.map +1 -1
  45. package/backend/dist/platform/jobs/domainJobHandlers.d.ts.map +1 -1
  46. package/backend/dist/platform/jobs/domainJobHandlers.js +7 -0
  47. package/backend/dist/platform/jobs/domainJobHandlers.js.map +1 -1
  48. package/backend/dist/routes/access.d.ts +3 -0
  49. package/backend/dist/routes/access.d.ts.map +1 -0
  50. package/backend/dist/routes/access.js +134 -0
  51. package/backend/dist/routes/access.js.map +1 -0
  52. package/backend/dist/routes/audit.d.ts +3 -0
  53. package/backend/dist/routes/audit.d.ts.map +1 -0
  54. package/backend/dist/routes/audit.js +82 -0
  55. package/backend/dist/routes/audit.js.map +1 -0
  56. package/backend/dist/routes/auth.d.ts.map +1 -1
  57. package/backend/dist/routes/auth.js +342 -14
  58. package/backend/dist/routes/auth.js.map +1 -1
  59. package/backend/dist/routes/groups.d.ts +3 -0
  60. package/backend/dist/routes/groups.d.ts.map +1 -0
  61. package/backend/dist/routes/groups.js +161 -0
  62. package/backend/dist/routes/groups.js.map +1 -0
  63. package/backend/dist/services/apiTokenService.d.ts +51 -0
  64. package/backend/dist/services/apiTokenService.d.ts.map +1 -0
  65. package/backend/dist/services/apiTokenService.js +220 -0
  66. package/backend/dist/services/apiTokenService.js.map +1 -0
  67. package/backend/dist/services/authService.d.ts +20 -4
  68. package/backend/dist/services/authService.d.ts.map +1 -1
  69. package/backend/dist/services/authService.js +44 -6
  70. package/backend/dist/services/authService.js.map +1 -1
  71. package/backend/dist/services/authSessionService.d.ts +34 -0
  72. package/backend/dist/services/authSessionService.d.ts.map +1 -0
  73. package/backend/dist/services/authSessionService.js +205 -0
  74. package/backend/dist/services/authSessionService.js.map +1 -0
  75. package/backend/dist/services/authorizationService.d.ts +64 -0
  76. package/backend/dist/services/authorizationService.d.ts.map +1 -0
  77. package/backend/dist/services/authorizationService.js +176 -0
  78. package/backend/dist/services/authorizationService.js.map +1 -0
  79. package/backend/dist/services/groupService.d.ts +27 -0
  80. package/backend/dist/services/groupService.d.ts.map +1 -0
  81. package/backend/dist/services/groupService.js +245 -0
  82. package/backend/dist/services/groupService.js.map +1 -0
  83. package/backend/dist/services/groupVectorPrincipalResolver.d.ts +12 -0
  84. package/backend/dist/services/groupVectorPrincipalResolver.d.ts.map +1 -0
  85. package/backend/dist/services/groupVectorPrincipalResolver.js +33 -0
  86. package/backend/dist/services/groupVectorPrincipalResolver.js.map +1 -0
  87. package/backend/dist/services/modelAccessService.d.ts +1 -0
  88. package/backend/dist/services/modelAccessService.d.ts.map +1 -1
  89. package/backend/dist/services/modelAccessService.js +3 -5
  90. package/backend/dist/services/modelAccessService.js.map +1 -1
  91. package/backend/dist/services/oauthSecurity.d.ts +12 -1
  92. package/backend/dist/services/oauthSecurity.d.ts.map +1 -1
  93. package/backend/dist/services/oauthSecurity.js +41 -0
  94. package/backend/dist/services/oauthSecurity.js.map +1 -1
  95. package/backend/dist/services/resourceGrantService.d.ts +28 -0
  96. package/backend/dist/services/resourceGrantService.d.ts.map +1 -0
  97. package/backend/dist/services/resourceGrantService.js +192 -0
  98. package/backend/dist/services/resourceGrantService.js.map +1 -0
  99. package/backend/dist/services/securityAuditService.d.ts +35 -0
  100. package/backend/dist/services/securityAuditService.d.ts.map +1 -0
  101. package/backend/dist/services/securityAuditService.js +159 -0
  102. package/backend/dist/services/securityAuditService.js.map +1 -0
  103. package/backend/dist/services/simpleGitHubOAuth.d.ts.map +1 -1
  104. package/backend/dist/services/simpleGitHubOAuth.js +4 -2
  105. package/backend/dist/services/simpleGitHubOAuth.js.map +1 -1
  106. package/backend/dist/services/simpleOidcOAuth.d.ts +62 -0
  107. package/backend/dist/services/simpleOidcOAuth.d.ts.map +1 -0
  108. package/backend/dist/services/simpleOidcOAuth.js +397 -0
  109. package/backend/dist/services/simpleOidcOAuth.js.map +1 -0
  110. package/backend/dist/services/webSearchService.d.ts +1 -0
  111. package/backend/dist/services/webSearchService.d.ts.map +1 -1
  112. package/backend/dist/services/webSearchService.js +3 -5
  113. package/backend/dist/services/webSearchService.js.map +1 -1
  114. package/backend/dist/services/websocketTicketService.d.ts +3 -1
  115. package/backend/dist/services/websocketTicketService.d.ts.map +1 -1
  116. package/backend/dist/services/websocketTicketService.js +4 -1
  117. package/backend/dist/services/websocketTicketService.js.map +1 -1
  118. package/backend/dist/services/workAccessService.d.ts +1 -0
  119. package/backend/dist/services/workAccessService.d.ts.map +1 -1
  120. package/backend/dist/services/workAccessService.js +3 -5
  121. package/backend/dist/services/workAccessService.js.map +1 -1
  122. package/backend/dist/services/workEventService.d.ts.map +1 -1
  123. package/backend/dist/services/workEventService.js +74 -18
  124. package/backend/dist/services/workEventService.js.map +1 -1
  125. package/backend/dist/services/workRuntimeService.d.ts +11 -0
  126. package/backend/dist/services/workRuntimeService.d.ts.map +1 -1
  127. package/backend/dist/services/workRuntimeService.js +78 -23
  128. package/backend/dist/services/workRuntimeService.js.map +1 -1
  129. package/backend/dist/websocketServer.d.ts.map +1 -1
  130. package/backend/dist/websocketServer.js +25 -1
  131. package/backend/dist/websocketServer.js.map +1 -1
  132. package/backend/dist/workTerminalServer.d.ts.map +1 -1
  133. package/backend/dist/workTerminalServer.js +19 -1
  134. package/backend/dist/workTerminalServer.js.map +1 -1
  135. package/backend/dist/worker.js +2 -0
  136. package/backend/dist/worker.js.map +1 -1
  137. package/backend/package.json +1 -1
  138. package/frontend/dist/artifact-runtime/.build-fingerprint +1 -1
  139. package/frontend/dist/assets/index-BXMQqOXF.js +11 -0
  140. package/frontend/dist/assets/index-DBaj1DRj.css +1 -0
  141. package/frontend/dist/index.html +11 -11
  142. package/frontend/dist/js/ArtifactContainer-BUjOZ5M5.js +1 -0
  143. package/frontend/dist/js/{ArtifactDemoPage-BDBXYv9l.js → ArtifactDemoPage-QRve-734.js} +1 -1
  144. package/frontend/dist/js/{ArtifactSandboxFrame-BN16NtKe.js → ArtifactSandboxFrame-DhvA-t-7.js} +2 -2
  145. package/frontend/dist/js/ArtifactSlideOutPanel-B8w1Orr1.js +1 -0
  146. package/frontend/dist/js/ChatPage-DKVwaYxn.js +23 -0
  147. package/frontend/dist/js/FirstTimeSetup-DaQveC0v.js +1 -0
  148. package/frontend/dist/js/{GalleryPage-CV_vbE7X.js → GalleryPage-Cz-VvarV.js} +1 -1
  149. package/frontend/dist/js/{HomePage-P-e7Huco.js → HomePage-DF9pZ5V5.js} +1 -1
  150. package/frontend/dist/js/{LibreClawPage-Cee06SUM.js → LibreClawPage-Dw8YQyFj.js} +1 -1
  151. package/frontend/dist/js/{ModelManagerModals-D7jIT3v1.js → ModelManagerModals-CZAWUxjI.js} +1 -1
  152. package/frontend/dist/js/{ModelSelector-DXucbvrz.js → ModelSelector-Cc91MEm4.js} +1 -1
  153. package/frontend/dist/js/ModelsPage-BgaQuCry.js +2 -0
  154. package/frontend/dist/js/{NotesPage-rEIPWGIb.js → NotesPage-CRAo-TFI.js} +1 -1
  155. package/frontend/dist/js/{PersonasPage-BXtepFuD.js → PersonasPage-DpN8DQkY.js} +2 -2
  156. package/frontend/dist/js/{PluginUsagePage-hhu8cxsu.js → PluginUsagePage-5PXXZXle.js} +1 -1
  157. package/frontend/dist/js/{RichMessageContent-DkiEvdSg.js → RichMessageContent-C67tFlr1.js} +1 -1
  158. package/frontend/dist/js/SettingsModal-BEzMSDlp.js +1 -0
  159. package/frontend/dist/js/SystemPage-FUnoW7Er.js +1 -0
  160. package/frontend/dist/js/UserManagementPage-SBsRbt0H.js +1 -0
  161. package/frontend/dist/js/WorkPage-D3ChSFo-.js +6 -0
  162. package/frontend/dist/js/api-Dw_IuHaz.js +14 -0
  163. package/frontend/dist/js/{appStore-DRSSjaHn.js → appStore-DAT2R-5p.js} +2 -2
  164. package/frontend/dist/js/ar-D0z0P4rC.js +2 -0
  165. package/frontend/dist/js/{authStore-BVykIRec.js → authStore-CwSMGkEM.js} +3 -3
  166. package/frontend/dist/js/bn-BYYU41A7.js +2 -0
  167. package/frontend/dist/js/chatStore-BK6YcouV.js +3 -0
  168. package/frontend/dist/js/{config-BTlPm-cZ.js → config-0eBxRk6E.js} +1 -1
  169. package/frontend/dist/js/cs-BFx6KNZe.js +2 -0
  170. package/frontend/dist/js/da-DSDuY5Du.js +2 -0
  171. package/frontend/dist/js/de-YqhP0FmX.js +2 -0
  172. package/frontend/dist/js/es-Dpr_y1cN.js +2 -0
  173. package/frontend/dist/js/{estree-CfYahF_d.js → estree-Db_NKIE7.js} +1 -1
  174. package/frontend/dist/js/fr-nVg_iAEC.js +2 -0
  175. package/frontend/dist/js/hi-gHKYCgkP.js +2 -0
  176. package/frontend/dist/js/{html-BJsDX1UZ.js → html-INl_p8N8.js} +1 -1
  177. package/frontend/dist/js/id-C_yID1Zk.js +2 -0
  178. package/frontend/dist/js/is-MoRPLbOM.js +2 -0
  179. package/frontend/dist/js/it-BZTscLxR.js +2 -0
  180. package/frontend/dist/js/ja-DpIbtmZq.js +2 -0
  181. package/frontend/dist/js/ko-LkWggmjU.js +2 -0
  182. package/frontend/dist/js/{markdown-GLyuUNig.js → markdown-DQbfLH11.js} +1 -1
  183. package/frontend/dist/js/{messageCodeStyles-BHddEFP1.js → messageCodeStyles-D7zXzjgH.js} +2 -2
  184. package/frontend/dist/js/ms-p3XiQSAo.js +2 -0
  185. package/frontend/dist/js/nl-sEHHO2Kb.js +2 -0
  186. package/frontend/dist/js/pl-D2GD6PDW.js +2 -0
  187. package/frontend/dist/js/pt-DPkn3GUn.js +2 -0
  188. package/frontend/dist/js/ru-C42iHrEd.js +2 -0
  189. package/frontend/dist/js/{standalone-Dh56V0YW.js → standalone-CFSd7xCM.js} +1 -1
  190. package/frontend/dist/js/sv-CGvHo4os.js +2 -0
  191. package/frontend/dist/js/th-BaDNpCdY.js +2 -0
  192. package/frontend/dist/js/tr-BHQvi1cN.js +2 -0
  193. package/frontend/dist/js/{typescript-DRy7A9w4.js → typescript-BIFKSiW0.js} +1 -1
  194. package/frontend/dist/js/{ui-CuY4IifA.js → ui-CS8EAgvS.js} +2 -2
  195. package/frontend/dist/js/{ui-vendor-D3Ahl1x5.js → ui-vendor-54SgntkX.js} +1 -1
  196. package/frontend/dist/js/uk-7pNGS1b2.js +2 -0
  197. package/frontend/dist/js/vi-DgAfh6mo.js +2 -0
  198. package/frontend/dist/js/{workApi-DHuYNHLf.js → workApi-DlmJ72dN.js} +2 -2
  199. package/frontend/dist/js/zh-FRTz6ZqA.js +2 -0
  200. package/package.json +2 -2
  201. package/frontend/dist/assets/index-Jtx9Amhz.js +0 -16
  202. package/frontend/dist/assets/index-kxtZQLV6.css +0 -1
  203. package/frontend/dist/js/ArtifactContainer-fZegtmva.js +0 -1
  204. package/frontend/dist/js/ArtifactSlideOutPanel-x1fS85Ww.js +0 -1
  205. package/frontend/dist/js/ChatPage-C_pXh7WN.js +0 -23
  206. package/frontend/dist/js/FirstTimeSetup-oRrlZnBm.js +0 -1
  207. package/frontend/dist/js/ModelsPage-C3_fZpMM.js +0 -2
  208. package/frontend/dist/js/SettingsModal-BNxCtJ51.js +0 -1
  209. package/frontend/dist/js/SystemPage-BvvKFuoG.js +0 -1
  210. package/frontend/dist/js/UserManagementPage-BccyR7si.js +0 -1
  211. package/frontend/dist/js/WorkPage-BgxrvY3I.js +0 -6
  212. package/frontend/dist/js/api-BvPDxsUQ.js +0 -14
  213. package/frontend/dist/js/ar-xTSvTq05.js +0 -2
  214. package/frontend/dist/js/bn-iYAsohEA.js +0 -2
  215. package/frontend/dist/js/chatStore-UPp5TV_t.js +0 -3
  216. package/frontend/dist/js/cs-YBHN88Hb.js +0 -2
  217. package/frontend/dist/js/da-D7qlLy_k.js +0 -2
  218. package/frontend/dist/js/de-DV671k2c.js +0 -2
  219. package/frontend/dist/js/es-kyBgzNq-.js +0 -2
  220. package/frontend/dist/js/fr-Cw1vut7I.js +0 -2
  221. package/frontend/dist/js/hi-DWEFC024.js +0 -2
  222. package/frontend/dist/js/id-DlMHjjy0.js +0 -2
  223. package/frontend/dist/js/is-B9E_a7dG.js +0 -2
  224. package/frontend/dist/js/it-DawmVbLC.js +0 -2
  225. package/frontend/dist/js/ja-DmVvwY3W.js +0 -2
  226. package/frontend/dist/js/ko-DzOPpkVs.js +0 -2
  227. package/frontend/dist/js/ms-DpsaOPht.js +0 -2
  228. package/frontend/dist/js/nl-B1d8W22n.js +0 -2
  229. package/frontend/dist/js/pl-nCncRVgt.js +0 -2
  230. package/frontend/dist/js/pt-DHw8fGuu.js +0 -2
  231. package/frontend/dist/js/ru-Derl_YP_.js +0 -2
  232. package/frontend/dist/js/sv-pJAfBVo0.js +0 -2
  233. package/frontend/dist/js/th-C_7fIGnk.js +0 -2
  234. package/frontend/dist/js/tr-CPqsJvaP.js +0 -2
  235. package/frontend/dist/js/uk-3o8P_kFi.js +0 -2
  236. package/frontend/dist/js/vi-Dv6N7OVD.js +0 -2
  237. package/frontend/dist/js/zh-qg5iqtPi.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/services/authService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/services/authService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { StoredAuthSessionRecord } from '../persistence/index.js';
2
+ export declare const SESSION_REVOCATION_TOPIC = "security.sessions.revoked.v1";
3
+ export interface SessionRevocationEvent {
4
+ version: 1;
5
+ userId: string;
6
+ sessionIds: string[];
7
+ }
8
+ export interface SessionIssueMetadata {
9
+ kind: string;
10
+ ip?: string | undefined;
11
+ userAgent?: string | undefined;
12
+ }
13
+ type SessionRevocationListener = (event: SessionRevocationEvent) => void;
14
+ /** Register for advisory revocation events (e.g. to close live sockets). */
15
+ export declare const registerSessionRevocationListener: (listener: SessionRevocationListener) => (() => void);
16
+ export declare const ensureSessionRevocationSubscription: () => Promise<void>;
17
+ export declare const createAuthSession: (userId: string, metadata: SessionIssueMetadata, expiresAt: number) => Promise<StoredAuthSessionRecord>;
18
+ /** A session usable for authentication right now, or null. */
19
+ export declare const getValidSession: (sessionId: string) => Promise<StoredAuthSessionRecord | null>;
20
+ export declare const touchSessionThrottled: (record: StoredAuthSessionRecord) => Promise<void>;
21
+ export declare const listSessionsForUser: (userId: string) => Promise<StoredAuthSessionRecord[]>;
22
+ export declare const findSessionById: (sessionId: string) => Promise<StoredAuthSessionRecord | null>;
23
+ export declare const revokeAuthSession: (sessionId: string, revokedBy: string) => Promise<boolean>;
24
+ /**
25
+ * Revoke every session for a user (optionally sparing the current one).
26
+ * Also stamps the invalid-before epoch so legacy tokens without a session
27
+ * id are rejected too.
28
+ */
29
+ export declare const revokeAllAuthSessions: (userId: string, revokedBy: string, exceptSessionId?: string) => Promise<string[]>;
30
+ /** Epoch (ms) before which any token for this user is rejected. */
31
+ export declare const getTokenInvalidBefore: (userId: string) => Promise<number>;
32
+ export declare const closeSessionRevocationSubscription: () => Promise<void>;
33
+ export {};
34
+ //# sourceMappingURL=authSessionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authSessionService.d.ts","sourceRoot":"","sources":["../../src/services/authSessionService.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAOvE,eAAO,MAAM,wBAAwB,iCAAiC,CAAC;AAEvE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AASD,KAAK,yBAAyB,GAAG,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;AA8BzE,4EAA4E;AAC5E,eAAO,MAAM,iCAAiC,aAClC,yBAAyB,KAClC,CAAC,MAAM,IAAI,CAGb,CAAC;AAEF,eAAO,MAAM,mCAAmC,QAAa,OAAO,CAAC,IAAI,CAkBxE,CAAC;AAwCF,eAAO,MAAM,iBAAiB,WACpB,MAAM,YACJ,oBAAoB,aACnB,MAAM,KAChB,OAAO,CAAC,uBAAuB,CAoBjC,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,eAAe,cACf,MAAM,KAChB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAOxC,CAAC;AAEF,eAAO,MAAM,qBAAqB,WACxB,uBAAuB,KAC9B,OAAO,CAAC,IAAI,CAMd,CAAC;AAEF,eAAO,MAAM,mBAAmB,WACtB,MAAM,KACb,OAAO,CAAC,uBAAuB,EAAE,CACQ,CAAC;AAE7C,eAAO,MAAM,eAAe,cACf,MAAM,KAChB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CACI,CAAC;AAE9C,eAAO,MAAM,iBAAiB,cACjB,MAAM,aACN,MAAM,KAChB,OAAO,CAAC,OAAO,CAUjB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,WACxB,MAAM,aACH,MAAM,oBACC,MAAM,KACvB,OAAO,CAAC,MAAM,EAAE,CAalB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,WACxB,MAAM,KACb,OAAO,CAAC,MAAM,CAIhB,CAAC;AAEF,eAAO,MAAM,kCAAkC,QAAa,OAAO,CAAC,IAAI,CAKvE,CAAC"}
@@ -0,0 +1,205 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Server-side auth sessions (IAM-04).
19
+ *
20
+ * Every issued JWT is bound to an `auth_sessions` row through its `sid`
21
+ * claim. The database is authoritative: a revoked or expired row makes the
22
+ * token unusable on the next request regardless of the JWT lifetime. The
23
+ * coordinator topic is an advisory fan-out that lets other replicas and live
24
+ * WebSocket connections react immediately.
25
+ *
26
+ * Tokens issued before this feature carry no `sid`. They stay valid until
27
+ * expiry unless the user (or an administrator) revokes all sessions, which
28
+ * also records a per-user invalid-before timestamp that rejects any token
29
+ * minted earlier — so "sign out everywhere" is complete even for legacy
30
+ * tokens.
31
+ */
32
+ import { randomUUID } from 'node:crypto';
33
+ import { getInitializedCoordinator } from '../platform/coordination/service.js';
34
+ import { getPersistence } from '../persistence/index.js';
35
+ import { encryptionService } from './encryptionService.js';
36
+ import { getSystemSetting, setSystemSetting } from './systemSettingsService.js';
37
+ import { createLogger } from '../utils/logger.js';
38
+ const logger = createLogger('services:auth-sessions');
39
+ export const SESSION_REVOCATION_TOPIC = 'security.sessions.revoked.v1';
40
+ const LAST_SEEN_THROTTLE_MS = 60000;
41
+ const PURGE_EVERY_N_READS = 1000;
42
+ let readsSincePurge = 0;
43
+ const invalidBeforeKey = (userId) => `auth_token_invalid_before:${userId}`;
44
+ const listeners = new Set();
45
+ let subscription;
46
+ const isRevocationEvent = (value) => {
47
+ if (!value || typeof value !== 'object' || Array.isArray(value))
48
+ return false;
49
+ const candidate = value;
50
+ return (candidate.version === 1 &&
51
+ typeof candidate.userId === 'string' &&
52
+ Array.isArray(candidate.sessionIds) &&
53
+ candidate.sessionIds.every(id => typeof id === 'string'));
54
+ };
55
+ const dispatch = (event) => {
56
+ for (const listener of [...listeners]) {
57
+ try {
58
+ listener(event);
59
+ }
60
+ catch {
61
+ // The database stays authoritative; a broken consumer must not stop
62
+ // other live connections from being closed.
63
+ logger.warn('A session revocation listener failed');
64
+ }
65
+ }
66
+ };
67
+ /** Register for advisory revocation events (e.g. to close live sockets). */
68
+ export const registerSessionRevocationListener = (listener) => {
69
+ listeners.add(listener);
70
+ return () => listeners.delete(listener);
71
+ };
72
+ export const ensureSessionRevocationSubscription = async () => {
73
+ const coordinator = getInitializedCoordinator();
74
+ if (!coordinator)
75
+ return;
76
+ if (subscription?.coordinator === coordinator)
77
+ return;
78
+ const previous = subscription;
79
+ subscription = undefined;
80
+ if (previous)
81
+ await previous.unsubscribe().catch(() => undefined);
82
+ const unsubscribe = await coordinator.subscribe(SESSION_REVOCATION_TOPIC, event => {
83
+ if (!isRevocationEvent(event.payload)) {
84
+ logger.warn('Ignoring an invalid session revocation message');
85
+ return;
86
+ }
87
+ dispatch(event.payload);
88
+ });
89
+ subscription = { coordinator, unsubscribe };
90
+ };
91
+ const publishRevocation = async (userId, sessionIds) => {
92
+ const event = { version: 1, userId, sessionIds };
93
+ // Local listeners first: revocation must reach this replica's sockets even
94
+ // when the coordinator is degraded.
95
+ dispatch(event);
96
+ try {
97
+ const coordinator = getInitializedCoordinator();
98
+ if (!coordinator)
99
+ return;
100
+ await ensureSessionRevocationSubscription();
101
+ await coordinator.publish(SESSION_REVOCATION_TOPIC, event);
102
+ await coordinator.revoke(`user-sessions:${userId}`).catch(() => undefined);
103
+ }
104
+ catch {
105
+ // The revoked rows are already committed; every replica enforces them on
106
+ // its next database read even without the advisory fan-out.
107
+ logger.warn('Session revocation publication failed');
108
+ }
109
+ };
110
+ const security = () => getPersistence(encryptionService).repositories.security;
111
+ const purgeOpportunistically = async () => {
112
+ readsSincePurge += 1;
113
+ if (readsSincePurge < PURGE_EVERY_N_READS)
114
+ return;
115
+ readsSincePurge = 0;
116
+ try {
117
+ // Keep expired rows for seven days so the session inventory can show
118
+ // recently expired devices before they disappear.
119
+ await security().authSessions.deleteExpired(Date.now() - 7 * 24 * 60 * 60 * 1000);
120
+ }
121
+ catch (error) {
122
+ logger.warn('Expired session purge failed', { error });
123
+ }
124
+ };
125
+ export const createAuthSession = async (userId, metadata, expiresAt) => {
126
+ const now = Date.now();
127
+ const record = {
128
+ id: randomUUID(),
129
+ user_id: userId,
130
+ kind: metadata.kind,
131
+ ip_hash: null,
132
+ user_agent: metadata.userAgent?.slice(0, 256) ?? null,
133
+ created_at: now,
134
+ last_seen_at: now,
135
+ expires_at: expiresAt,
136
+ revoked_at: null,
137
+ revoked_by: null,
138
+ };
139
+ if (metadata.ip) {
140
+ const { hashClientIp } = await import('./securityAuditService.js');
141
+ record.ip_hash = hashClientIp(metadata.ip);
142
+ }
143
+ await security().authSessions.insert(record);
144
+ return record;
145
+ };
146
+ /** A session usable for authentication right now, or null. */
147
+ export const getValidSession = async (sessionId) => {
148
+ const record = await security().authSessions.findById(sessionId);
149
+ await purgeOpportunistically();
150
+ if (!record)
151
+ return null;
152
+ if (record.revoked_at !== null)
153
+ return null;
154
+ if (record.expires_at <= Date.now())
155
+ return null;
156
+ return record;
157
+ };
158
+ export const touchSessionThrottled = async (record) => {
159
+ const now = Date.now();
160
+ if (now - record.last_seen_at < LAST_SEEN_THROTTLE_MS)
161
+ return;
162
+ await security()
163
+ .authSessions.touch(record.id, now)
164
+ .catch(() => undefined);
165
+ };
166
+ export const listSessionsForUser = (userId) => security().authSessions.listByUser(userId);
167
+ export const findSessionById = (sessionId) => security().authSessions.findById(sessionId);
168
+ export const revokeAuthSession = async (sessionId, revokedBy) => {
169
+ const record = await security().authSessions.findById(sessionId);
170
+ if (!record)
171
+ return false;
172
+ const revoked = await security().authSessions.revoke(sessionId, Date.now(), revokedBy);
173
+ if (revoked)
174
+ await publishRevocation(record.user_id, [sessionId]);
175
+ return revoked;
176
+ };
177
+ /**
178
+ * Revoke every session for a user (optionally sparing the current one).
179
+ * Also stamps the invalid-before epoch so legacy tokens without a session
180
+ * id are rejected too.
181
+ */
182
+ export const revokeAllAuthSessions = async (userId, revokedBy, exceptSessionId) => {
183
+ const revokedIds = await security().authSessions.revokeAllForUser(userId, Date.now(), revokedBy, exceptSessionId);
184
+ if (!exceptSessionId) {
185
+ // A full sign-out invalidates sid-less legacy tokens as well.
186
+ await setSystemSetting(invalidBeforeKey(userId), String(Date.now()));
187
+ }
188
+ if (revokedIds.length > 0)
189
+ await publishRevocation(userId, revokedIds);
190
+ return revokedIds;
191
+ };
192
+ /** Epoch (ms) before which any token for this user is rejected. */
193
+ export const getTokenInvalidBefore = async (userId) => {
194
+ const value = await getSystemSetting(invalidBeforeKey(userId));
195
+ const parsed = Number.parseInt(value ?? '', 10);
196
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
197
+ };
198
+ export const closeSessionRevocationSubscription = async () => {
199
+ const current = subscription;
200
+ subscription = undefined;
201
+ listeners.clear();
202
+ if (current)
203
+ await current.unsubscribe().catch(() => undefined);
204
+ };
205
+ //# sourceMappingURL=authSessionService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authSessionService.js","sourceRoot":"","sources":["../../src/services/authSessionService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { ArchiveOwnedResource, GrantPermission, StoredResourceGrantRecord } from '../persistence/index.js';
2
+ export type AuthzAction = 'read' | 'write' | 'manage' | 'use';
3
+ export type FeatureId = 'work' | 'model-download' | 'web-search' | 'agents';
4
+ /** Grantable resource families reuse the portable-archive taxonomy. */
5
+ export type ShareableResourceType = ArchiveOwnedResource;
6
+ export declare const SHAREABLE_RESOURCE_TYPES: readonly ShareableResourceType[];
7
+ export declare const isShareableResourceType: (value: unknown) => value is ShareableResourceType;
8
+ export interface AuthzActor {
9
+ userId: string;
10
+ role?: string | undefined;
11
+ status?: string | undefined;
12
+ }
13
+ export type AuthzResource = {
14
+ type: 'feature';
15
+ id: FeatureId;
16
+ } | {
17
+ type: ShareableResourceType;
18
+ id: string;
19
+ ownerUserId?: string;
20
+ };
21
+ export interface AuthzDecision {
22
+ allowed: boolean;
23
+ reason: string;
24
+ }
25
+ export declare class AuthorizationError extends Error {
26
+ readonly statusCode = 403;
27
+ constructor(message?: string);
28
+ }
29
+ /** Group memberships resolved fresh so removals apply immediately. */
30
+ export declare const resolveGroupIdsForUser: (userId: string) => Promise<string[]>;
31
+ /** Effective grants a user holds on a resource, via user and group rows. */
32
+ export declare const effectiveGrantsFor: (userId: string, resourceType: ShareableResourceType, resourceId: string) => Promise<StoredResourceGrantRecord[]>;
33
+ export declare const authorize: (actor: AuthzActor, action: AuthzAction, resource: AuthzResource) => Promise<AuthzDecision>;
34
+ /** Throwing variant for route and service guards. */
35
+ export declare const requireAuthorized: (actor: AuthzActor, action: AuthzAction, resource: AuthzResource) => Promise<AuthzDecision>;
36
+ export interface EffectiveAccessView {
37
+ userId: string;
38
+ role: string | null;
39
+ status: string | null;
40
+ groups: Array<{
41
+ id: string;
42
+ name: string;
43
+ }>;
44
+ features: Record<FeatureId, boolean>;
45
+ grants: Array<{
46
+ id: string;
47
+ resourceType: string;
48
+ resourceId: string;
49
+ permission: GrantPermission;
50
+ via: 'user' | 'group';
51
+ principalId: string;
52
+ }>;
53
+ }
54
+ /**
55
+ * "Why can this user access this?" — the complete effective-access picture
56
+ * for one user: role, groups, feature gates, and every grant that reaches
57
+ * them directly or through a group.
58
+ */
59
+ export declare const explainEffectiveAccess: (user: {
60
+ id: string;
61
+ role?: string;
62
+ status?: string;
63
+ }) => Promise<EffectiveAccessView>;
64
+ //# sourceMappingURL=authorizationService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorizationService.d.ts","sourceRoot":"","sources":["../../src/services/authorizationService.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AAOjC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,gBAAgB,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE5E,uEAAuE;AACvE,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAEzD,eAAO,MAAM,wBAAwB,EAAE,SAAS,qBAAqB,EAOpE,CAAC;AAEF,eAAO,MAAM,uBAAuB,UAC3B,OAAO,KACb,KAAK,IAAI,qBAEqD,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,SAAS,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,UAAU,OAAO;IAC1B,YAAY,OAAO,SAAkB,EAGpC;CACF;AAOD,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,WAAY,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CACzB,CAAC;AAoChD,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,WACrB,MAAM,gBACA,qBAAqB,cACvB,MAAM,KACjB,OAAO,CAAC,yBAAyB,EAAE,CAQrC,CAAC;AAEF,eAAO,MAAM,SAAS,UACb,UAAU,UACT,WAAW,YACT,aAAa,KACtB,OAAO,CAAC,aAAa,CAsCvB,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,UACrB,UAAU,UACT,WAAW,YACT,aAAa,KACtB,OAAO,CAAC,aAAa,CAIvB,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACrC,MAAM,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,eAAe,CAAC;QAC5B,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,SAAgB;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,OAAO,CAAC,mBAAmB,CA2C9B,CAAC"}
@@ -0,0 +1,176 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at:
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Central authorization (IAM-01).
19
+ *
20
+ * One decision point for feature gates and shareable-resource access:
21
+ *
22
+ * role/feature permissions + ownership + direct grants + group grants
23
+ * = effective allow
24
+ *
25
+ * Feature gates keep their existing semantics (admin always allowed, others
26
+ * by the admin-controlled mode); the per-feature services now delegate here.
27
+ * Resource decisions are private by default: the owner has every permission,
28
+ * other users only what an explicit user or group grant confers. The admin
29
+ * role deliberately does NOT bypass resource privacy — administration is a
30
+ * feature-level power, not a content read.
31
+ *
32
+ * `explainEffectiveAccess` answers "why can this user access this?" for the
33
+ * administrator-facing effective-access view.
34
+ */
35
+ import { getPersistence } from '../persistence/index.js';
36
+ import { encryptionService } from './encryptionService.js';
37
+ import { getWorkAccessMode } from './workAccessService.js';
38
+ import { getModelDownloadMode } from './modelAccessService.js';
39
+ import { getAgentsEnabled } from './agentAccessService.js';
40
+ import { getWebSearchAccessMode } from './webSearchService.js';
41
+ export const SHAREABLE_RESOURCE_TYPES = [
42
+ 'session',
43
+ 'session-folder',
44
+ 'note',
45
+ 'knowledge-collection',
46
+ 'document',
47
+ 'persona',
48
+ ];
49
+ export const isShareableResourceType = (value) => typeof value === 'string' &&
50
+ SHAREABLE_RESOURCE_TYPES.includes(value);
51
+ export class AuthorizationError extends Error {
52
+ constructor(message = 'Access denied') {
53
+ super(message);
54
+ this.statusCode = 403;
55
+ this.name = 'AuthorizationError';
56
+ }
57
+ }
58
+ const security = () => getPersistence(encryptionService).repositories.security;
59
+ const archive = () => getPersistence(encryptionService).repositories.resources.archive;
60
+ /** Group memberships resolved fresh so removals apply immediately. */
61
+ export const resolveGroupIdsForUser = (userId) => security().groups.listGroupIdsForUser(userId);
62
+ const permissionSatisfies = (granted, action) => {
63
+ if (action === 'read' || action === 'use')
64
+ return true;
65
+ if (action === 'write')
66
+ return granted === 'write' || granted === 'admin';
67
+ return granted === 'admin';
68
+ };
69
+ const featureDecision = async (actor, featureId) => {
70
+ if (actor.role === 'admin')
71
+ return { allowed: true, reason: 'admin-role' };
72
+ switch (featureId) {
73
+ case 'work':
74
+ return (await getWorkAccessMode()) === 'all-users'
75
+ ? { allowed: true, reason: 'feature-open-to-all-users' }
76
+ : { allowed: false, reason: 'feature-restricted-to-admins' };
77
+ case 'model-download':
78
+ return (await getModelDownloadMode()) === 'all-users'
79
+ ? { allowed: true, reason: 'feature-open-to-all-users' }
80
+ : { allowed: false, reason: 'feature-restricted-to-admins' };
81
+ case 'web-search':
82
+ return (await getWebSearchAccessMode()) === 'all-users'
83
+ ? { allowed: true, reason: 'feature-open-to-all-users' }
84
+ : { allowed: false, reason: 'feature-restricted-to-admins' };
85
+ case 'agents':
86
+ return (await getAgentsEnabled())
87
+ ? { allowed: true, reason: 'feature-enabled' }
88
+ : { allowed: false, reason: 'feature-disabled' };
89
+ }
90
+ };
91
+ /** Effective grants a user holds on a resource, via user and group rows. */
92
+ export const effectiveGrantsFor = async (userId, resourceType, resourceId) => {
93
+ const groupIds = await resolveGroupIdsForUser(userId);
94
+ return security().grants.listEffective(resourceType, resourceId, userId, groupIds);
95
+ };
96
+ export const authorize = async (actor, action, resource) => {
97
+ if (actor.status !== undefined && actor.status !== 'active') {
98
+ return { allowed: false, reason: 'inactive-account' };
99
+ }
100
+ if (resource.type === 'feature') {
101
+ return featureDecision(actor, resource.id);
102
+ }
103
+ const ownerUserId = resource.ownerUserId ??
104
+ (await archive().ownerOf(resource.type, resource.id));
105
+ if (ownerUserId === actor.userId) {
106
+ return { allowed: true, reason: 'owner' };
107
+ }
108
+ if (ownerUserId === null) {
109
+ return { allowed: false, reason: 'resource-not-found' };
110
+ }
111
+ const grants = await effectiveGrantsFor(actor.userId, resource.type, resource.id);
112
+ const qualifying = grants.find(grant => permissionSatisfies(grant.permission, action));
113
+ if (qualifying) {
114
+ return {
115
+ allowed: true,
116
+ reason: qualifying.principal_type === 'user' ? 'direct-grant' : 'group-grant',
117
+ };
118
+ }
119
+ return {
120
+ allowed: false,
121
+ reason: grants.length > 0 ? 'insufficient-permission' : 'no-grant',
122
+ };
123
+ };
124
+ /** Throwing variant for route and service guards. */
125
+ export const requireAuthorized = async (actor, action, resource) => {
126
+ const decision = await authorize(actor, action, resource);
127
+ if (!decision.allowed)
128
+ throw new AuthorizationError();
129
+ return decision;
130
+ };
131
+ /**
132
+ * "Why can this user access this?" — the complete effective-access picture
133
+ * for one user: role, groups, feature gates, and every grant that reaches
134
+ * them directly or through a group.
135
+ */
136
+ export const explainEffectiveAccess = async (user) => {
137
+ const actor = {
138
+ userId: user.id,
139
+ role: user.role,
140
+ status: user.status,
141
+ };
142
+ const groups = await security().groups.listGroupsForUser(user.id);
143
+ const [work, modelDownload, webSearch, agents] = await Promise.all([
144
+ authorize(actor, 'use', { type: 'feature', id: 'work' }),
145
+ authorize(actor, 'use', { type: 'feature', id: 'model-download' }),
146
+ authorize(actor, 'use', { type: 'feature', id: 'web-search' }),
147
+ authorize(actor, 'use', { type: 'feature', id: 'agents' }),
148
+ ]);
149
+ const grantRows = [
150
+ ...(await security().grants.listForPrincipal('user', user.id)),
151
+ ];
152
+ for (const group of groups) {
153
+ grantRows.push(...(await security().grants.listForPrincipal('group', group.id)));
154
+ }
155
+ return {
156
+ userId: user.id,
157
+ role: user.role ?? null,
158
+ status: user.status ?? null,
159
+ groups: groups.map(group => ({ id: group.id, name: group.name })),
160
+ features: {
161
+ work: work.allowed,
162
+ 'model-download': modelDownload.allowed,
163
+ 'web-search': webSearch.allowed,
164
+ agents: agents.allowed,
165
+ },
166
+ grants: grantRows.map(grant => ({
167
+ id: grant.id,
168
+ resourceType: grant.resource_type,
169
+ resourceId: grant.resource_id,
170
+ permission: grant.permission,
171
+ via: grant.principal_type,
172
+ principalId: grant.principal_id,
173
+ })),
174
+ };
175
+ };
176
+ //# sourceMappingURL=authorizationService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorizationService.js","sourceRoot":"","sources":["../../src/services/authorizationService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAMzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAS/D,MAAM,CAAC,MAAM,wBAAwB,GAAqC;IACxE,SAAS;IACT,gBAAgB;IAChB,MAAM;IACN,sBAAsB;IACtB,UAAU;IACV,SAAS;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,KAAc,EACkB,EAAE,CAClC,OAAO,KAAK,KAAK,QAAQ;IACxB,wBAA8C,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAiBlE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAE3C,YAAY,OAAO,GAAG,eAAe;QACnC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,eAAU,GAAG,GAAG,CAAC;QAGxB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC;AAE/E,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,cAAc,CAAC,iBAAiB,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC;AAEnE,sEAAsE;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAc,EAAqB,EAAE,CAC1E,QAAQ,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,mBAAmB,GAAG,CAC1B,OAAwB,EACxB,MAAmB,EACV,EAAE;IACX,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,OAAO,CAAC;IAC1E,OAAO,OAAO,KAAK,OAAO,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAC3B,KAAiB,EACjB,SAAoB,EACI,EAAE;IAC1B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAC3E,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,CAAC,MAAM,iBAAiB,EAAE,CAAC,KAAK,WAAW;gBAChD,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,2BAA2B,EAAE;gBACxD,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;QACjE,KAAK,gBAAgB;YACnB,OAAO,CAAC,MAAM,oBAAoB,EAAE,CAAC,KAAK,WAAW;gBACnD,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,2BAA2B,EAAE;gBACxD,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;QACjE,KAAK,YAAY;YACf,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,KAAK,WAAW;gBACrD,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,2BAA2B,EAAE;gBACxD,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;QACjE,KAAK,QAAQ;YACX,OAAO,CAAC,MAAM,gBAAgB,EAAE,CAAC;gBAC/B,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE;gBAC9C,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACvD,CAAC;AACH,CAAC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,MAAc,EACd,YAAmC,EACnC,UAAkB,EACoB,EAAE;IACxC,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC,aAAa,CACpC,YAAY,EACZ,UAAU,EACV,MAAM,EACN,QAAQ,CACT,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,KAAiB,EACjB,MAAmB,EACnB,QAAuB,EACC,EAAE;IAC1B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC5D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACxD,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,WAAW,GACf,QAAQ,CAAC,WAAW;QACpB,CAAC,MAAM,OAAO,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,IAAI,WAAW,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IACD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,KAAK,CAAC,MAAM,EACZ,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,EAAE,CACZ,CAAC;IACF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACrC,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAC9C,CAAC;IACF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EACJ,UAAU,CAAC,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;SACxE,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,UAAU;KACnE,CAAC;AACJ,CAAC,CAAC;AAEF,qDAAqD;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,KAAiB,EACjB,MAAmB,EACnB,QAAuB,EACC,EAAE;IAC1B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,CAAC,OAAO;QAAE,MAAM,IAAI,kBAAkB,EAAE,CAAC;IACtD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAkBF;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,IAI5C,EAAgC,EAAE;IACjC,MAAM,KAAK,GAAe;QACxB,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,QAAQ,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;QACxD,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC;QAClE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC;QAC9D,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;KAC3D,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG;QAChB,GAAG,CAAC,MAAM,QAAQ,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;KAC/D,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,SAAS,CAAC,IAAI,CACZ,GAAG,CAAC,MAAM,QAAQ,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CACjE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;QAC3B,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACjE,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,gBAAgB,EAAE,aAAa,CAAC,OAAO;YACvC,YAAY,EAAE,SAAS,CAAC,OAAO;YAC/B,MAAM,EAAE,MAAM,CAAC,OAAO;SACvB;QACD,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,YAAY,EAAE,KAAK,CAAC,aAAa;YACjC,UAAU,EAAE,KAAK,CAAC,WAAW;YAC7B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,EAAE,KAAK,CAAC,cAAc;YACzB,WAAW,EAAE,KAAK,CAAC,YAAY;SAChC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { StoredGroupMemberRecord, StoredGroupRecord } from '../persistence/index.js';
2
+ export declare class GroupError extends Error {
3
+ readonly statusCode: number;
4
+ constructor(message: string, statusCode: number);
5
+ }
6
+ export interface GroupWithMembers extends StoredGroupRecord {
7
+ members: StoredGroupMemberRecord[];
8
+ }
9
+ export declare const listGroups: () => Promise<StoredGroupRecord[]>;
10
+ export declare const listGroupsWithMembers: () => Promise<GroupWithMembers[]>;
11
+ export declare const getGroup: (groupId: string) => Promise<StoredGroupRecord | null>;
12
+ export declare const getGroupByName: (name: string) => Promise<StoredGroupRecord | null>;
13
+ export declare const listGroupsForUser: (userId: string) => Promise<StoredGroupRecord[]>;
14
+ export declare const createGroup: (input: {
15
+ name: string;
16
+ description?: string | null;
17
+ }, actorUserId: string) => Promise<StoredGroupRecord>;
18
+ export declare const updateGroup: (groupId: string, patch: {
19
+ name?: string;
20
+ description?: string | null;
21
+ }, actorUserId: string) => Promise<StoredGroupRecord | null>;
22
+ export declare const deleteGroup: (groupId: string, actorUserId: string) => Promise<boolean>;
23
+ export declare const addGroupMember: (groupId: string, userId: string, actorUserId: string) => Promise<boolean>;
24
+ export declare const removeGroupMember: (groupId: string, userId: string, actorUserId: string) => Promise<boolean>;
25
+ /** Deletion hygiene: strip a retiring user from groups and their grants. */
26
+ export declare const removeUserFromSecurityPrincipals: (userId: string) => Promise<void>;
27
+ //# sourceMappingURL=groupService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groupService.d.ts","sourceRoot":"","sources":["../../src/services/groupService.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAKjC,qBAAa,UAAW,SAAQ,KAAK;IAGjC,QAAQ,CAAC,UAAU,EAAE,MAAM;IAF7B,YACE,OAAO,EAAE,MAAM,EACN,UAAU,EAAE,MAAM,EAI5B;CACF;AAiBD,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,OAAO,EAAE,uBAAuB,EAAE,CAAC;CACpC;AAED,eAAO,MAAM,UAAU,QAAO,OAAO,CAAC,iBAAiB,EAAE,CAC/B,CAAC;AAE3B,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,gBAAgB,EAAE,CAQxE,CAAC;AAEF,eAAO,MAAM,QAAQ,YAAa,MAAM,KAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CACtC,CAAC;AAEtC,eAAO,MAAM,cAAc,SACnB,MAAM,KACX,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAuC,CAAC;AAE3E,eAAO,MAAM,iBAAiB,WACpB,MAAM,KACb,OAAO,CAAC,iBAAiB,EAAE,CAAgD,CAAC;AAE/E,eAAO,MAAM,WAAW,UACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,eACvC,MAAM,KAClB,OAAO,CAAC,iBAAiB,CAwC3B,CAAC;AAEF,eAAO,MAAM,WAAW,YACb,MAAM,SACR;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,eACxC,MAAM,KAClB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CA6ClC,CAAC;AAEF,eAAO,MAAM,WAAW,YACb,MAAM,eACF,MAAM,KAClB,OAAO,CAAC,OAAO,CAwBjB,CAAC;AAEF,eAAO,MAAM,cAAc,YAChB,MAAM,UACP,MAAM,eACD,MAAM,KAClB,OAAO,CAAC,OAAO,CAoCjB,CAAC;AAEF,eAAO,MAAM,iBAAiB,YACnB,MAAM,UACP,MAAM,eACD,MAAM,KAClB,OAAO,CAAC,OAAO,CAsBjB,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,gCAAgC,WACnC,MAAM,KACb,OAAO,CAAC,IAAI,CAGd,CAAC"}