@spinajs/authz-fs 0.0.0-stage → 3.0.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 (198) hide show
  1. package/README.md +30 -2
  2. package/lib/cjs/access-config/acl-config.d.ts +23 -0
  3. package/lib/cjs/access-config/acl-config.d.ts.map +1 -0
  4. package/lib/cjs/access-config/acl-config.js +36 -0
  5. package/lib/cjs/access-config/acl-config.js.map +1 -0
  6. package/lib/cjs/access-config/index.d.ts +34 -0
  7. package/lib/cjs/access-config/index.d.ts.map +1 -0
  8. package/lib/cjs/access-config/index.js +89 -0
  9. package/lib/cjs/access-config/index.js.map +1 -0
  10. package/lib/cjs/access-config/schema.d.ts +31 -0
  11. package/lib/cjs/access-config/schema.d.ts.map +1 -0
  12. package/lib/cjs/access-config/schema.js +55 -0
  13. package/lib/cjs/access-config/schema.js.map +1 -0
  14. package/lib/cjs/acl/facade.d.ts +39 -0
  15. package/lib/cjs/acl/facade.d.ts.map +1 -0
  16. package/lib/cjs/acl/facade.js +73 -0
  17. package/lib/cjs/acl/facade.js.map +1 -0
  18. package/lib/cjs/acl/index.d.ts +6 -0
  19. package/lib/cjs/acl/index.d.ts.map +1 -0
  20. package/lib/cjs/acl/index.js +25 -0
  21. package/lib/cjs/acl/index.js.map +1 -0
  22. package/lib/cjs/acl/orm-store.d.ts +31 -0
  23. package/lib/cjs/acl/orm-store.d.ts.map +1 -0
  24. package/lib/cjs/acl/orm-store.js +199 -0
  25. package/lib/cjs/acl/orm-store.js.map +1 -0
  26. package/lib/cjs/acl/relation.d.ts +29 -0
  27. package/lib/cjs/acl/relation.d.ts.map +1 -0
  28. package/lib/cjs/acl/relation.js +60 -0
  29. package/lib/cjs/acl/relation.js.map +1 -0
  30. package/lib/cjs/acl/shared.d.ts +36 -0
  31. package/lib/cjs/acl/shared.d.ts.map +1 -0
  32. package/lib/cjs/acl/shared.js +91 -0
  33. package/lib/cjs/acl/shared.js.map +1 -0
  34. package/lib/cjs/acl/store.d.ts +43 -0
  35. package/lib/cjs/acl/store.d.ts.map +1 -0
  36. package/lib/cjs/acl/store.js +12 -0
  37. package/lib/cjs/acl/store.js.map +1 -0
  38. package/lib/cjs/adapter/index.d.ts +33 -0
  39. package/lib/cjs/adapter/index.d.ts.map +1 -0
  40. package/lib/cjs/adapter/index.js +76 -0
  41. package/lib/cjs/adapter/index.js.map +1 -0
  42. package/lib/cjs/checks.d.ts +5 -0
  43. package/lib/cjs/checks.d.ts.map +1 -0
  44. package/lib/cjs/checks.js +20 -0
  45. package/lib/cjs/checks.js.map +1 -0
  46. package/lib/cjs/http/from-fs-path.d.ts +15 -0
  47. package/lib/cjs/http/from-fs-path.d.ts.map +1 -0
  48. package/lib/cjs/http/from-fs-path.js +43 -0
  49. package/lib/cjs/http/from-fs-path.js.map +1 -0
  50. package/lib/cjs/http/index.d.ts +3 -0
  51. package/lib/cjs/http/index.d.ts.map +1 -0
  52. package/lib/cjs/http/index.js +19 -0
  53. package/lib/cjs/http/index.js.map +1 -0
  54. package/lib/cjs/http/upload.d.ts +29 -0
  55. package/lib/cjs/http/upload.d.ts.map +1 -0
  56. package/lib/cjs/http/upload.js +67 -0
  57. package/lib/cjs/http/upload.js.map +1 -0
  58. package/lib/cjs/index.d.ts +9 -0
  59. package/lib/cjs/index.d.ts.map +1 -0
  60. package/lib/cjs/index.js +25 -0
  61. package/lib/cjs/index.js.map +1 -0
  62. package/lib/cjs/middleware/decide.d.ts +32 -0
  63. package/lib/cjs/middleware/decide.d.ts.map +1 -0
  64. package/lib/cjs/middleware/decide.js +51 -0
  65. package/lib/cjs/middleware/decide.js.map +1 -0
  66. package/lib/cjs/middleware/index.d.ts +53 -0
  67. package/lib/cjs/middleware/index.d.ts.map +1 -0
  68. package/lib/cjs/middleware/index.js +236 -0
  69. package/lib/cjs/middleware/index.js.map +1 -0
  70. package/lib/cjs/middleware/owner.d.ts +10 -0
  71. package/lib/cjs/middleware/owner.d.ts.map +1 -0
  72. package/lib/cjs/middleware/owner.js +20 -0
  73. package/lib/cjs/middleware/owner.js.map +1 -0
  74. package/lib/cjs/middleware/signed-url.d.ts +22 -0
  75. package/lib/cjs/middleware/signed-url.d.ts.map +1 -0
  76. package/lib/cjs/middleware/signed-url.js +36 -0
  77. package/lib/cjs/middleware/signed-url.js.map +1 -0
  78. package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts +8 -0
  79. package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts.map +1 -0
  80. package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js +45 -0
  81. package/lib/cjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js.map +1 -0
  82. package/lib/cjs/migrations/index.d.ts +2 -0
  83. package/lib/cjs/migrations/index.d.ts.map +1 -0
  84. package/lib/cjs/migrations/index.js +18 -0
  85. package/lib/cjs/migrations/index.js.map +1 -0
  86. package/lib/cjs/package.json +1 -0
  87. package/lib/cjs/permissions/index.d.ts +3 -0
  88. package/lib/cjs/permissions/index.d.ts.map +1 -0
  89. package/lib/cjs/permissions/index.js +7 -0
  90. package/lib/cjs/permissions/index.js.map +1 -0
  91. package/lib/cjs/refs/index.d.ts +3 -0
  92. package/lib/cjs/refs/index.d.ts.map +1 -0
  93. package/lib/cjs/refs/index.js +21 -0
  94. package/lib/cjs/refs/index.js.map +1 -0
  95. package/lib/cjs/refs/refs.d.ts +34 -0
  96. package/lib/cjs/refs/refs.d.ts.map +1 -0
  97. package/lib/cjs/refs/refs.js +79 -0
  98. package/lib/cjs/refs/refs.js.map +1 -0
  99. package/lib/mjs/access-config/acl-config.d.ts +23 -0
  100. package/lib/mjs/access-config/acl-config.d.ts.map +1 -0
  101. package/lib/mjs/access-config/acl-config.js +32 -0
  102. package/lib/mjs/access-config/acl-config.js.map +1 -0
  103. package/lib/mjs/access-config/index.d.ts +34 -0
  104. package/lib/mjs/access-config/index.d.ts.map +1 -0
  105. package/lib/mjs/access-config/index.js +71 -0
  106. package/lib/mjs/access-config/index.js.map +1 -0
  107. package/lib/mjs/access-config/schema.d.ts +31 -0
  108. package/lib/mjs/access-config/schema.d.ts.map +1 -0
  109. package/lib/mjs/access-config/schema.js +52 -0
  110. package/lib/mjs/access-config/schema.js.map +1 -0
  111. package/lib/mjs/acl/facade.d.ts +39 -0
  112. package/lib/mjs/acl/facade.d.ts.map +1 -0
  113. package/lib/mjs/acl/facade.js +69 -0
  114. package/lib/mjs/acl/facade.js.map +1 -0
  115. package/lib/mjs/acl/index.d.ts +6 -0
  116. package/lib/mjs/acl/index.d.ts.map +1 -0
  117. package/lib/mjs/acl/index.js +6 -0
  118. package/lib/mjs/acl/index.js.map +1 -0
  119. package/lib/mjs/acl/orm-store.d.ts +31 -0
  120. package/lib/mjs/acl/orm-store.d.ts.map +1 -0
  121. package/lib/mjs/acl/orm-store.js +196 -0
  122. package/lib/mjs/acl/orm-store.js.map +1 -0
  123. package/lib/mjs/acl/relation.d.ts +29 -0
  124. package/lib/mjs/acl/relation.d.ts.map +1 -0
  125. package/lib/mjs/acl/relation.js +56 -0
  126. package/lib/mjs/acl/relation.js.map +1 -0
  127. package/lib/mjs/acl/shared.d.ts +36 -0
  128. package/lib/mjs/acl/shared.d.ts.map +1 -0
  129. package/lib/mjs/acl/shared.js +73 -0
  130. package/lib/mjs/acl/shared.js.map +1 -0
  131. package/lib/mjs/acl/store.d.ts +43 -0
  132. package/lib/mjs/acl/store.d.ts.map +1 -0
  133. package/lib/mjs/acl/store.js +8 -0
  134. package/lib/mjs/acl/store.js.map +1 -0
  135. package/lib/mjs/adapter/index.d.ts +33 -0
  136. package/lib/mjs/adapter/index.d.ts.map +1 -0
  137. package/lib/mjs/adapter/index.js +73 -0
  138. package/lib/mjs/adapter/index.js.map +1 -0
  139. package/lib/mjs/checks.d.ts +5 -0
  140. package/lib/mjs/checks.d.ts.map +1 -0
  141. package/lib/mjs/checks.js +16 -0
  142. package/lib/mjs/checks.js.map +1 -0
  143. package/lib/mjs/http/from-fs-path.d.ts +15 -0
  144. package/lib/mjs/http/from-fs-path.d.ts.map +1 -0
  145. package/lib/mjs/http/from-fs-path.js +40 -0
  146. package/lib/mjs/http/from-fs-path.js.map +1 -0
  147. package/lib/mjs/http/index.d.ts +3 -0
  148. package/lib/mjs/http/index.d.ts.map +1 -0
  149. package/lib/mjs/http/index.js +3 -0
  150. package/lib/mjs/http/index.js.map +1 -0
  151. package/lib/mjs/http/upload.d.ts +29 -0
  152. package/lib/mjs/http/upload.d.ts.map +1 -0
  153. package/lib/mjs/http/upload.js +64 -0
  154. package/lib/mjs/http/upload.js.map +1 -0
  155. package/lib/mjs/index.d.ts +9 -0
  156. package/lib/mjs/index.d.ts.map +1 -0
  157. package/lib/mjs/index.js +9 -0
  158. package/lib/mjs/index.js.map +1 -0
  159. package/lib/mjs/middleware/decide.d.ts +32 -0
  160. package/lib/mjs/middleware/decide.d.ts.map +1 -0
  161. package/lib/mjs/middleware/decide.js +42 -0
  162. package/lib/mjs/middleware/decide.js.map +1 -0
  163. package/lib/mjs/middleware/index.d.ts +53 -0
  164. package/lib/mjs/middleware/index.d.ts.map +1 -0
  165. package/lib/mjs/middleware/index.js +231 -0
  166. package/lib/mjs/middleware/index.js.map +1 -0
  167. package/lib/mjs/middleware/owner.d.ts +10 -0
  168. package/lib/mjs/middleware/owner.d.ts.map +1 -0
  169. package/lib/mjs/middleware/owner.js +16 -0
  170. package/lib/mjs/middleware/owner.js.map +1 -0
  171. package/lib/mjs/middleware/signed-url.d.ts +22 -0
  172. package/lib/mjs/middleware/signed-url.d.ts.map +1 -0
  173. package/lib/mjs/middleware/signed-url.js +31 -0
  174. package/lib/mjs/middleware/signed-url.js.map +1 -0
  175. package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts +8 -0
  176. package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.d.ts.map +1 -0
  177. package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js +42 -0
  178. package/lib/mjs/migrations/AuthzFsAcl_2026_10_17_00_00_00.js.map +1 -0
  179. package/lib/mjs/migrations/index.d.ts +2 -0
  180. package/lib/mjs/migrations/index.d.ts.map +1 -0
  181. package/lib/mjs/migrations/index.js +2 -0
  182. package/lib/mjs/migrations/index.js.map +1 -0
  183. package/lib/mjs/package.json +1 -0
  184. package/lib/mjs/permissions/index.d.ts +3 -0
  185. package/lib/mjs/permissions/index.d.ts.map +1 -0
  186. package/lib/mjs/permissions/index.js +4 -0
  187. package/lib/mjs/permissions/index.js.map +1 -0
  188. package/lib/mjs/refs/index.d.ts +3 -0
  189. package/lib/mjs/refs/index.d.ts.map +1 -0
  190. package/lib/mjs/refs/index.js +3 -0
  191. package/lib/mjs/refs/index.js.map +1 -0
  192. package/lib/mjs/refs/refs.d.ts +34 -0
  193. package/lib/mjs/refs/refs.d.ts.map +1 -0
  194. package/lib/mjs/refs/refs.js +71 -0
  195. package/lib/mjs/refs/refs.js.map +1 -0
  196. package/lib/tsconfig.cjs.tsbuildinfo +1 -0
  197. package/lib/tsconfig.mjs.tsbuildinfo +1 -0
  198. package/package.json +74 -4
