@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,196 @@
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 { randomUUID } from 'node:crypto';
11
+ import { AuthzConfigError } from '@spinajs/authz';
12
+ import { DI, Injectable } from '@spinajs/di';
13
+ import { InvalidArgument } from '@spinajs/exceptions';
14
+ import { Orm, instantFromDb } from '@spinajs/orm';
15
+ import { chunk } from '@spinajs/util';
16
+ import { FS_ACL_CONNECTION_KEY, FS_ACL_OWNER, fsAclConfig } from '../access-config/acl-config.js';
17
+ import { FS_ACL_LIMITS, FS_ACL_TABLE, aclExpiry, aclFs, aclOwnerKey, aclPath, aclPathHash, aclRelation, aclSubjectKey, checkMove, fits, isWildcardKey, movedPath, subjectOfKey } from './shared.js';
18
+ import { FileAclStore } from './store.js';
19
+ const IN_CHUNK = 500;
20
+ /**
21
+ * FileAclStore over `fs_acl` (migration AuthzFsAcl_2026_10_17_00_00_00). Reads are narrowed in SQL by `path_hash`
22
+ * (the indexed key) and decided by an exact comparison of `path` in code, and rows change by id, so a table created
23
+ * with a case-insensitive collation never merges two paths.
24
+ */
25
+ let OrmFileAclStore = class OrmFileAclStore extends FileAclStore {
26
+ constructor(opts = {}) {
27
+ super();
28
+ this.opts = opts;
29
+ }
30
+ async holds(fs, paths, subjectKeys, relation, at) {
31
+ const f = aclFs(fs);
32
+ const r = aclRelation(relation);
33
+ const wanted = [...new Set(paths.map(aclPath))];
34
+ const keys = [...new Set(subjectKeys)];
35
+ if (wanted.length === 0 || keys.length === 0)
36
+ return false;
37
+ const hashes = wanted.map(aclPathHash);
38
+ const driver = await this.driver();
39
+ for (const part of chunk(keys, IN_CHUNK)) {
40
+ const rows = ((await driver.select().from(FS_ACL_TABLE).where({ fs: f, relation: r }).whereIn('path_hash', hashes).whereIn('subject_key', part)) ?? []);
41
+ if (rows.some((row) => row.fs === f && row.relation === r && wanted.includes(row.path) && part.includes(row.subject_key) && live(row, at)))
42
+ return true;
43
+ }
44
+ return false;
45
+ }
46
+ async list(fs, path) {
47
+ const f = aclFs(fs);
48
+ const p = aclPath(path);
49
+ return (await exactRows(await this.driver(), f, p)).map(rowOf);
50
+ }
51
+ async grant(row) {
52
+ const key = { fs: aclFs(row.fs), path: aclPath(row.path), subject_key: aclSubjectKey(row.subject), relation: aclRelation(row.relation) };
53
+ const values = { expires_at: aclExpiry(row.expiresAt), granted_by: row.grantedBy === undefined ? null : fits(row.grantedBy, 'granted_by') };
54
+ const driver = await this.driver();
55
+ await driver.transaction(async (tx) => {
56
+ const found = (await exactRows(tx, key.fs, key.path)).find((r) => r.subject_key === key.subject_key && r.relation === key.relation);
57
+ if (found)
58
+ await tx.update().in(FS_ACL_TABLE).update(values).where({ id: found.id });
59
+ else
60
+ await tx.insert().into(FS_ACL_TABLE).values({ id: randomUUID(), ...key, path_hash: aclPathHash(key.path), ...values, created_at: new Date() });
61
+ });
62
+ }
63
+ async revoke(fs, path, subjectKey, relation) {
64
+ const f = aclFs(fs);
65
+ const p = aclPath(path);
66
+ const r = aclRelation(relation);
67
+ const driver = await this.driver();
68
+ await driver.transaction(async (tx) => deleteIds(tx, (await exactRows(tx, f, p)).filter((row) => row.subject_key === subjectKey && row.relation === r).map((row) => row.id)));
69
+ }
70
+ async ownerOf(fs, path) {
71
+ const rows = (await exactRows(await this.driver(), aclFs(fs), aclPath(path))).filter((r) => r.relation === FS_ACL_OWNER && !isWildcardKey(r.subject_key));
72
+ for (const row of oldestFirst(rows)) {
73
+ const subject = subjectOfKey(row.subject_key, `${FS_ACL_TABLE} row ${row.id}`);
74
+ if (!('set' in subject))
75
+ return { type: subject.type, id: subject.id };
76
+ }
77
+ return null;
78
+ }
79
+ async setOwnerIfAbsent(fs, path, owner) {
80
+ const key = { fs: aclFs(fs), path: aclPath(path), subject_key: aclOwnerKey(owner), relation: FS_ACL_OWNER };
81
+ const driver = await this.driver();
82
+ await driver.transaction(async (tx) => {
83
+ if ((await exactRows(tx, key.fs, key.path)).some((r) => r.relation === FS_ACL_OWNER))
84
+ return;
85
+ await tx.insert().into(FS_ACL_TABLE).values({ id: randomUUID(), ...key, path_hash: aclPathHash(key.path), expires_at: null, granted_by: null, created_at: new Date() });
86
+ });
87
+ }
88
+ async deleteTree(fs, path) {
89
+ const f = aclFs(fs);
90
+ const p = aclPath(path);
91
+ const driver = await this.driver();
92
+ await driver.transaction(async (tx) => deleteIds(tx, (await tree(tx, f, p)).map((r) => r.id)));
93
+ }
94
+ async deletePath(fs, path) {
95
+ const f = aclFs(fs);
96
+ const p = aclPath(path);
97
+ const driver = await this.driver();
98
+ await driver.transaction(async (tx) => deleteIds(tx, (await exactRows(tx, f, p)).map((r) => r.id)));
99
+ }
100
+ async moveTree(fromFs, from, toFs, to) {
101
+ const src = { fs: aclFs(fromFs), path: aclPath(from) };
102
+ const dst = { fs: aclFs(toFs), path: aclPath(to) };
103
+ if (src.fs === dst.fs && src.path === dst.path)
104
+ return;
105
+ checkMove(src.fs, src.path, dst.fs, dst.path);
106
+ const driver = await this.driver();
107
+ await driver.transaction(async (tx) => {
108
+ const rows = await tree(tx, src.fs, src.path);
109
+ const landing = rows.map((row) => ({ row, path: movedPath(src.path, dst.path, row.path) }));
110
+ // A row too long for the path column goes: what it named falls under the moved parents' rows.
111
+ const moves = landing.filter((m) => m.path.length <= FS_ACL_LIMITS.path);
112
+ // Only a move onto an ancestor can land one moved row on another; no provider moves a directory there.
113
+ const sources = new Set(rows.map((r) => r.path));
114
+ if (src.fs === dst.fs && moves.some((m) => sources.has(m.path)))
115
+ throw new InvalidArgument(`cannot move ${src.fs}:${src.path} onto ${dst.path}, which holds it`, 'to');
116
+ const taken = new Set(moves.map((m) => rowKey(m.path, m.row)));
117
+ const replaced = (await tree(tx, dst.fs, dst.path)).filter((r) => taken.has(rowKey(r.path, r))).map((r) => r.id);
118
+ const dropped = landing.filter((m) => !moves.includes(m)).map((m) => m.row.id);
119
+ await deleteIds(tx, [...replaced, ...dropped]);
120
+ for (const m of moves)
121
+ await tx.update().in(FS_ACL_TABLE).update({ fs: dst.fs, path: m.path, path_hash: aclPathHash(m.path) }).where({ id: m.row.id });
122
+ });
123
+ }
124
+ async movePath(fromFs, from, toFs, to) {
125
+ const src = { fs: aclFs(fromFs), path: aclPath(from) };
126
+ const dst = { fs: aclFs(toFs), path: aclPath(to) };
127
+ if (src.fs === dst.fs && src.path === dst.path)
128
+ return;
129
+ const driver = await this.driver();
130
+ await driver.transaction(async (tx) => {
131
+ // The destination's equal rows go first, else the UPDATE would break the unique key.
132
+ const moving = new Set((await exactRows(tx, src.fs, src.path)).map((r) => rowKey(dst.path, r)));
133
+ await deleteIds(tx, (await exactRows(tx, dst.fs, dst.path)).filter((r) => moving.has(rowKey(r.path, r))).map((r) => r.id));
134
+ await tx.update().in(FS_ACL_TABLE).update({ fs: dst.fs, path: dst.path, path_hash: aclPathHash(dst.path) }).where({ fs: src.fs, path_hash: aclPathHash(src.path), path: src.path });
135
+ });
136
+ }
137
+ async driver() {
138
+ const container = this.opts.container ?? DI.RootContainer;
139
+ const name = this.opts.connection ?? fsAclConfig(container).connection;
140
+ const orm = (await container.resolve(Orm));
141
+ const driver = orm.Connections.get(name);
142
+ if (!driver)
143
+ throw new AuthzConfigError(`OrmFileAclStore: ${FS_ACL_CONNECTION_KEY} names connection ${JSON.stringify(name)}, which the ORM does not have (connections: ${[...orm.Connections.keys()].join(', ') || 'none'})`);
144
+ return driver;
145
+ }
146
+ };
147
+ OrmFileAclStore = __decorate([
148
+ Injectable(FileAclStore),
149
+ __metadata("design:paramtypes", [Object])
150
+ ], OrmFileAclStore);
151
+ export { OrmFileAclStore };
152
+ const rowKey = (path, r) => `${path}\0${r.subject_key}\0${r.relation}`;
153
+ // Rows are read without a model, so no column converter runs: SQLite hands back ISO text, the others a Date.
154
+ function toDate(value, column) {
155
+ if (value === null || value === undefined)
156
+ return null;
157
+ const instant = instantFromDb(value);
158
+ if (!instant)
159
+ throw new AuthzConfigError(`${FS_ACL_TABLE}.${column} holds an unreadable datetime ${JSON.stringify(value)}`);
160
+ return instant.toJSDate();
161
+ }
162
+ function live(row, at) {
163
+ const until = toDate(row.expires_at, 'expires_at');
164
+ return until === null || until.getTime() > at.getTime();
165
+ }
166
+ const oldestFirst = (rows) => [...rows].sort((a, b) => (toDate(a.created_at, 'created_at')?.getTime() ?? 0) - (toDate(b.created_at, 'created_at')?.getTime() ?? 0));
167
+ function rowOf(row) {
168
+ const expiresAt = toDate(row.expires_at, 'expires_at');
169
+ return Object.freeze({
170
+ fs: row.fs,
171
+ path: row.path,
172
+ subject: subjectOfKey(row.subject_key, `${FS_ACL_TABLE} row ${row.id}`),
173
+ relation: row.relation,
174
+ ...(expiresAt ? { expiresAt } : {}),
175
+ ...(row.granted_by ? { grantedBy: row.granted_by } : {}),
176
+ });
177
+ }
178
+ async function exactRows(driver, fs, path) {
179
+ const rows = ((await driver.select().from(FS_ACL_TABLE).where({ fs, path_hash: aclPathHash(path), path })) ?? []);
180
+ return rows.filter((r) => r.fs === fs && r.path === path);
181
+ }
182
+ /**
183
+ * The rows at `path` and under it ('' = every row of the filesystem). `whereStartsWith` only narrows the read (it may
184
+ * ignore case under the column's collation); the exact test in code decides.
185
+ */
186
+ async function tree(driver, fs, path) {
187
+ if (path === '')
188
+ return ((await driver.select().from(FS_ACL_TABLE).where({ fs })) ?? []).filter((r) => r.fs === fs);
189
+ const below = ((await driver.select().from(FS_ACL_TABLE).where({ fs }).whereStartsWith('path', `${path}/`)) ?? []);
190
+ return [...(await exactRows(driver, fs, path)), ...below.filter((r) => r.fs === fs && r.path.startsWith(`${path}/`))];
191
+ }
192
+ async function deleteIds(driver, ids) {
193
+ for (const part of chunk(ids, IN_CHUNK))
194
+ await driver.del().from(FS_ACL_TABLE).whereIn('id', part);
195
+ }
196
+ //# sourceMappingURL=orm-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm-store.js","sourceRoot":"","sources":["../../../src/acl/orm-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { RelationResolver } from '@spinajs/authz';
2
+ import type { Principal, ResourceRef } from '@spinajs/authz';
3
+ import type { IContainer } from '@spinajs/di';
4
+ import type { FsRefType } from '../refs/index.js';
5
+ /**
6
+ * `relation` on fs refs of `type`, read from the file ACL (fs middleware design §2.2): holds when a live row of the
7
+ * relation at the path, a parent directory or the filesystem root names one of the principal's subject keys. The
8
+ * subject the engine passes is ignored: a caller-built row could claim anything.
9
+ *
10
+ * Known limit: `holds` never sees a check's `fresh` flag, so subjectKeysOf reads assignments through the RBAC
11
+ * model's cache and a set membership may lag by its TTL.
12
+ */
13
+ export declare class FsAclRelation extends RelationResolver {
14
+ readonly type: FsRefType;
15
+ readonly relation: string;
16
+ /** Where the Configuration, AuthzDomains and the FileAclStore are resolved. */
17
+ protected readonly container: IContainer;
18
+ constructor(type: FsRefType, relation: string,
19
+ /** Where the Configuration, AuthzDomains and the FileAclStore are resolved. */
20
+ container?: IContainer);
21
+ holds(principal: Principal, ref: ResourceRef): Promise<boolean>;
22
+ /**
23
+ * From the RbacService registered in the domain or a parent (sets, companions, wildcards, the ceiling applied),
24
+ * used only when it is the service of a model the domain's AuthzService runs: a child domain without one must not match
25
+ * set rows through its parent's service. Otherwise the principal and its type wildcard.
26
+ */
27
+ protected subjectKeys(principal: Principal, domain: string, at: Date): Promise<readonly string[]>;
28
+ }
29
+ //# sourceMappingURL=relation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.d.ts","sourceRoot":"","sources":["../../../src/acl/relation.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,gBAAgB;IAE/C,QAAQ,CAAC,IAAI,EAAE,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,+EAA+E;IAC/E,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU;IAJ1C,YACW,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM;IACzB,+EAA+E;IAC5D,SAAS,GAAE,UAA6B,EAG5D;IAEK,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpE;IAED;;;;OAIG;IACH,UAAgB,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAQtG;CACF"}
@@ -0,0 +1,56 @@
1
+ import { AuthzDomains, AuthzService, RelationResolver } from '@spinajs/authz';
2
+ import { RbacService, principalSubjectKey, subjectKeyOf } from '@spinajs/authz-rbac';
3
+ import { Configuration } from '@spinajs/configuration';
4
+ import { DI } from '@spinajs/di';
5
+ import { fsAccessConfig } from '../access-config/index.js';
6
+ import { domainNow } from '../middleware/decide.js';
7
+ import { FS_NO_OWNER_TYPES } from '../middleware/owner.js';
8
+ import { parseFsRef } from '../refs/index.js';
9
+ import { FS_ACL_LIMITS, aclPathChain, fileAclStore } from './shared.js';
10
+ /**
11
+ * `relation` on fs refs of `type`, read from the file ACL (fs middleware design §2.2): holds when a live row of the
12
+ * relation at the path, a parent directory or the filesystem root names one of the principal's subject keys. The
13
+ * subject the engine passes is ignored: a caller-built row could claim anything.
14
+ *
15
+ * Known limit: `holds` never sees a check's `fresh` flag, so subjectKeysOf reads assignments through the RBAC
16
+ * model's cache and a set membership may lag by its TTL.
17
+ */
18
+ export class FsAclRelation extends RelationResolver {
19
+ constructor(type, relation,
20
+ /** Where the Configuration, AuthzDomains and the FileAclStore are resolved. */
21
+ container = DI.RootContainer) {
22
+ super();
23
+ this.type = type;
24
+ this.relation = relation;
25
+ this.container = container;
26
+ }
27
+ async holds(principal, ref) {
28
+ if (ref?.type !== this.type || FS_NO_OWNER_TYPES.has(principal.type))
29
+ return false;
30
+ const parsed = parseFsRef(ref);
31
+ if (!parsed || parsed.fs.length > FS_ACL_LIMITS.fs)
32
+ return false;
33
+ // No row can exist for a path past the column width, and the store refuses one.
34
+ const chain = aclPathChain(parsed.path).filter((p) => p.length <= FS_ACL_LIMITS.path);
35
+ const domain = this.container.get(Configuration) ? fsAccessConfig(parsed.fs, this.container).domain : 'root';
36
+ const at = await domainNow(this.container, domain);
37
+ const keys = await this.subjectKeys(principal, domain, at);
38
+ return (await fileAclStore(this.container)).holds(parsed.fs, chain, keys, this.relation, at);
39
+ }
40
+ /**
41
+ * From the RbacService registered in the domain or a parent (sets, companions, wildcards, the ceiling applied),
42
+ * used only when it is the service of a model the domain's AuthzService runs: a child domain without one must not match
43
+ * set rows through its parent's service. Otherwise the principal and its type wildcard.
44
+ */
45
+ async subjectKeys(principal, domain, at) {
46
+ const own = [principalSubjectKey(principal), subjectKeyOf({ type: principal.type, id: '*' })];
47
+ const domains = domain === 'root' ? undefined : (await this.container.resolve(AuthzDomains));
48
+ const scope = domains ? domains.container(domain) : this.container;
49
+ if (!scope.hasRegistered(RbacService))
50
+ return own;
51
+ const rbac = (await scope.resolve(RbacService));
52
+ const authz = domains ? await domains.service(domain) : (await scope.resolve(AuthzService));
53
+ return authz.models().includes(rbac.model) ? rbac.subjectKeysOf(principal, at) : own;
54
+ }
55
+ }
56
+ //# sourceMappingURL=relation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.js","sourceRoot":"","sources":["../../../src/acl/relation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { AssignmentSubject, PrincipalRef } from '@spinajs/authz';
2
+ import type { IContainer } from '@spinajs/di';
3
+ import { FileAclStore } from './store.js';
4
+ export declare const FS_ACL_TABLE = "fs_acl";
5
+ export declare const FS_ACL_LIMITS: Readonly<{
6
+ fs: 64;
7
+ path: 512;
8
+ subject_key: 200;
9
+ relation: 64;
10
+ granted_by: 100;
11
+ }>;
12
+ type Column = keyof typeof FS_ACL_LIMITS;
13
+ export declare function fits(value: string, column: Column): string;
14
+ export declare const aclFs: (fs: unknown) => string;
15
+ export declare const aclPath: (path: string) => string;
16
+ /** `fs_acl.path_hash`: keeps the unique key short enough for every driver (path alone is 2048 bytes in MySQL utf8mb4). */
17
+ export declare const aclPathHash: (normalised: string) => string;
18
+ export declare const aclRelation: (relation: unknown) => string;
19
+ export declare const aclSubjectKey: (subject: AssignmentSubject) => string;
20
+ /** An owner is one principal: its own key, never the type wildcard (a principal whose id is '*' stays itself). */
21
+ export declare function aclOwnerKey(owner: PrincipalRef): string;
22
+ export declare function aclExpiry(expiresAt: unknown): Date | null;
23
+ /** `type:*`: every principal of the type. */
24
+ export declare const isWildcardKey: (key: string) => boolean;
25
+ /** The subject a stored key names: a set (`type:id#role`), a principal, or a type wildcard. */
26
+ export declare function subjectOfKey(key: string, at: string): AssignmentSubject;
27
+ /** `path`, its parent directories nearest first, then '' (D7: a row on a directory or the root covers what is under it). */
28
+ export declare function aclPathChain(path: string): string[];
29
+ export declare const isUnder: (path: string, root: string) => boolean;
30
+ /** Where `path` (at or under `from`) lands when `from` moves to `to`. */
31
+ export declare function movedPath(from: string, to: string, path: string): string;
32
+ export declare function checkMove(fromFs: string, from: string, toFs: string, to: string): void;
33
+ /** The FileAclStore of `container`: the last one registered (OrmFileAclStore unless an app or a test adds one). */
34
+ export declare function fileAclStore(container: IContainer): Promise<FileAclStore>;
35
+ export {};
36
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/acl/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,eAAO,MAAM,aAAa;;;;;;EAA2G,CAAC;AAEtI,KAAK,MAAM,GAAG,MAAM,OAAO,aAAa,CAAC;AAEzC,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,eAAO,MAAM,KAAK,OAAQ,OAAO,KAAG,MAAqC,CAAC;AAE1E,eAAO,MAAM,OAAO,SAAU,MAAM,KAAG,MAA6C,CAAC;AAErF,0HAA0H;AAC1H,eAAO,MAAM,WAAW,eAAgB,MAAM,KAAG,MAA4B,CAAC;AAE9E,eAAO,MAAM,WAAW,aAAc,OAAO,KAAG,MAAgG,CAAC;AAEjJ,eAAO,MAAM,aAAa,YAAa,iBAAiB,KAAG,MAAoD,CAAC;AAEhH,kHAAkH;AAClH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAKvD;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAIzD;AAED,6CAA6C;AAC7C,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,OAA6B,CAAC;AAE1E,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAIvE;AAED,4HAA4H;AAC5H,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAOnD;AAED,eAAO,MAAM,OAAO,SAAU,MAAM,QAAQ,MAAM,KAAG,OAAsE,CAAC;AAE5H,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAEtF;AAED,mHAAmH;AACnH,wBAAsB,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAE/E"}
@@ -0,0 +1,73 @@
1
+ import { AuthzConfigError } from '@spinajs/authz';
2
+ import { SUBJECT_KEY_MAX_LENGTH, parsePrincipalKey, parsePrincipalSubjectKey, parseSetKey, principalSubjectKey, subjectKeyOf } from '@spinajs/authz-rbac';
3
+ import { InvalidArgument } from '@spinajs/exceptions';
4
+ import { normalizeFsPath } from '@spinajs/fs';
5
+ import { _check_arg, _is_string, _non_empty } from '@spinajs/util';
6
+ import { sha256 } from '@spinajs/util/crypto';
7
+ import { checkFsName } from '../checks.js';
8
+ import { FileAclStore } from './store.js';
9
+ // Internal to the ACL stores, the relation and the middleware; the barrel exports the two constants only.
10
+ export const FS_ACL_TABLE = 'fs_acl';
11
+ export const FS_ACL_LIMITS = Object.freeze({ fs: 64, path: 512, subject_key: SUBJECT_KEY_MAX_LENGTH, relation: 64, granted_by: 100 });
12
+ export function fits(value, column) {
13
+ if (value.length > FS_ACL_LIMITS[column])
14
+ throw new InvalidArgument(`${JSON.stringify(value.slice(0, 40))}… does not fit ${FS_ACL_TABLE}.${column} (${FS_ACL_LIMITS[column]} characters)`, column);
15
+ return value;
16
+ }
17
+ export const aclFs = (fs) => fits(checkFsName(fs), 'fs');
18
+ export const aclPath = (path) => fits(normalizeFsPath(path), 'path');
19
+ /** `fs_acl.path_hash`: keeps the unique key short enough for every driver (path alone is 2048 bytes in MySQL utf8mb4). */
20
+ export const aclPathHash = (normalised) => sha256(normalised);
21
+ export const aclRelation = (relation) => fits(_check_arg(_is_string(_non_empty()))(relation, 'relation'), 'relation');
22
+ export const aclSubjectKey = (subject) => fits(subjectKeyOf(subject), 'subject_key');
23
+ /** An owner is one principal: its own key, never the type wildcard (a principal whose id is '*' stays itself). */
24
+ export function aclOwnerKey(owner) {
25
+ if (owner === null || typeof owner !== 'object' || typeof owner.type !== 'string' || owner.type === '' || typeof owner.id !== 'string' || owner.id === '') {
26
+ throw new InvalidArgument(`an owner is a principal { type, id } with non-empty strings, got ${JSON.stringify(owner)}`, 'owner');
27
+ }
28
+ return fits(principalSubjectKey({ type: owner.type, id: owner.id }), 'subject_key');
29
+ }
30
+ export function aclExpiry(expiresAt) {
31
+ if (expiresAt === undefined || expiresAt === null)
32
+ return null;
33
+ if (!(expiresAt instanceof Date) || Number.isNaN(expiresAt.getTime()))
34
+ throw new InvalidArgument(`expiresAt must be a valid Date, got ${String(expiresAt)}`, 'expiresAt');
35
+ return expiresAt;
36
+ }
37
+ /** `type:*`: every principal of the type. */
38
+ export const isWildcardKey = (key) => key.endsWith(':*');
39
+ /** The subject a stored key names: a set (`type:id#role`), a principal, or a type wildcard. */
40
+ export function subjectOfKey(key, at) {
41
+ const subject = parseSetKey(key) ?? parsePrincipalSubjectKey(key) ?? (isWildcardKey(key) ? parsePrincipalKey(key) : undefined);
42
+ if (!subject)
43
+ throw new AuthzConfigError(`${at}: ${JSON.stringify(key)} is not a subject key`);
44
+ return subject;
45
+ }
46
+ /** `path`, its parent directories nearest first, then '' (D7: a row on a directory or the root covers what is under it). */
47
+ export function aclPathChain(path) {
48
+ if (path === '')
49
+ return [''];
50
+ const segments = path.split('/');
51
+ const chain = [];
52
+ for (let n = segments.length; n > 0; n--)
53
+ chain.push(segments.slice(0, n).join('/'));
54
+ chain.push('');
55
+ return chain;
56
+ }
57
+ export const isUnder = (path, root) => root === '' || path === root || path.startsWith(`${root}/`);
58
+ /** Where `path` (at or under `from`) lands when `from` moves to `to`. */
59
+ export function movedPath(from, to, path) {
60
+ const rest = from === '' ? path : path.slice(from.length + 1);
61
+ if (to === '')
62
+ return rest;
63
+ return rest === '' ? to : `${to}/${rest}`;
64
+ }
65
+ export function checkMove(fromFs, from, toFs, to) {
66
+ if (fromFs === toFs && from !== to && (from === '' || to.startsWith(`${from}/`)))
67
+ throw new InvalidArgument(`cannot move ${fromFs}:${from} into itself (${to})`, 'to');
68
+ }
69
+ /** The FileAclStore of `container`: the last one registered (OrmFileAclStore unless an app or a test adds one). */
70
+ export async function fileAclStore(container) {
71
+ return (await container.resolve(FileAclStore));
72
+ }
73
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/acl/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { AssignmentSubject, PrincipalRef } from '@spinajs/authz';
2
+ /** One row of the file ACL: `subject` holds `relation` on `path` of `fs` and on everything under it (D7). */
3
+ export interface FsAclRow {
4
+ readonly fs: string;
5
+ /** Normalised; '' is the filesystem root. */
6
+ readonly path: string;
7
+ /** A principal, `{ type, id: '*' }` for every principal of a type, or a subject set (D8). */
8
+ readonly subject: AssignmentSubject;
9
+ readonly relation: string;
10
+ readonly expiresAt?: Date;
11
+ /** principalKey of whoever granted the row. */
12
+ readonly grantedBy?: string;
13
+ }
14
+ /**
15
+ * The file ACL (fs middleware design §3.1). Paths are normalised without a base path ('' = the root); subject keys
16
+ * are authz-rbac `subjectKeyOf` keys. AuthzFsMiddleware keeps it in step with the files; system code may call it
17
+ * directly, apps go through FsAcl.
18
+ */
19
+ export declare abstract class FileAclStore {
20
+ /** Whether a live row of `relation` at one of `paths` names one of `subjectKeys` at `at`. */
21
+ abstract holds(fs: string, paths: readonly string[], subjectKeys: readonly string[], relation: string, at: Date): Promise<boolean>;
22
+ /** The rows at exactly `path`, expired ones included. */
23
+ abstract list(fs: string, path: string): Promise<readonly FsAclRow[]>;
24
+ /** Idempotent on (fs, path, subject, relation): a second grant replaces `expiresAt` and `grantedBy`. */
25
+ abstract grant(row: FsAclRow): Promise<void>;
26
+ abstract revoke(fs: string, path: string, subjectKey: string, relation: string): Promise<void>;
27
+ /** The principal of the oldest `owner` row at exactly `path` (set and wildcard rows skipped); null without one. */
28
+ abstract ownerOf(fs: string, path: string): Promise<PrincipalRef | null>;
29
+ /** Adds an `owner` row for `owner` unless `path` has an owner row already (first writer wins). */
30
+ abstract setOwnerIfAbsent(fs: string, path: string, owner: PrincipalRef): Promise<void>;
31
+ /** The rows at `path` and under it; '' takes every row of the filesystem. */
32
+ abstract deleteTree(fs: string, path: string): Promise<void>;
33
+ /** The rows at exactly `path`. */
34
+ abstract deletePath(fs: string, path: string): Promise<void>;
35
+ /**
36
+ * Moves the rows at `from` and under it to `to` on `toFs`; a moved row replaces an equal one there. A row whose new
37
+ * path would be longer than FS_ACL_LIMITS.path is deleted.
38
+ */
39
+ abstract moveTree(fromFs: string, from: string, toFs: string, to: string): Promise<void>;
40
+ /** Moves the rows at exactly `from` (none under it) to `to` on `toFs`; a moved row replaces an equal one there. */
41
+ abstract movePath(fromFs: string, from: string, toFs: string, to: string): Promise<void>;
42
+ }
43
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/acl/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,6GAA6G;AAC7G,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,8BAAsB,YAAY;IAChC,6FAA6F;IAC7F,QAAQ,CAAC,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,CAAC;IACnI,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IACtE,wGAAwG;IACxG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,mHAAmH;IACnH,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACzE,kGAAkG;IAClG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,kCAAkC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1F"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The file ACL (fs middleware design §3.1). Paths are normalised without a base path ('' = the root); subject keys
3
+ * are authz-rbac `subjectKeyOf` keys. AuthzFsMiddleware keeps it in step with the files; system code may call it
4
+ * directly, apps go through FsAcl.
5
+ */
6
+ export class FileAclStore {
7
+ }
8
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/acl/store.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,MAAM,OAAgB,YAAY;CAuBjC"}
@@ -0,0 +1,33 @@
1
+ import { ResourceAdapter } from '@spinajs/authz';
2
+ import type { PermissionDef, RelationResolver, ResourceRef, ResourceType } from '@spinajs/authz';
3
+ import type { IContainer } from '@spinajs/di';
4
+ import type { FsPathKind, FsRow } from '../refs/index.js';
5
+ export interface FsResourceTarget {
6
+ readonly fs: string;
7
+ readonly path: string;
8
+ /** Default: 'dir' for a row (load) of type 'dir', else 'file'. */
9
+ readonly kind?: FsPathKind;
10
+ }
11
+ /** Refs, ancestors, rows and permissions of the filesystems; registered in the root container. */
12
+ export declare class FsResourceAdapter extends ResourceAdapter<FsResourceTarget> {
13
+ protected readonly container: IContainer;
14
+ readonly kind = "fs";
15
+ readonly types: readonly ResourceType[];
16
+ /** Where the published fs providers and the Configuration are looked up. */
17
+ constructor(container?: IContainer);
18
+ accepts(target: unknown): target is FsResourceTarget;
19
+ refOf(target: FsResourceTarget): ResourceRef;
20
+ /** Does not know which filesystems exist, so an fs name with no provider still gets a chain (it grants nothing). */
21
+ ancestors(ref: ResourceRef): Promise<readonly ResourceRef[] | null>;
22
+ /** The row AuthzFsMiddleware passes as the subject of every check, built without IO. */
23
+ load(ref: ResourceRef): Promise<FsRow | null>;
24
+ attribute(subject: unknown, field: string): unknown;
25
+ /**
26
+ * One FsAclRelation per fs type and `authz.fsAcl` relation: boot rule 8 needs a resolver for every relation a grant
27
+ * names, on every type of the permission, known at boot.
28
+ */
29
+ relations(): readonly RelationResolver[];
30
+ permissions(): readonly Omit<PermissionDef, 'source'>[];
31
+ protected basePathOf(fsName: string): string | undefined;
32
+ }
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC5B;AAID,kGAAkG;AAClG,qBACa,iBAAkB,SAAQ,eAAe,CAAC,gBAAgB,CAAC;IAK1D,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU;IAJpD,QAAQ,CAAC,IAAI,QAAQ;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAqB;IAE5D,4EAA4E;IAC5E,YAA+B,SAAS,GAAE,UAA6B,EAEtE;IAED,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,gBAAgB,CAMnD;IAED,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAG3C;IAED,oHAAoH;IAC9G,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC,CAExE;IAED,wFAAwF;IAClF,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAElD;IAED,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAElD;IAED;;;OAGG;IACH,SAAS,IAAI,SAAS,gBAAgB,EAAE,CAGvC;IAED,WAAW,IAAI,SAAS,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,CAEtD;IAGD,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGvD;CACF"}
@@ -0,0 +1,73 @@
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 { ResourceAdapter } from '@spinajs/authz';
11
+ import { DI, Injectable } from '@spinajs/di';
12
+ import { publishedFs } from '@spinajs/fs';
13
+ import { fsAclConfig } from '../access-config/index.js';
14
+ import { FsAclRelation } from '../acl/relation.js';
15
+ import { FS_PERMISSIONS } from '../permissions/index.js';
16
+ import { FS_RESOURCE_TYPES, fsAncestors, fsRef, fsRow, normalizeFsPath } from '../refs/index.js';
17
+ const isKind = (v) => v === 'file' || v === 'dir';
18
+ /** Refs, ancestors, rows and permissions of the filesystems; registered in the root container. */
19
+ let FsResourceAdapter = class FsResourceAdapter extends ResourceAdapter {
20
+ /** Where the published fs providers and the Configuration are looked up. */
21
+ constructor(container = DI.RootContainer) {
22
+ super();
23
+ this.container = container;
24
+ this.kind = 'fs';
25
+ this.types = FS_RESOURCE_TYPES;
26
+ }
27
+ accepts(target) {
28
+ if (target === null || typeof target !== 'object')
29
+ return false;
30
+ const proto = Object.getPrototypeOf(target);
31
+ if (proto !== Object.prototype && proto !== null)
32
+ return false;
33
+ const t = target;
34
+ return typeof t.fs === 'string' && typeof t.path === 'string' && (t.kind === undefined || isKind(t.kind));
35
+ }
36
+ refOf(target) {
37
+ const type = target.type;
38
+ return fsRef(target.fs, normalizeFsPath(target.path, this.basePathOf(target.fs)), target.kind ?? (type === 'dir' ? 'dir' : 'file'));
39
+ }
40
+ /** Does not know which filesystems exist, so an fs name with no provider still gets a chain (it grants nothing). */
41
+ async ancestors(ref) {
42
+ return fsAncestors(ref);
43
+ }
44
+ /** The row AuthzFsMiddleware passes as the subject of every check, built without IO. */
45
+ async load(ref) {
46
+ return fsRow(ref);
47
+ }
48
+ attribute(subject, field) {
49
+ return subject !== null && typeof subject === 'object' && Object.hasOwn(subject, field) ? subject[field] : undefined;
50
+ }
51
+ /**
52
+ * One FsAclRelation per fs type and `authz.fsAcl` relation: boot rule 8 needs a resolver for every relation a grant
53
+ * names, on every type of the permission, known at boot.
54
+ */
55
+ relations() {
56
+ const { relations } = fsAclConfig(this.container);
57
+ return Object.freeze(FS_RESOURCE_TYPES.flatMap((type) => relations.map((relation) => new FsAclRelation(type, relation, this.container))));
58
+ }
59
+ permissions() {
60
+ return FS_PERMISSIONS;
61
+ }
62
+ // Read from the published provider, so refOf does no IO.
63
+ basePathOf(fsName) {
64
+ const basePath = publishedFs(fsName, this.container)?.BasePath;
65
+ return typeof basePath === 'string' && basePath !== '' ? basePath : undefined;
66
+ }
67
+ };
68
+ FsResourceAdapter = __decorate([
69
+ Injectable(ResourceAdapter),
70
+ __metadata("design:paramtypes", [Object])
71
+ ], FsResourceAdapter);
72
+ export { FsResourceAdapter };
73
+ //# sourceMappingURL=index.js.map