@spinajs/authz-fs 0.0.0-stage → 3.0.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 (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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapter/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** A non-empty filesystem name without ':' (the first ':' of a ref id ends the name). */
2
+ export declare function checkFsName(fsName: unknown): string;
3
+ /** `value` as JSON for an error message; a value JSON cannot hold gives its String or its tag. */
4
+ export declare function show(value: unknown): string;
5
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/checks.ts"],"names":[],"mappings":"AAIA,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAEnD;AAED,kGAAkG;AAClG,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM3C"}
@@ -0,0 +1,16 @@
1
+ import { _check_arg, _is_string, _non_empty, _reg_match } from '@spinajs/util';
2
+ // Internal: the barrel does not export this module.
3
+ /** A non-empty filesystem name without ':' (the first ':' of a ref id ends the name). */
4
+ export function checkFsName(fsName) {
5
+ return _check_arg(_is_string(_non_empty(), _reg_match(/^[^:]*$/)))(fsName, 'fsName');
6
+ }
7
+ /** `value` as JSON for an error message; a value JSON cannot hold gives its String or its tag. */
8
+ export function show(value) {
9
+ try {
10
+ return JSON.stringify(value) ?? String(value);
11
+ }
12
+ catch {
13
+ return Object.prototype.toString.call(value);
14
+ }
15
+ }
16
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/E,oDAAoD;AAEpD,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,OAAO,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACvF,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,IAAI,CAAC,KAAc;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { ResourceRef } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ /**
4
+ * A resource extractor for `@Access` (authz-http's `ResourceExtractor`): the `file` ref of the url parameter
5
+ * `param` on `fsName`, the `fs` ref for the root. The path is normalised as the fs core does (D3), with the base
6
+ * path of the published provider, so the ref is the one AuthzFsMiddleware checks for the same path. Only url
7
+ * parameters are read, as authz-http's `fromParam` does. An Express 5 wildcard (`*path`) gives an array of
8
+ * segments: they are joined with '/', each segment refused on its own when the normaliser refuses it (`..` included).
9
+ *
10
+ * @param container - where the published provider is looked up; default the root container
11
+ * @throws InvalidArgument (400) when the parameter is missing, not a string or a non-empty string array, or the
12
+ * path is refused
13
+ */
14
+ export declare function fromFsPath(fsName: string, param: string, container?: IContainer): (req: unknown) => ResourceRef | Promise<ResourceRef>;
15
+ //# sourceMappingURL=from-fs-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-fs-path.d.ts","sourceRoot":"","sources":["../../../src/http/from-fs-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAStI"}
@@ -0,0 +1,40 @@
1
+ import { DI } from '@spinajs/di';
2
+ import { InvalidArgument } from '@spinajs/exceptions';
3
+ import { publishedFs } from '@spinajs/fs';
4
+ import { _check_arg, _is_string, _non_empty, isStringArray } from '@spinajs/util';
5
+ import { checkFsName } from '../checks.js';
6
+ import { refOf } from '../middleware/decide.js';
7
+ import { normalizeFsPath } from '../refs/index.js';
8
+ /**
9
+ * A resource extractor for `@Access` (authz-http's `ResourceExtractor`): the `file` ref of the url parameter
10
+ * `param` on `fsName`, the `fs` ref for the root. The path is normalised as the fs core does (D3), with the base
11
+ * path of the published provider, so the ref is the one AuthzFsMiddleware checks for the same path. Only url
12
+ * parameters are read, as authz-http's `fromParam` does. An Express 5 wildcard (`*path`) gives an array of
13
+ * segments: they are joined with '/', each segment refused on its own when the normaliser refuses it (`..` included).
14
+ *
15
+ * @param container - where the published provider is looked up; default the root container
16
+ * @throws InvalidArgument (400) when the parameter is missing, not a string or a non-empty string array, or the
17
+ * path is refused
18
+ */
19
+ export function fromFsPath(fsName, param, container) {
20
+ checkFsName(fsName);
21
+ _check_arg(_is_string(_non_empty()))(param, 'param');
22
+ return (req) => {
23
+ const params = req !== null && typeof req === 'object' ? req.params : undefined;
24
+ const value = params !== null && typeof params === 'object' && Object.hasOwn(params, param) ? params[param] : undefined;
25
+ return refOf(fsName, normalizeFsPath(pathOf(value, param, fsName), publishedFs(fsName, container ?? DI.RootContainer)?.BasePath), 'file');
26
+ };
27
+ }
28
+ function pathOf(value, param, fsName) {
29
+ if (typeof value === 'string')
30
+ return value;
31
+ if (isStringArray(value) && value.length > 0) {
32
+ // A segment such as '..' is refused even where the joined path would stay inside the filesystem.
33
+ for (const segment of value)
34
+ if (segment === '' || segment.includes('/') || normalizeFsPath(segment) !== segment)
35
+ throw new InvalidArgument(`url parameter ${param} has the segment ${JSON.stringify(segment)}`, param);
36
+ return value.join('/');
37
+ }
38
+ throw new InvalidArgument(`url parameter ${param} is required to identify a file of ${fsName}`, param);
39
+ }
40
+ //# sourceMappingURL=from-fs-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-fs-path.js","sourceRoot":"","sources":["../../../src/http/from-fs-path.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,KAAa,EAAE,SAAsB;IAC9E,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAErD,OAAO,CAAC,GAAY,EAAe,EAAE;QACnC,MAAM,MAAM,GAAY,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAE,GAA4B,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACnH,MAAM,KAAK,GAAY,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAE,MAAkC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9J,OAAO,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5I,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa,EAAE,MAAc;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,iGAAiG;QACjG,KAAK,MAAM,OAAO,IAAI,KAAiB;YAAE,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,KAAK,OAAO;gBAAE,MAAM,IAAI,eAAe,CAAC,iBAAiB,KAAK,oBAAoB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpO,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,IAAI,eAAe,CAAC,iBAAiB,KAAK,sCAAsC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;AACzG,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './upload.js';
2
+ export * from './from-fs-path.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './upload.js';
2
+ export * from './from-fs-path.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { Principal } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ import { FileUploadMiddleware } from '@spinajs/http';
4
+ import type { IUploadOptions, IUploadedFile } from '@spinajs/http';
5
+ import type { FsDecideService, FsLog } from '../middleware/decide.js';
6
+ /** The filesystem `FromFile` uploads to when the route names none. */
7
+ export declare const DEFAULT_UPLOAD_FS = "__file_upload_default_provider__";
8
+ export interface AuthzUploadMiddlewareOptions {
9
+ /** Where the Configuration, the published providers and AuthzDomains are resolved; default the root. */
10
+ readonly container?: IContainer;
11
+ /** The service that decides for a domain; default the root AuthzService, else `AuthzDomains.service(domain)`. */
12
+ readonly service?: (domain: string) => Promise<FsDecideService>;
13
+ /** Default: the ALS principal, else UNATTENDED (what AuthzService.current() returns). */
14
+ readonly principal?: () => Principal;
15
+ readonly log?: FsLog;
16
+ }
17
+ /**
18
+ * Checks `fs:write` on the file an upload will be written to (`file.Provider`, else `options.fs`, else the default
19
+ * upload filesystem, at `file.BaseName`) before the uploader copies it, with that filesystem's mode and domain:
20
+ * enforce refuses with AccessDenied (403) so the formidable temp file is never copied, audit warns, off does
21
+ * nothing. AuthzFsMiddleware checks the copy again, but the uploader turns its denial into an IOFail (500); this
22
+ * gives the 403. Apps add it after middlewares that rename the file.
23
+ */
24
+ export declare class AuthzUploadMiddleware extends FileUploadMiddleware {
25
+ protected readonly options: AuthzUploadMiddlewareOptions;
26
+ constructor(options?: AuthzUploadMiddlewareOptions);
27
+ beforeUpload(file: IUploadedFile, options?: IUploadOptions): Promise<IUploadedFile>;
28
+ }
29
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/http/upload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAInE,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAGtE,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,qCAAqC,CAAC;AAEpE,MAAM,WAAW,4BAA4B;IAC3C,wGAAwG;IACxG,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,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,SAAS,CAAC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;CACtB;AAED;;;;;;GAMG;AACH,qBACa,qBAAsB,SAAQ,oBAAoB;IACjD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,4BAA4B;IAApE,YAA+B,OAAO,GAAE,4BAAiC,EAExE;IAEY,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAyB/F;CACF"}
@@ -0,0 +1,64 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { currentPrincipal, engineLog } from '@spinajs/authz';
11
+ import { DI, Injectable } from '@spinajs/di';
12
+ import { InvalidArgument } from '@spinajs/exceptions';
13
+ import { publishedFs } from '@spinajs/fs';
14
+ import { FileUploadMiddleware } from '@spinajs/http';
15
+ import { fsAccessConfig } from '../access-config/index.js';
16
+ import { decideFs, domainService, refOf } from '../middleware/decide.js';
17
+ import { fsRowOf, normalizeFsPath } from '../refs/index.js';
18
+ /** The filesystem `FromFile` uploads to when the route names none. */
19
+ export const DEFAULT_UPLOAD_FS = '__file_upload_default_provider__';
20
+ /**
21
+ * Checks `fs:write` on the file an upload will be written to (`file.Provider`, else `options.fs`, else the default
22
+ * upload filesystem, at `file.BaseName`) before the uploader copies it, with that filesystem's mode and domain:
23
+ * enforce refuses with AccessDenied (403) so the formidable temp file is never copied, audit warns, off does
24
+ * nothing. AuthzFsMiddleware checks the copy again, but the uploader turns its denial into an IOFail (500); this
25
+ * gives the 403. Apps add it after middlewares that rename the file.
26
+ */
27
+ let AuthzUploadMiddleware = class AuthzUploadMiddleware extends FileUploadMiddleware {
28
+ constructor(options = {}) {
29
+ super();
30
+ this.options = options;
31
+ }
32
+ async beforeUpload(file, options) {
33
+ // ImmediateFileUploader copies to file.Provider, which an earlier middleware may have replaced; FromFile also
34
+ // falls back on an empty options.fs.
35
+ const named = file.Provider?.Name;
36
+ const fsName = typeof named === 'string' && named !== '' ? named : options?.fs || DEFAULT_UPLOAD_FS;
37
+ const container = this.options.container ?? DI.RootContainer;
38
+ const config = fsAccessConfig(fsName, container);
39
+ if (config.mode === 'off')
40
+ return file;
41
+ const provider = publishedFs(fsName, container) ?? (file.Provider?.Name === fsName ? file.Provider : undefined);
42
+ const path = normalizeFsPath(file.BaseName, provider?.BasePath);
43
+ if (path === '')
44
+ throw new InvalidArgument(`upload ${JSON.stringify(file.Name)} has no file name to write to`, 'BaseName');
45
+ const service = await (this.options.service ?? ((domain) => domainService(container, domain)))(config.domain);
46
+ await decideFs({
47
+ fsName,
48
+ mode: config.mode,
49
+ service,
50
+ log: this.options.log ?? engineLog('authz-fs'),
51
+ principal: (this.options.principal ?? currentPrincipal)(),
52
+ permission: 'fs:write',
53
+ ref: refOf(fsName, path, 'file'),
54
+ subject: fsRowOf(fsName, path, 'file'),
55
+ });
56
+ return file;
57
+ }
58
+ };
59
+ AuthzUploadMiddleware = __decorate([
60
+ Injectable(FileUploadMiddleware),
61
+ __metadata("design:paramtypes", [Object])
62
+ ], AuthzUploadMiddleware);
63
+ export { AuthzUploadMiddleware };
64
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/http/upload.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE5D,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,kCAAkC,CAAC;AAYpE;;;;;;GAMG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,oBAAoB;IAC7D,YAA+B,OAAO,GAAiC,EAAE;QACvE,KAAK,EAAE,CAAC;uBADqB,OAAO;IAEtC,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,IAAmB,EAAE,OAAwB;QACrE,8GAA8G;QAC9G,qCAAqC;QACrC,MAAM,KAAK,GAAY,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,IAAI,iBAAiB,CAAC;QACpG,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,aAAa,CAAC;QAC7D,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjD,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QAEvC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChH,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChE,IAAI,IAAI,KAAK,EAAE;YAAE,MAAM,IAAI,eAAe,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B,EAAE,UAAU,CAAC,CAAC;QAE3H,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC,MAAc,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtH,MAAM,QAAQ,CAAC;YACb,MAAM;YACN,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC,UAAU,CAAC;YAC9C,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC,EAAE;YACzD,UAAU,EAAE,UAAU;YACtB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;YAChC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;SACvC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA/BY,qBAAqB;IADjC,UAAU,CAAC,oBAAoB,CAAC;;GACpB,qBAAqB,CA+BjC"}
@@ -0,0 +1,9 @@
1
+ export * from './refs/index.js';
2
+ export * from './permissions/index.js';
3
+ export * from './access-config/index.js';
4
+ export * from './acl/index.js';
5
+ export * from './adapter/index.js';
6
+ export * from './middleware/index.js';
7
+ export * from './migrations/index.js';
8
+ export * from './http/index.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export * from './refs/index.js';
2
+ export * from './permissions/index.js';
3
+ export * from './access-config/index.js';
4
+ export * from './acl/index.js';
5
+ export * from './adapter/index.js';
6
+ export * from './middleware/index.js';
7
+ export * from './migrations/index.js';
8
+ export * from './http/index.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { AuthzLog, CheckInput, Decision, Permission, Principal, ResourceRef } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ import type { FsAccessMode } from '../access-config/index.js';
4
+ import type { FsPathKind, FsRow } from '../refs/index.js';
5
+ /** The part of AuthzService the fs checks call. */
6
+ export interface FsDecideService {
7
+ check(req: CheckInput): Promise<Decision>;
8
+ assert(principal: Principal, permission: Permission, resource?: ResourceRef | object, subject?: unknown): Promise<Decision>;
9
+ }
10
+ /** `error` is for a file ACL update that failed after the IO; default `warn`. */
11
+ export type FsLog = Pick<AuthzLog, 'warn'> & Partial<Pick<AuthzLog, 'error'>>;
12
+ /** One check of one path: enforce asserts, audit checks and warns. */
13
+ export interface FsCheck {
14
+ readonly fsName: string;
15
+ readonly mode: Exclude<FsAccessMode, 'off'>;
16
+ readonly service: FsDecideService;
17
+ readonly log: FsLog;
18
+ readonly principal: Principal;
19
+ readonly permission: Permission;
20
+ readonly ref: ResourceRef;
21
+ readonly subject: FsRow;
22
+ }
23
+ export declare function decideFs({ fsName, mode, service, log, principal, permission, ref, subject }: FsCheck): Promise<Decision>;
24
+ export declare function warnDenied(fsName: string, log: FsLog, principal: Principal, permission: Permission, ref: ResourceRef, decision: Decision): void;
25
+ /** 'root' is the root AuthzService; any other domain must exist already (`authz.domains`): it is never created here. */
26
+ export declare function domainService(container: IContainer, domain: string): Promise<FsDecideService>;
27
+ /** `now` when it is a valid Date, else the system time. */
28
+ export declare const validNow: (now: unknown) => Date;
29
+ /** The AuthzClock the domain's service booted with, else the system time. */
30
+ export declare function domainNow(container: IContainer, domain: string): Promise<Date>;
31
+ export declare const refOf: (fsName: string, normalised: string, kind: FsPathKind) => ResourceRef;
32
+ //# sourceMappingURL=decide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../../../src/middleware/decide.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAI1D,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC7H;AAED,iFAAiF;AACjF,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9E,sEAAsE;AACtE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;CACzB;AAED,wBAAsB,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAS9H;AAMD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAG/I;AAED,wHAAwH;AACxH,wBAAsB,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAGnG;AAED,2DAA2D;AAC3D,eAAO,MAAM,QAAQ,QAAS,OAAO,KAAG,IAAgF,CAAC;AAEzH,6EAA6E;AAC7E,wBAAsB,SAAS,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF;AAED,eAAO,MAAM,KAAK,WAAY,MAAM,cAAc,MAAM,QAAQ,UAAU,KAAG,WAA+G,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { AccessDenied, AuthzDomains, AuthzService, DEFAULT_DENY_PRIORITY, DefaultAuthzDomains, FALSE, definite, principalKey, resourceKey } from '@spinajs/authz';
2
+ export async function decideFs({ fsName, mode, service, log, principal, permission, ref, subject }) {
3
+ if (mode === 'enforce') {
4
+ const decision = await service.assert(principal, permission, ref, subject);
5
+ if (!definite(decision))
6
+ throw new AccessDenied(conditional(decision));
7
+ return decision;
8
+ }
9
+ const decision = await service.check({ principal, permission, resource: ref, subject });
10
+ if (!definite(decision))
11
+ warnDenied(fsName, log, principal, permission, ref, decision);
12
+ return decision;
13
+ }
14
+ function conditional(decision) {
15
+ return { ...decision, allowed: false, residual: FALSE, reason: { code: 'needs_subject', priority: DEFAULT_DENY_PRIORITY.needs_subject } };
16
+ }
17
+ export function warnDenied(fsName, log, principal, permission, ref, decision) {
18
+ const why = decision.allowed ? 'conditional' : decision.reason?.code;
19
+ log.warn({ fsName, principal: principalKey(principal), permission, resource: resourceKey(ref), why }, 'authz.fs.${fsName}: ${principal} lacks ${permission} on ${resource}${?why} (${why})${/why}; allowed in audit mode');
20
+ }
21
+ /** 'root' is the root AuthzService; any other domain must exist already (`authz.domains`): it is never created here. */
22
+ export async function domainService(container, domain) {
23
+ if (domain === 'root')
24
+ return (await container.resolve(AuthzService));
25
+ return (await container.resolve(AuthzDomains)).service(domain);
26
+ }
27
+ /** `now` when it is a valid Date, else the system time. */
28
+ export const validNow = (now) => (now instanceof Date && !Number.isNaN(now.getTime()) ? now : new Date());
29
+ /** The AuthzClock the domain's service booted with, else the system time. */
30
+ export async function domainNow(container, domain) {
31
+ try {
32
+ const domains = await container.resolve(AuthzDomains);
33
+ if (domains instanceof DefaultAuthzDomains)
34
+ return validNow(domains.clock(domain).now());
35
+ }
36
+ catch {
37
+ // no authz host, no such domain or its service has not booted: the system time
38
+ }
39
+ return new Date();
40
+ }
41
+ export const refOf = (fsName, normalised, kind) => (normalised === '' ? { type: 'fs', id: fsName } : { type: kind, id: `${fsName}:${normalised}` });
42
+ //# sourceMappingURL=decide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decide.js","sourceRoot":"","sources":["../../../src/middleware/decide.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { Principal } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ import { FsMiddleware } from '@spinajs/fs';
4
+ import type { FsActionContext, fs } from '@spinajs/fs';
5
+ import type { FsAccessConfig } from '../access-config/index.js';
6
+ import type { FileAclStore } from '../acl/store.js';
7
+ import type { FsDecideService, FsLog } from './decide.js';
8
+ export type { FsDecideService, FsLog } from './decide.js';
9
+ export { FS_NO_OWNER_TYPES } from './owner.js';
10
+ export { DEFAULT_SIGNED_URL_TTL_SECONDS } from './signed-url.js';
11
+ export interface AuthzFsMiddlewareOptions {
12
+ /** Where the Configuration, AuthzService, AuthzDomains and the FileAclStore are resolved; default the root. */
13
+ readonly container?: IContainer;
14
+ /** The service that decides for a domain; default the root AuthzService, else `AuthzDomains.service(domain)`. */
15
+ readonly service?: (domain: string) => Promise<FsDecideService>;
16
+ /** Default: the ALS principal, else UNATTENDED (what AuthzService.current() returns). */
17
+ readonly principal?: () => Principal;
18
+ readonly log?: FsLog;
19
+ /** The time signed URL lifetimes count from; default the AuthzClock of the filesystem's domain. */
20
+ readonly now?: () => Date;
21
+ readonly store?: () => Promise<FileAclStore>;
22
+ }
23
+ /**
24
+ * Checks every target of every fs action with the `authz.fs.<name>` entry of the target's own filesystem (fs
25
+ * middleware design §2.1) and keeps the file ACL in step with what the action did.
26
+ */
27
+ export declare class AuthzFsMiddleware extends FsMiddleware {
28
+ protected readonly options: AuthzFsMiddlewareOptions;
29
+ order: number;
30
+ private logger?;
31
+ constructor(options?: AuthzFsMiddlewareOptions);
32
+ isEnabled(target: fs): boolean;
33
+ before(ctx: FsActionContext): Promise<void>;
34
+ after(ctx: FsActionContext, result: unknown): Promise<unknown>;
35
+ protected get container(): IContainer;
36
+ protected configOf(target: fs): FsAccessConfig;
37
+ private get log();
38
+ private service;
39
+ private store;
40
+ private decide;
41
+ private narrowSignedUrl;
42
+ private probeDeleted;
43
+ private applyRows;
44
+ /**
45
+ * A destination that existed keeps its rows (first writer) and the source rows go; otherwise the source rows move
46
+ * there, onto another filesystem too (one table): a directory's whole tree, anything else only its own rows. No
47
+ * owner is stamped: the rows travel with the file. A key whose prefix holds keys leaves its rows to the prefix. A
48
+ * destination too long for a row gets none: the source rows go, its parents' rows cover it.
49
+ */
50
+ private moveRows;
51
+ private listEach;
52
+ }
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAY,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAK1D,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC;AAEjE,MAAM,WAAW,wBAAwB;IACvC,+GAA+G;IAC/G,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,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,SAAS,CAAC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IACrB,mGAAmG;IACnG,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9C;AA8CD;;;GAGG;AACH,qBACa,iBAAkB,SAAQ,YAAY;IAIrC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,wBAAwB;IAHzD,KAAK,SAAO;IACnB,OAAO,CAAC,MAAM,CAAC,CAAQ;IAEvB,YAA+B,OAAO,GAAE,wBAA6B,EAEpE;IAED,SAAS,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAE7B;IAEK,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhD;IAEK,KAAK,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAcnE;IAED,SAAS,KAAK,SAAS,IAAI,UAAU,CAEpC;IAKD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,CAM7C;IAED,OAAO,KAAK,GAAG,GAEd;IAED,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;YAIC,MAAM;YAYN,eAAe;YAQf,YAAY;YAKZ,SAAS;IAmBvB;;;;;OAKG;YACW,QAAQ;YAaR,QAAQ;CA0BvB"}