package/README.md CHANGED
@@ -1,3 +1,31 @@
1
- # Temporary Holding Version
1
+ # `@spinajs/authz-fs`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Checks every file action of `@spinajs/fs` providers with `@spinajs/authz` (`AuthzFsMiddleware`) and keeps per-file
4
+ rights in the ORM table `fs_acl`.
5
+
6
+ ## Documentation
7
+
8
+ - [Package overview](../../docs/authz-fs/README.md)
9
+ - [Access modes and configuration](../../docs/authz-fs/01-access-modes-and-configuration.md)
10
+ - [Checks on file actions](../../docs/authz-fs/02-checks-on-file-actions.md)
11
+ - [File ACL](../../docs/authz-fs/03-file-acl.md)
12
+ - [Relation grants](../../docs/authz-fs/04-relation-grants.md)
13
+ - [Managing ACL rows](../../docs/authz-fs/05-managing-acl-rows.md)
14
+ - [Uploads and routes](../../docs/authz-fs/06-uploads-and-routes.md)
15
+ - [ACL store](../../docs/authz-fs/07-acl-store.md)
16
+
17
+ ## Tests
18
+
19
+ `npm run test` runs the behaviour fixture B28 once per provider kind, in suites titled `local` (fsNative), `temp`
20
+ (fsTemp over fsNative) and `s3` (fsS3). The `s3` suites need localstack at `AUTHZ_FS_S3_ENDPOINT` (default
21
+ `http://localhost:4566`):
22
+
23
+ ```sh
24
+ docker run --rm -d -p 4566:4566 -e SERVICES=s3 localstack/localstack
25
+ ```
26
+
27
+ Without it they are skipped with a message. Set `AUTHZ_FS_S3=required` (release gate item 4: run
28
+ `AUTHZ_FS_S3=required npm test` in `packages/authz-fs` against localstack, a manual release step) to make an
29
+ unreachable localstack fail them instead. Cases that cannot hold on S3 for a provider reason are listed, with the
30
+ reason, as pending tests (`test/support/on-s3.ts`). The ORM store suite runs on SQLite, and on Postgres and MySQL with
31
+ `AUTHZ_FS_DB=postgres,mysql` and the orm packages' test containers.
@@ -0,0 +1,23 @@
1
+ import type { IContainer } from '@spinajs/di';
2
+ export declare const FS_ACL_CONNECTION_KEY = "authz.fsAcl.connection";
3
+ export declare const FS_ACL_DEFAULT_CONNECTION = "default";
4
+ /** The relation of the row owner stamping writes. */
5
+ export declare const FS_ACL_OWNER = "owner";
6
+ export declare const FS_ACL_DEFAULT_RELATIONS: readonly string[];
7
+ /** fs_acl.relation holds this many characters. */
8
+ export declare const FS_ACL_RELATION_MAX_LENGTH = 64;
9
+ /** `authz.fsAcl` (fs middleware design §2). */
10
+ export interface FsAclConfig {
11
+ /** ORM connection of OrmFileAclStore and of its migration. */
12
+ readonly connection: string;
13
+ /** The relations an ACL row may name; FsResourceAdapter serves a RelationResolver for each on fs, dir and file. */
14
+ readonly relations: readonly string[];
15
+ }
16
+ /**
17
+ * `authz.fsAcl` of the Configuration in `container`, defaults filled; without a Configuration the defaults (the
18
+ * migration reads the connection before any is resolved). `owner` is always among the relations, first: owner
19
+ * stamping writes it whatever the config lists.
20
+ * @throws AuthzConfigError for a malformed value no schema checked
21
+ */
22
+ export declare function fsAclConfig(container?: IContainer): FsAclConfig;
23
+ //# sourceMappingURL=acl-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl-config.d.ts","sourceRoot":"","sources":["../../../src/access-config/acl-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAC9D,eAAO,MAAM,yBAAyB,YAAY,CAAC;AACnD,qDAAqD;AACrD,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAAsD,CAAC;AAC7G,kDAAkD;AAClD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mHAAmH;IACnH,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,GAAE,UAA6B,GAAG,WAAW,CAUjF"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FS_ACL_RELATION_MAX_LENGTH = exports.FS_ACL_DEFAULT_RELATIONS = exports.FS_ACL_OWNER = exports.FS_ACL_DEFAULT_CONNECTION = exports.FS_ACL_CONNECTION_KEY = void 0;
4
+ exports.fsAclConfig = fsAclConfig;
5
+ const authz_1 = require("@spinajs/authz");
6
+ const configuration_1 = require("@spinajs/configuration");
7
+ const di_1 = require("@spinajs/di");
8
+ const util_1 = require("@spinajs/util");
9
+ const checks_js_1 = require("../checks.js");
10
+ // Not under authz.fs: that section is keyed by filesystem name.
11
+ exports.FS_ACL_CONNECTION_KEY = 'authz.fsAcl.connection';
12
+ exports.FS_ACL_DEFAULT_CONNECTION = 'default';
13
+ /** The relation of the row owner stamping writes. */
14
+ exports.FS_ACL_OWNER = 'owner';
15
+ exports.FS_ACL_DEFAULT_RELATIONS = Object.freeze([exports.FS_ACL_OWNER, 'editor', 'viewer']);
16
+ /** fs_acl.relation holds this many characters. */
17
+ exports.FS_ACL_RELATION_MAX_LENGTH = 64;
18
+ /**
19
+ * `authz.fsAcl` of the Configuration in `container`, defaults filled; without a Configuration the defaults (the
20
+ * migration reads the connection before any is resolved). `owner` is always among the relations, first: owner
21
+ * stamping writes it whatever the config lists.
22
+ * @throws AuthzConfigError for a malformed value no schema checked
23
+ */
24
+ function fsAclConfig(container = di_1.DI.RootContainer) {
25
+ const configuration = container.get(configuration_1.Configuration);
26
+ const read = (key) => (configuration && typeof configuration.get === 'function' ? configuration.get(['authz', 'fsAcl', key]) : undefined);
27
+ const connection = read('connection') ?? exports.FS_ACL_DEFAULT_CONNECTION;
28
+ if (typeof connection !== 'string' || connection === '')
29
+ throw new authz_1.AuthzConfigError(`${exports.FS_ACL_CONNECTION_KEY} must be a non-empty string, got ${(0, checks_js_1.show)(connection)}`);
30
+ const relations = read('relations') ?? exports.FS_ACL_DEFAULT_RELATIONS;
31
+ if (!(0, util_1.isStringArray)(relations, { nonEmpty: true }) || !relations.every((r) => r.length <= exports.FS_ACL_RELATION_MAX_LENGTH)) {
32
+ throw new authz_1.AuthzConfigError(`authz.fsAcl.relations must be a list of relation names of 1-${exports.FS_ACL_RELATION_MAX_LENGTH} characters, got ${(0, checks_js_1.show)(relations)}`);
33
+ }
34
+ return Object.freeze({ connection, relations: Object.freeze([...new Set([exports.FS_ACL_OWNER, ...relations])]) });
35
+ }
36
+ //# sourceMappingURL=acl-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl-config.js","sourceRoot":"","sources":["../../../src/access-config/acl-config.ts"],"names":[],"mappings":";;;;AAAA,0CAAkD;AAClD,0DAAuD;AACvD,oCAAiC;AAEjC,wCAA8C;AAE9C,4CAAoC;AAEpC,gEAAgE;AACnD,QAAA,qBAAqB,GAAG,wBAAwB,CAAC;AACjD,QAAA,yBAAyB,GAAG,SAAS,CAAC;AACnD,qDAAqD;AACxC,QAAA,YAAY,GAAG,OAAO,CAAC;AACvB,QAAA,wBAAwB,GAAsB,MAAM,CAAC,MAAM,CAAC,CAAC,QAAA,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC7G,kDAAkD;AACrC,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAU7C;;;;;GAKG;AACH,qBAA4B,SAAS,GAAe,OAAE,CAAC,aAAa;IAClE,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,6BAAa,CAA8B,CAAC;IAChF,MAAM,IAAI,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,CAAC,aAAa,IAAI,OAAO,aAAa,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpK,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,QAAA,yBAAyB,CAAC;IACnE,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,EAAE;QAAE,MAAM,IAAI,wBAAgB,CAAC,GAAG,QAAA,qBAAqB,oCAAoC,IAAA,gBAAI,EAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACpK,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,QAAA,wBAAwB,CAAC;IAChE,IAAI,CAAC,IAAA,oBAAa,EAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,QAAA,0BAA0B,CAAC,EAAE,CAAC;QACrH,MAAM,IAAI,wBAAgB,CAAC,+DAA+D,QAAA,0BAA0B,oBAAoB,IAAA,gBAAI,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7J,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,QAAA,YAAY,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7G,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { IContainer } from '@spinajs/di';
2
+ export * from './schema.js';
3
+ export * from './acl-config.js';
4
+ export type FsAccessMode = 'off' | 'audit' | 'enforce';
5
+ /** `authz.fs.<name>.signedUrl` (D9). */
6
+ export interface FsSignedUrlConfig {
7
+ /** Cap on every signed URL's lifetime. */
8
+ readonly maxTtlSeconds?: number;
9
+ /** Lifetime when the caller asks for no `until`; default 900 (the S3 signer's own default). */
10
+ readonly defaultTtlSeconds?: number;
11
+ }
12
+ /** `authz.fs.<name>` (fs middleware design §2). */
13
+ export interface FsAccessConfig {
14
+ readonly mode: FsAccessMode;
15
+ /** Authz domain the checks run in; default 'root'. Another domain must exist: authz-fs never creates one. */
16
+ readonly domain: string;
17
+ /** Record the first writer of a path an action creates as its `owner` ACL row. */
18
+ readonly stampOwner?: boolean;
19
+ readonly list?: 'dir' | 'each';
20
+ readonly signedUrl?: FsSignedUrlConfig;
21
+ }
22
+ /**
23
+ * `authz.fs.<fsName>` of the Configuration resolved in `container`, read on every call. A filesystem without an
24
+ * entry is off.
25
+ */
26
+ export declare function fsAccessConfig(fsName: string, container?: IContainer): FsAccessConfig;
27
+ /**
28
+ * One `authz.fs.<fsName>` entry; undefined is a missing entry (off). AUTHZ_FS_CONFIGURATION_SCHEMA checks the entry
29
+ * at boot; it may also come from a Configuration no schema checked, so every value is checked here too.
30
+ * @throws AuthzConfigError for a malformed value or an unknown key: a removed key such as `policies` must not be
31
+ * dropped silently, since a dropped deny policy would open files
32
+ */
33
+ export declare function parseFsAccessConfig(fsName: string, entry: unknown): FsAccessConfig;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/access-config/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAEhC,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvD,wCAAwC;AACxC,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,+FAA+F;IAC/F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;CACxC;AAOD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,UAA6B,GAAG,cAAc,CAGvG;AAcD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,cAAc,CAalF"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.fsAccessConfig = fsAccessConfig;
18
+ exports.parseFsAccessConfig = parseFsAccessConfig;
19
+ const authz_1 = require("@spinajs/authz");
20
+ const configuration_1 = require("@spinajs/configuration");
21
+ const di_1 = require("@spinajs/di");
22
+ const util_1 = require("@spinajs/util");
23
+ const checks_js_1 = require("../checks.js");
24
+ __exportStar(require("./schema.js"), exports);
25
+ __exportStar(require("./acl-config.js"), exports);
26
+ const MODES = ['off', 'audit', 'enforce'];
27
+ const KEYS = new Set(['mode', 'domain', 'stampOwner', 'list', 'signedUrl']);
28
+ const OFF = Object.freeze({ mode: 'off', domain: 'root' });
29
+ /**
30
+ * `authz.fs.<fsName>` of the Configuration resolved in `container`, read on every call. A filesystem without an
31
+ * entry is off.
32
+ */
33
+ function fsAccessConfig(fsName, container = di_1.DI.RootContainer) {
34
+ const all = fsSection(container);
35
+ return all ? parseFsAccessConfig(fsName, Object.hasOwn(all, fsName) ? all[fsName] : undefined) : OFF;
36
+ }
37
+ function fsSection(container) {
38
+ const configuration = container.get(configuration_1.Configuration);
39
+ if (!configuration || typeof configuration.get !== 'function') {
40
+ throw new authz_1.AuthzConfigError('authz.fs: Configuration is not resolved; await DI.resolve(Configuration) first');
41
+ }
42
+ const all = configuration.get(['authz', 'fs']);
43
+ if (all === undefined || all === null)
44
+ return undefined;
45
+ // Fail-closed floor for a section no schema checked (Configuration.set, test configurations): it would read as every filesystem off.
46
+ if (!(0, util_1.isPlainObject)(all))
47
+ throw new authz_1.AuthzConfigError(`authz.fs must be an object keyed by filesystem name, got ${(0, checks_js_1.show)(all)}`);
48
+ return all;
49
+ }
50
+ /**
51
+ * One `authz.fs.<fsName>` entry; undefined is a missing entry (off). AUTHZ_FS_CONFIGURATION_SCHEMA checks the entry
52
+ * at boot; it may also come from a Configuration no schema checked, so every value is checked here too.
53
+ * @throws AuthzConfigError for a malformed value or an unknown key: a removed key such as `policies` must not be
54
+ * dropped silently, since a dropped deny policy would open files
55
+ */
56
+ function parseFsAccessConfig(fsName, entry) {
57
+ if (entry === undefined)
58
+ return OFF;
59
+ const at = `authz.fs.${fsName}`;
60
+ const mode = (0, util_1.isPlainObject)(entry) ? entry.mode : undefined;
61
+ if (!MODES.includes(mode))
62
+ throw new authz_1.AuthzConfigError(`${at}.mode must be one of ${MODES.join(', ')}, got ${(0, checks_js_1.show)((0, util_1.isPlainObject)(entry) ? mode : entry)}`);
63
+ const e = entry;
64
+ for (const key of Object.keys(e))
65
+ if (!KEYS.has(key))
66
+ throw new authz_1.AuthzConfigError(`${at}.${key} is not an authz.fs option (${[...KEYS].join(', ')})`);
67
+ if (e.domain !== undefined && (typeof e.domain !== 'string' || e.domain === ''))
68
+ throw new authz_1.AuthzConfigError(`${at}.domain must be a non-empty string, got ${(0, checks_js_1.show)(e.domain)}`);
69
+ if (e.stampOwner !== undefined && typeof e.stampOwner !== 'boolean')
70
+ throw new authz_1.AuthzConfigError(`${at}.stampOwner must be a boolean, got ${(0, checks_js_1.show)(e.stampOwner)}`);
71
+ if (e.list !== undefined && e.list !== 'dir' && e.list !== 'each')
72
+ throw new authz_1.AuthzConfigError(`${at}.list must be 'dir' or 'each', got ${(0, checks_js_1.show)(e.list)}`);
73
+ const out = { ...e, domain: e.domain ?? 'root' };
74
+ if (e.signedUrl !== undefined)
75
+ out.signedUrl = signedUrlOf(e.signedUrl, `${at}.signedUrl`);
76
+ return Object.freeze(out);
77
+ }
78
+ function signedUrlOf(value, at) {
79
+ if (!(0, util_1.isPlainObject)(value))
80
+ throw new authz_1.AuthzConfigError(`${at} must be an object, got ${(0, checks_js_1.show)(value)}`);
81
+ for (const [key, ttl] of Object.entries(value)) {
82
+ if (key !== 'maxTtlSeconds' && key !== 'defaultTtlSeconds')
83
+ throw new authz_1.AuthzConfigError(`${at}.${key} is not a signedUrl option`);
84
+ if (typeof ttl !== 'number' || !Number.isFinite(ttl) || ttl <= 0)
85
+ throw new authz_1.AuthzConfigError(`${at}.${key} must be a positive finite number, got ${(0, checks_js_1.show)(ttl)}`);
86
+ }
87
+ return Object.freeze({ ...value });
88
+ }
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/access-config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { Bootstrapper } from '@spinajs/di';
2
+ /** `authz.fs.<filesystem>`: one entry per filesystem name; a filesystem without one is off. */
3
+ export declare const AUTHZ_FS_CONFIGURATION_SCHEMA: {
4
+ $id: string;
5
+ $configurationModule: string;
6
+ description: string;
7
+ type: string;
8
+ additionalProperties: {
9
+ type: string;
10
+ properties: Record<string, unknown>;
11
+ propertyNames: {
12
+ enum: string[];
13
+ };
14
+ required?: string[] | undefined;
15
+ };
16
+ };
17
+ export declare const AUTHZ_FS_ACL_CONFIGURATION_SCHEMA: {
18
+ type: string;
19
+ properties: Record<string, unknown>;
20
+ propertyNames: {
21
+ enum: string[];
22
+ };
23
+ required?: string[] | undefined;
24
+ $id: string;
25
+ $configurationModule: string;
26
+ description: string;
27
+ };
28
+ export declare class AuthzFsConfigBootstrapper extends Bootstrapper {
29
+ bootstrap(): void;
30
+ }
31
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/access-config/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;AAqBvD,+FAA+F;AAC/F,eAAO,MAAM,6BAA6B;IACxC,GAAG;IACH,oBAAoB;IACpB,WAAW;IACX,IAAI;IACJ,oBAAoB;;;;YApBuG,IAAI;;;;CAqBhI,CAAC;AAEF,eAAO,MAAM,iCAAiC;;;;QAvB+E,IAAI;;;;;;CAgChI,CAAC;AAKF,qBACa,yBAA0B,SAAQ,YAAY;IAClD,SAAS,IAAI,IAAI,CAGvB;CACF"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AuthzFsConfigBootstrapper = exports.AUTHZ_FS_ACL_CONFIGURATION_SCHEMA = exports.AUTHZ_FS_CONFIGURATION_SCHEMA = void 0;
10
+ const configuration_1 = require("@spinajs/configuration");
11
+ const di_1 = require("@spinajs/di");
12
+ const acl_config_js_1 = require("./acl-config.js");
13
+ const name = { type: 'string', minLength: 1 };
14
+ // propertyNames refuses an unknown key; additionalProperties: false would let removeAdditional drop a typo silently.
15
+ const closed = (properties, required) => ({ type: 'object', properties, propertyNames: { enum: Object.keys(properties) }, ...(required ? { required } : {}) });
16
+ const entry = closed({
17
+ mode: { type: 'string', enum: ['off', 'audit', 'enforce'] },
18
+ domain: name,
19
+ stampOwner: { type: 'boolean' },
20
+ signedUrl: closed({ maxTtlSeconds: { type: 'number', exclusiveMinimum: 0 }, defaultTtlSeconds: { type: 'number', exclusiveMinimum: 0 } }),
21
+ list: { type: 'string', enum: ['dir', 'each'] },
22
+ },
23
+ // A present entry says its mode: an entry with other keys but no mode must not be silently off.
24
+ ['mode']);
25
+ /** `authz.fs.<filesystem>`: one entry per filesystem name; a filesystem without one is off. */
26
+ exports.AUTHZ_FS_CONFIGURATION_SCHEMA = {
27
+ $id: 'spinajs/authz-fs.configuration.schema.json',
28
+ $configurationModule: 'authz.fs',
29
+ description: 'Filesystem access configuration (authz.fs.<filesystem>)',
30
+ type: 'object',
31
+ additionalProperties: entry,
32
+ };
33
+ exports.AUTHZ_FS_ACL_CONFIGURATION_SCHEMA = {
34
+ $id: 'spinajs/authz-fs-acl.configuration.schema.json',
35
+ // Not under authz.fs: that section is keyed by filesystem name.
36
+ $configurationModule: 'authz.fsAcl',
37
+ description: 'File ACL configuration (authz.fsAcl.*)',
38
+ ...closed({
39
+ connection: { ...name, default: acl_config_js_1.FS_ACL_DEFAULT_CONNECTION },
40
+ relations: { type: 'array', uniqueItems: true, items: { type: 'string', minLength: 1, maxLength: acl_config_js_1.FS_ACL_RELATION_MAX_LENGTH }, default: [...acl_config_js_1.FS_ACL_DEFAULT_RELATIONS] },
41
+ }),
42
+ };
43
+ (0, configuration_1.registerConfigurationSchemaAtImport)(exports.AUTHZ_FS_CONFIGURATION_SCHEMA);
44
+ (0, configuration_1.registerConfigurationSchemaAtImport)(exports.AUTHZ_FS_ACL_CONFIGURATION_SCHEMA);
45
+ let AuthzFsConfigBootstrapper = class AuthzFsConfigBootstrapper extends di_1.Bootstrapper {
46
+ bootstrap() {
47
+ (0, configuration_1.registerConfigurationSchema)(exports.AUTHZ_FS_CONFIGURATION_SCHEMA);
48
+ (0, configuration_1.registerConfigurationSchema)(exports.AUTHZ_FS_ACL_CONFIGURATION_SCHEMA);
49
+ }
50
+ };
51
+ exports.AuthzFsConfigBootstrapper = AuthzFsConfigBootstrapper;
52
+ exports.AuthzFsConfigBootstrapper = AuthzFsConfigBootstrapper = __decorate([
53
+ (0, di_1.Injectable)(di_1.Bootstrapper)
54
+ ], AuthzFsConfigBootstrapper);
55
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/access-config/schema.ts"],"names":[],"mappings":";;;;;;;;;AAAA,0DAA0G;AAC1G,oCAAuD;AAEvD,mDAAkH;AAElH,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAE9C,qHAAqH;AACrH,MAAM,MAAM,GAAG,CAAC,UAAmC,EAAE,QAAmB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAEnM,MAAM,KAAK,GAAG,MAAM,CAClB;IACE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE;IAC3D,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC/B,SAAS,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,EAAE,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC;IACzI,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;CAChD;AACD,gGAAgG;AAChG,CAAC,MAAM,CAAC,CACT,CAAC;AAEF,+FAA+F;AAClF,QAAA,6BAA6B,GAAG;IAC3C,GAAG,EAAE,4CAA4C;IACjD,oBAAoB,EAAE,UAAU;IAChC,WAAW,EAAE,yDAAyD;IACtE,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAEW,QAAA,iCAAiC,GAAG;IAC/C,GAAG,EAAE,gDAAgD;IACrD,gEAAgE;IAChE,oBAAoB,EAAE,aAAa;IACnC,WAAW,EAAE,wCAAwC;IACrD,GAAG,MAAM,CAAC;QACR,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,yCAAyB,EAAE;QAC3D,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,0CAA0B,EAAE,EAAE,OAAO,EAAE,CAAC,GAAG,wCAAwB,CAAC,EAAE;KACxK,CAAC;CACH,CAAC;AAEF,IAAA,mDAAmC,EAAC,QAAA,6BAA6B,CAAC,CAAC;AACnE,IAAA,mDAAmC,EAAC,QAAA,iCAAiC,CAAC,CAAC;AAGhE,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,iBAAY;IAClD,SAAS;QACd,IAAA,2CAA2B,EAAC,QAAA,6BAA6B,CAAC,CAAC;QAC3D,IAAA,2CAA2B,EAAC,QAAA,iCAAiC,CAAC,CAAC;IACjE,CAAC;CACF,CAAA;;oCALY,yBAAyB;IADrC,IAAA,eAAU,EAAC,iBAAY,CAAC;GACZ,yBAAyB,CAKrC"}
@@ -0,0 +1,39 @@
1
+ import type { AssignmentSubject, Principal } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ import type { FsDecideService, FsLog } from '../middleware/decide.js';
4
+ import type { FileAclStore, FsAclRow } from './store.js';
5
+ export interface FsAclOptions {
6
+ /** Where the Configuration, the published providers, AuthzService, AuthzDomains and the FileAclStore are resolved; default the root. */
7
+ readonly container?: IContainer;
8
+ /** The service that decides for a domain; default the root AuthzService, else `AuthzDomains.service(domain)`. */
9
+ readonly service?: (domain: string) => Promise<FsDecideService>;
10
+ /** Default: the ALS principal, else UNATTENDED. */
11
+ readonly principal?: () => Principal;
12
+ readonly log?: FsLog;
13
+ readonly store?: () => Promise<FileAclStore>;
14
+ }
15
+ /**
16
+ * Changes the file ACL as the current principal. Every call asserts a definite
17
+ * `fs:manage` on both the file and the dir ref of the path (the fs ref for the root), whatever the filesystem's
18
+ * `authz.fs` mode; only SYSTEM is exempt. The checks run in the domain of `authz.fs.<fs>.domain`, 'root' without an
19
+ * entry. fs:manage lets the holder grant any configured relation, owner included. System code that needs unchecked
20
+ * writes uses the FileAclStore directly. A row granted on a path that does not exist yet is cleared as stale when
21
+ * that path is later created through the middleware.
22
+ */
23
+ export declare class FsAcl {
24
+ protected readonly options: FsAclOptions;
25
+ private logger?;
26
+ constructor(options?: FsAclOptions);
27
+ grant(fs: string, path: string, subject: AssignmentSubject, relation: string, opts?: {
28
+ readonly expiresAt?: Date;
29
+ }): Promise<void>;
30
+ revoke(fs: string, path: string, subject: AssignmentSubject, relation: string): Promise<void>;
31
+ list(fs: string, path: string): Promise<readonly FsAclRow[]>;
32
+ protected get container(): IContainer;
33
+ private get log();
34
+ private principal;
35
+ private store;
36
+ private known;
37
+ private authorize;
38
+ }
39
+ //# sourceMappingURL=facade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../../../src/acl/facade.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAItE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,wIAAwI;IACxI,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC;IAChC,iHAAiH;IACjH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAChE,mDAAmD;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,SAAS,CAAC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9C;AAED;;;;;;;GAOG;AACH,qBAAa,KAAK;IAGJ,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY;IAFpD,OAAO,CAAC,MAAM,CAAC,CAAQ;IAEvB,YAA+B,OAAO,GAAE,YAAiB,EAAI;IAEvD,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3I;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlG;IAEK,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAGjE;IAED,SAAS,KAAK,SAAS,IAAI,UAAU,CAEpC;IAED,OAAO,KAAK,GAAG,GAEd;IAED,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,KAAK;YAKC,SAAS;CAaxB"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FsAcl = void 0;
4
+ const authz_1 = require("@spinajs/authz");
5
+ const di_1 = require("@spinajs/di");
6
+ const fs_1 = require("@spinajs/fs");
7
+ const index_js_1 = require("../access-config/index.js");
8
+ const decide_js_1 = require("../middleware/decide.js");
9
+ const index_js_2 = require("../refs/index.js");
10
+ const shared_js_1 = require("./shared.js");
11
+ /**
12
+ * Changes the file ACL as the current principal. Every call asserts a definite
13
+ * `fs:manage` on both the file and the dir ref of the path (the fs ref for the root), whatever the filesystem's
14
+ * `authz.fs` mode; only SYSTEM is exempt. The checks run in the domain of `authz.fs.<fs>.domain`, 'root' without an
15
+ * entry. fs:manage lets the holder grant any configured relation, owner included. System code that needs unchecked
16
+ * writes uses the FileAclStore directly. A row granted on a path that does not exist yet is cleared as stale when
17
+ * that path is later created through the middleware.
18
+ */
19
+ class FsAcl {
20
+ constructor(options = {}) {
21
+ this.options = options;
22
+ }
23
+ async grant(fs, path, subject, relation, opts = {}) {
24
+ this.known(relation);
25
+ const principal = this.principal();
26
+ const at = await this.authorize(fs, path, principal);
27
+ await (await this.store()).grant({ fs, path: at, subject, relation, grantedBy: (0, authz_1.principalKey)(principal), ...(opts.expiresAt ? { expiresAt: opts.expiresAt } : {}) });
28
+ }
29
+ async revoke(fs, path, subject, relation) {
30
+ this.known(relation);
31
+ const key = (0, shared_js_1.aclSubjectKey)(subject);
32
+ const at = await this.authorize(fs, path, this.principal());
33
+ await (await this.store()).revoke(fs, at, key, relation);
34
+ }
35
+ async list(fs, path) {
36
+ const at = await this.authorize(fs, path, this.principal());
37
+ return (await this.store()).list(fs, at);
38
+ }
39
+ get container() {
40
+ return this.options.container ?? di_1.DI.RootContainer;
41
+ }
42
+ get log() {
43
+ return (this.logger ??= this.options.log ?? (0, authz_1.engineLog)('authz-fs'));
44
+ }
45
+ principal() {
46
+ return (this.options.principal ?? authz_1.currentPrincipal)();
47
+ }
48
+ store() {
49
+ return this.options.store ? this.options.store() : (0, shared_js_1.fileAclStore)(this.container);
50
+ }
51
+ known(relation) {
52
+ const { relations } = (0, index_js_1.fsAclConfig)(this.container);
53
+ if (!relations.includes(relation))
54
+ throw new authz_1.AuthzConfigError(`FsAcl: relation ${JSON.stringify(relation)} is not in authz.fsAcl.relations (${relations.join(', ')})`);
55
+ }
56
+ async authorize(fs, path, principal) {
57
+ const provider = (0, fs_1.publishedFs)(fs, this.container);
58
+ if (!provider)
59
+ throw new authz_1.AuthzConfigError(`FsAcl: filesystem ${JSON.stringify(fs)} has no published provider`);
60
+ const normalised = (0, index_js_2.normalizeFsPath)(path, provider.BasePath);
61
+ if (principal === authz_1.SYSTEM)
62
+ return normalised;
63
+ const { domain } = (0, index_js_1.fsAccessConfig)(fs, this.container);
64
+ const service = await (this.options.service ? this.options.service(domain) : (0, decide_js_1.domainService)(this.container, domain));
65
+ const kinds = normalised === '' ? ['file'] : ['file', 'dir'];
66
+ for (const kind of kinds) {
67
+ await (0, decide_js_1.decideFs)({ fsName: fs, mode: 'enforce', service, log: this.log, principal, permission: 'fs:manage', ref: (0, decide_js_1.refOf)(fs, normalised, kind), subject: (0, index_js_2.fsRowOf)(fs, normalised, kind) });
68
+ }
69
+ return normalised;
70
+ }
71
+ }
72
+ exports.FsAcl = FsAcl;
73
+ //# sourceMappingURL=facade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facade.js","sourceRoot":"","sources":["../../../src/acl/facade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './store.js';
2
+ export * from './orm-store.js';
3
+ export * from './relation.js';
4
+ export * from './facade.js';
5
+ export { FS_ACL_LIMITS, FS_ACL_TABLE } from './shared.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/acl/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.FS_ACL_TABLE = exports.FS_ACL_LIMITS = void 0;
18
+ __exportStar(require("./store.js"), exports);
19
+ __exportStar(require("./orm-store.js"), exports);
20
+ __exportStar(require("./relation.js"), exports);
21
+ __exportStar(require("./facade.js"), exports);
22
+ var shared_js_1 = require("./shared.js");
23
+ Object.defineProperty(exports, "FS_ACL_LIMITS", { enumerable: true, get: function () { return shared_js_1.FS_ACL_LIMITS; } });
24
+ Object.defineProperty(exports, "FS_ACL_TABLE", { enumerable: true, get: function () { return shared_js_1.FS_ACL_TABLE; } });
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/acl/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,iDAA+B;AAC/B,gDAA8B;AAC9B,8CAA4B;AAC5B,yCAA0D;AAAjD,0GAAA,aAAa,OAAA;AAAE,yGAAA,YAAY,OAAA"}
@@ -0,0 +1,31 @@
1
+ import type { PrincipalRef } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ import { FileAclStore } from './store.js';
4
+ import type { FsAclRow } from './store.js';
5
+ export interface OrmFileAclStoreOptions {
6
+ /** The ORM connection; default `authz.fsAcl.connection`, else 'default'. */
7
+ readonly connection?: string;
8
+ /** Where Configuration and Orm are resolved; default the DI root. */
9
+ readonly container?: IContainer;
10
+ }
11
+ /**
12
+ * FileAclStore over `fs_acl` (migration AuthzFsAcl_2026_10_17_00_00_00). Reads are narrowed in SQL by `path_hash`
13
+ * (the indexed key) and decided by an exact comparison of `path` in code, and rows change by id, so a table created
14
+ * with a case-insensitive collation never merges two paths.
15
+ */
16
+ export declare class OrmFileAclStore extends FileAclStore {
17
+ private readonly opts;
18
+ constructor(opts?: OrmFileAclStoreOptions);
19
+ holds(fs: string, paths: readonly string[], subjectKeys: readonly string[], relation: string, at: Date): Promise<boolean>;
20
+ list(fs: string, path: string): Promise<readonly FsAclRow[]>;
21
+ grant(row: FsAclRow): Promise<void>;
22
+ revoke(fs: string, path: string, subjectKey: string, relation: string): Promise<void>;
23
+ ownerOf(fs: string, path: string): Promise<PrincipalRef | null>;
24
+ setOwnerIfAbsent(fs: string, path: string, owner: PrincipalRef): Promise<void>;
25
+ deleteTree(fs: string, path: string): Promise<void>;
26
+ deletePath(fs: string, path: string): Promise<void>;
27
+ moveTree(fromFs: string, from: string, toFs: string, to: string): Promise<void>;
28
+ movePath(fromFs: string, from: string, toFs: string, to: string): Promise<void>;
29
+ private driver;
30
+ }
31
+ //# sourceMappingURL=orm-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm-store.d.ts","sourceRoot":"","sources":["../../../src/acl/orm-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAc3C,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC;CACjC;AAID;;;;GAIG;AACH,qBACa,eAAgB,SAAQ,YAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,GAAE,sBAA2B,EAE7D;IAEK,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAa9H;IAEK,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAIjE;IAEK,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CASxC;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1F;IAEK,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOpE;IAEK,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAOnF;IAEK,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxD;IAEK,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxD;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBpF;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcpF;YAEa,MAAM;CAQrB"}