@docstack/client 0.0.1 → 0.0.3

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 (60) hide show
  1. package/lib/core/attribute.d.ts +4 -4
  2. package/lib/core/class.d.ts +13 -12
  3. package/lib/core/crypto-engine/index.d.ts +5 -5
  4. package/lib/core/query-engine/executor.d.ts +1 -1
  5. package/lib/core/query-engine/index.d.ts +3 -3
  6. package/lib/core/stack.d.ts +6 -6
  7. package/lib/index.d.ts +1 -1
  8. package/lib/index.js +7530 -7536
  9. package/lib/index.js.map +1 -1
  10. package/lib/index.umd.js +8256 -0
  11. package/lib/utils/index.d.ts +1 -1
  12. package/package.json +11 -4
  13. package/lib/core/attribute.js +0 -296
  14. package/lib/core/attribute.js.map +0 -1
  15. package/lib/core/class.js +0 -540
  16. package/lib/core/class.js.map +0 -1
  17. package/lib/core/crypto-engine/index.js +0 -130
  18. package/lib/core/crypto-engine/index.js.map +0 -1
  19. package/lib/core/crypto-engine/utils.js +0 -76
  20. package/lib/core/crypto-engine/utils.js.map +0 -1
  21. package/lib/core/datamodel/index.js +0 -1186
  22. package/lib/core/datamodel/index.js.map +0 -1
  23. package/lib/core/domain.js +0 -285
  24. package/lib/core/domain.js.map +0 -1
  25. package/lib/core/index.js +0 -379
  26. package/lib/core/index.js.map +0 -1
  27. package/lib/core/job-engine/index.js +0 -116
  28. package/lib/core/job-engine/index.js.map +0 -1
  29. package/lib/core/policy-engine/index.js +0 -150
  30. package/lib/core/policy-engine/index.js.map +0 -1
  31. package/lib/core/query-engine/accumulators.js +0 -258
  32. package/lib/core/query-engine/accumulators.js.map +0 -1
  33. package/lib/core/query-engine/evaluator.js +0 -179
  34. package/lib/core/query-engine/evaluator.js.map +0 -1
  35. package/lib/core/query-engine/executor.js +0 -405
  36. package/lib/core/query-engine/executor.js.map +0 -1
  37. package/lib/core/query-engine/index.js +0 -4
  38. package/lib/core/query-engine/index.js.map +0 -1
  39. package/lib/core/query-engine/parser.js +0 -515
  40. package/lib/core/query-engine/parser.js.map +0 -1
  41. package/lib/core/query-engine/planner.js +0 -330
  42. package/lib/core/query-engine/planner.js.map +0 -1
  43. package/lib/core/stack.js +0 -1507
  44. package/lib/core/stack.js.map +0 -1
  45. package/lib/core/test-utils/docstack.js +0 -222
  46. package/lib/core/test-utils/docstack.js.map +0 -1
  47. package/lib/core/trigger/index.js +0 -81
  48. package/lib/core/trigger/index.js.map +0 -1
  49. package/lib/plugins/pouchdb.js +0 -403
  50. package/lib/plugins/pouchdb.js.map +0 -1
  51. package/lib/utils/crypto/index.js +0 -34
  52. package/lib/utils/crypto/index.js.map +0 -1
  53. package/lib/utils/index.js +0 -58
  54. package/lib/utils/index.js.map +0 -1
  55. package/lib/utils/logger/index.js +0 -20
  56. package/lib/utils/logger/index.js.map +0 -1
  57. package/lib/utils/logger/transport.js +0 -28
  58. package/lib/utils/logger/transport.js.map +0 -1
  59. package/lib/workers/dataModel.js +0 -48
  60. package/lib/workers/dataModel.js.map +0 -1
package/lib/core/index.js DELETED
@@ -1,379 +0,0 @@
1
- // import express, {Express} from 'express'
2
- // import { static as exStatic } from 'express';
3
- // import * as dotenv from "dotenv";
4
- // import cors from "cors";
5
- // dotenv.config({ path: './.env' })
6
- import createlogger from "../utils/logger/index";
7
- // import test from '../../../server/src//utils/dbManager/test';
8
- // import { generateJwtKeys, generatePswKeys } from '../../../server/src/utils/crypto';
9
- import ClientStack from './stack';
10
- // import { login, JWTAuthPayload, setupAdminUser } from '../../../server/src//utils/auth';
11
- // import memoryAdapter from "pouchdb-adapter-memory"
12
- // import cookieParser from 'cookie-parser';
13
- // import jwt from 'jsonwebtoken';
14
- import Class from "./class";
15
- import Domain from './domain';
16
- import { Trigger } from "./trigger/index";
17
- import { JobEngine } from "./job-engine/index";
18
- // import AbstractClass from '../../shared/src//utils/stack/class';
19
- import Attribute from './attribute';
20
- // import { EventTarget } from 'node:events';
21
- // let envPath = process.env.ENVFILE || "./.env";
22
- // envPath = resolve(process.cwd(), envPath);
23
- // dotenv.config({ path: envPath });
24
- // [TODO] Implement DocStack.type in "remote" | "local"
25
- // When is remote, open a websocket (socket.io) connection to given remote
26
- // implement cases in each of stack methods (queries and doc creation)
27
- // to actually send and receive messages
28
- // [TODO][HARD] Think about authentication mechanism
29
- // Probably support same rest authentication (jwtToken)
30
- // but also api tokens
31
- // Remote connection that require auth can be opened but
32
- // cannot send or receive messages until authentication
33
- class DocStack extends EventTarget {
34
- async addStack(config) {
35
- let stack;
36
- if (typeof config == "object" && config.name) {
37
- stack = await ClientStack.create(`db-${config.name}`, {
38
- // defaults to leveldb
39
- // adapter: 'memory',
40
- plugins: [
41
- // https://www.npmjs.com/package/pouchdb-adapter-memory
42
- // memoryAdapter
43
- ],
44
- patches: config.patches,
45
- credentials: config.credentials,
46
- disableCryptoEngine: config.disableCryptoEngine,
47
- });
48
- }
49
- else if (typeof config === "string") {
50
- stack = await ClientStack.create(`db-${config}`, {
51
- // defaults to leveldb
52
- // adapter: 'memory',
53
- plugins: [
54
- // https://www.npmjs.com/package/pouchdb-adapter-memory
55
- // memoryAdapter
56
- ]
57
- });
58
- }
59
- if (stack) {
60
- this.stacks.push(stack);
61
- // let window_ = window as Window & typeof globalThis & {
62
- // stacks: ClientStack[]
63
- // }
64
- // if (window_.stacks) {
65
- // window_.stacks.push(stack)
66
- // }
67
- return stack;
68
- }
69
- // await setupAdminUser();
70
- }
71
- async resetAll() {
72
- try {
73
- for (const stack of this.stacks) {
74
- await stack.reset();
75
- }
76
- }
77
- catch (e) {
78
- throw new Error(e);
79
- }
80
- }
81
- getStacks() {
82
- return this.stacks;
83
- }
84
- async authenticateStack(name, credentials) {
85
- const stack = this.getStack(name);
86
- if (!stack) {
87
- throw new Error(`Stack '${name}' not found`);
88
- }
89
- return stack.authenticate(credentials);
90
- }
91
- getReadyState() {
92
- return this.readyState;
93
- }
94
- async reset() {
95
- try {
96
- await this.resetAll();
97
- await this.initStacks(this.config);
98
- }
99
- catch (e) {
100
- throw new Error(e);
101
- }
102
- }
103
- constructor(...config) {
104
- super();
105
- //private app: Express;
106
- // private dbName: string;
107
- this.config = [];
108
- this.stacks = [];
109
- this.logger = createlogger().child({ module: "client" });
110
- this.initStacks = async (configs) => {
111
- // TODO: Consider changing to Promise.all for concurrency
112
- for (const config of configs) {
113
- const stack = await this.addStack(config);
114
- }
115
- this.readyState = true;
116
- this.dispatchEvent(new CustomEvent("ready", {
117
- detail: {
118
- stacks: this.stacks
119
- }
120
- }));
121
- };
122
- this.getStack = (name) => {
123
- return this.stacks.find(s => s.name == name || s.connection == name);
124
- };
125
- this.clearConnection = async (conn) => {
126
- const fnLogger = this.logger.child({ method: 'clearConnection' });
127
- try {
128
- // const conn = req.params.conn;
129
- if (!conn) {
130
- throw new Error("Connection name not provided");
131
- }
132
- await ClientStack.clear(conn);
133
- fnLogger.info('Internal database cleared');
134
- // return res.status(200).json({ success: true, message: 'Internal database cleared' });
135
- }
136
- catch (e) {
137
- throw new Error(e);
138
- // return res.status(500).json({ success: false, error: 'An error occurred' });
139
- }
140
- };
141
- this.export = async (stackName) => {
142
- const stack = this.getStack(stackName);
143
- if (stack) {
144
- const dump = await stack.dump();
145
- return dump;
146
- }
147
- else {
148
- throw new Error(`Did not find any stack for name '${stackName}'`);
149
- }
150
- };
151
- this.createClass = async (name, config) => {
152
- const fnLogger = this.logger.child({ method: 'createClass' });
153
- const { type, description } = config;
154
- fnLogger.info("Args", {
155
- name, config
156
- });
157
- try {
158
- const newClass = await Class.create(this.store, name, "class", description, {});
159
- fnLogger.info(`class '${name}' created successfully.`, { classModel: newClass.getModel() });
160
- }
161
- catch (e) {
162
- throw new Error(`Error during class '${name} creation. ${e}`);
163
- }
164
- fnLogger.info('Class created successfully');
165
- };
166
- this.createAttribute = async (className, params) => {
167
- const fnLogger = this.logger.child({ method: 'createAttribute' });
168
- const { name, type, description, config } = params;
169
- fnLogger.info(`Creating attribute for class '${className}'`, {
170
- name, type, config
171
- });
172
- try {
173
- // Loads the class object
174
- let classObj = await this.store.getClass(className);
175
- if (classObj) {
176
- let newAttribute = await Attribute.create(classObj, name, type, description, config);
177
- fnLogger.info(`Attribute '${name}' added to class '${className}'`, { attributeModel: newAttribute.getModel() });
178
- }
179
- else {
180
- throw new Error(`Failed to retrieve Class '${className}'`);
181
- }
182
- }
183
- catch (e) {
184
- fnLogger.error(`Error during attribute '${name}' creation: ${e}`);
185
- throw new Error(`Error during attribute '${name}' creation: ${e}`);
186
- }
187
- };
188
- //this.dbName = (config && config.dbName) ? config.dbName : "docstack";
189
- // this.app = express();
190
- this.readyState = false;
191
- const fnLogger = this.logger.child({ method: "constructor" });
192
- /*
193
- this.app.use(logRequest)
194
- // Enable CORS for all routes
195
- if (process.env.NODE_ENV === 'development') {
196
- logger.info("Development environment. Enabling CORS for :8080");
197
- this.app.use(cors({
198
- origin: 'http://localhost:8080',
199
- // Replace with the origin of webpack dev server
200
- methods: ['GET', 'POST'],
201
- credentials: true,
202
- }));
203
- }
204
- */
205
- /*
206
- // Use built-in middleware for parsing JSON and URL-encoded data
207
- this.app.use(express.json());
208
- this.app.use(express.urlencoded({ extended: true }));
209
- this.app.use(cookieParser());
210
- this.app.use((req, res, next) => {
211
- if (!this.readyState) {
212
- return res.status(503); // Service Unavailable.
213
- }
214
- // Server is ready to receive requests
215
- next()
216
- })
217
- */
218
- /*
219
- this.app.use('/api/private', (req, res, next) => {
220
- const token = req.cookies.jwtToken
221
- if (!token) {
222
- logger.error("No token provided")
223
- return res.status(403).json({
224
- success: false,
225
- message: 'No token provided',
226
- });
227
- }
228
- const secretKey = process.env.JWT_PUBLIC_KEY;
229
- if (!secretKey || secretKey === '') {
230
- logger.error("No secret key found")
231
- return res.status(500).json({
232
- success: false,
233
- message: 'No secret key found',
234
- });
235
- }
236
- jwt.verify(token, secretKey, async (err, payload: JWTAuthPayload) => {
237
- if (err) {
238
- logger.error("Invalid token", err)
239
- return res.status(403).json({
240
- success: false,
241
- message: 'Invalid token',
242
- });
243
- } else {
244
- // Check whether the session is still valid
245
- const { sessionId } = payload;
246
- const UserSessionClass = await this.store.getClass("UserSession");
247
- const sessionCards = await UserSessionClass.getCards({
248
- sessionId: { $eq: sessionId },
249
- sessionStatus: { $eq: "active" }
250
- }, null, 0, 1);
251
- if (sessionCards.length === 0) {
252
- return res.status(403).json({
253
- success: false,
254
- message: 'Session expired',
255
- });
256
- }
257
- // TODO: Consider passing the session card to the next middleware
258
- next();
259
- }
260
- });
261
- })
262
- */
263
- // TODO: Serve the dashboard to a specific route, i.e.: admin
264
- // this.app.use(exStatic('./dist'));
265
- // TODO: Serve the static files from the build folder
266
- // of the UI application
267
- // this.app.get('*', (req, res) => {
268
- // const templatePath = resolve(__dirname, './dist', 'index.html');
269
- // res.sendFile(templatePath);
270
- // });
271
- /*
272
- this.app.post('/login', async (req, res) => {
273
- try {
274
- const { username, password } = req.body;
275
- const { responseCode, body, token } = await login(username, password);
276
- // Append also the token to the response
277
- let cookieOptions = {}
278
- if (process.env.NODE_ENV === 'development') {
279
- cookieOptions = { sameSite: 'None', secure: true, maxAge: 1000 * 60 * 15 };
280
- logger.warn("Development mode: setting cookie options to SameSite=None; Secure=true for JWT token");
281
- } else cookieOptions = { sameSite: 'Strict', httpOnly: true, maxAge: 1000 * 60 * 15 };
282
-
283
- res.cookie('jwtToken', token, cookieOptions);
284
- return res.status(responseCode).json(body);
285
- } catch (error) {
286
- console.error("Error during login", error);
287
- return res.status(500).json({ success: false, error: 'An error occurred' });
288
- }
289
- });
290
- */
291
- /*
292
- this.app.get('/api/private/reset', async (req, res) => {
293
- try {
294
- await this.reset();
295
- return res.status(200).json({ success: true, message: 'Internal database reset' });
296
- } catch (e) {
297
- return res.status(500).json({ success: false, error: 'An error occurred' });
298
- }
299
- });
300
- */
301
- /*
302
- this.app.get('/api/private/clear:conn', async (req, res) => {
303
- try {
304
- const conn = req.params.conn;
305
- if (!conn) {
306
- throw new Error("Connection name not provided");
307
- }
308
- await ClientStack.clear(conn);
309
- return res.status(200).json({ success: true, message: 'Internal database cleared' });
310
- } catch (e) {
311
- logger.error("Error during database clear", e);
312
- return res.status(500).json({ success: false, error: 'An error occurred' });
313
- }
314
- });
315
- */
316
- /*
317
- this.app.get('/api/private/test', (req, res) => {
318
- return res.status(200).json({ message: 'Hello from the server! This is a private route' });
319
- });
320
- */
321
- /*
322
- this.app.post('/api/private/create-class/:name', async (req, res) => {
323
- const { name } = req.params;
324
- const { type, description } = req.query;
325
- logger.info("create-class - received request", {
326
- params: req.params,
327
- query: req.query
328
- })
329
-
330
- try {
331
- const newClass = await Class.create(
332
- this.store, name, type as string, description as string
333
- );
334
- logger.info("create-class", `class '${name}' created successfully.`,
335
- {classModel: newClass.getModel()}
336
- )
337
- } catch (e) {
338
- logger.error(`Error during class '${name} creation: ${e}`);
339
- return res.status(500).json({ success: false, error: 'An error occurred' });
340
- }
341
-
342
- return res.status(200).json({ success: true, message: 'Class created successfully' });
343
- })
344
- */
345
- /*
346
- this.app.put('/api/private/create-attribute/:name', async (req, res) => {
347
- const className = req.params.name;
348
- const { name, type, config } = req.body;
349
- logger.info(`create-attribute - for class '${className}'`, {
350
- name, type, config
351
- });
352
-
353
- try {
354
- // Loads the class object
355
- let classObj = await this.store.getClass(className);
356
- let newAttribute = await Attribute.create(classObj, name, type, config);
357
- logger.info(`create-attribute - Attribute '${name}' added to class '${className}'`,
358
- {attributeModel: newAttribute.getModel()}
359
- );
360
- } catch (e) {
361
- logger.error(`Error during attribute '${name}' creation: ${e}`)
362
- }
363
- })
364
- */
365
- // const port = process.env.SERVER_PORT || 5000;
366
- // const server = this.app.listen(port, () => logger.info(`Listening on port ${port}`));
367
- // Procedure that should run once only
368
- // can be considered "setup procedures"
369
- //generatePswKeys()
370
- // generateJwtKeys()
371
- // Server "startup procedures"
372
- // setTimeout(test, 1000)
373
- this.initStacks(config);
374
- this.addEventListener("ready", () => fnLogger.info("DocStack client successfully initialized"));
375
- }
376
- }
377
- export { ClientStack, Trigger, Class, Attribute, Domain, JobEngine };
378
- export { DocStack };
379
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
@@ -1,116 +0,0 @@
1
- import crypto from "crypto";
2
- const calculateHash = (content) => {
3
- return crypto.createHash("sha256").update(content).digest("hex");
4
- };
5
- const now = () => Date.now();
6
- export class Job {
7
- constructor(model, stack) {
8
- this.model = model;
9
- this.stack = stack;
10
- const computed = calculateHash(model.content);
11
- if (computed !== model.hash) {
12
- throw new Error(`Job content hash mismatch for ${model._id}`);
13
- }
14
- }
15
- hydrate() {
16
- return new Function("stack", "params", "job", `"use strict"; ${this.model.content}; return execute(stack, params, job);`);
17
- }
18
- async hasRunningInstance() {
19
- var _a;
20
- if (!this.model.isSingleton)
21
- return false;
22
- const existingRuns = await this.stack.db.find({
23
- selector: {
24
- "~class": "~JobRun",
25
- jobId: this.model._id,
26
- status: "RUNNING",
27
- },
28
- limit: 1,
29
- });
30
- return Boolean((_a = existingRuns === null || existingRuns === void 0 ? void 0 : existingRuns.docs) === null || _a === void 0 ? void 0 : _a.length);
31
- }
32
- buildRun(triggerType, runtimeArgs) {
33
- const id = `JobRun-${crypto.randomUUID ? crypto.randomUUID() : crypto.randomBytes(16).toString("hex")}`;
34
- const base = {
35
- _id: id,
36
- "~class": "~JobRun",
37
- jobId: this.model._id,
38
- status: "PENDING",
39
- triggerType,
40
- startTime: now(),
41
- runtimeArgs,
42
- initialMetadata: this.model.metadata ? Object.assign({}, this.model.metadata) : undefined,
43
- };
44
- return base;
45
- }
46
- async persistRun(run) {
47
- const existing = await this.stack.db.get(run._id).catch(() => null);
48
- const doc = existing ? Object.assign(Object.assign({}, run), { _rev: existing._rev }) : run;
49
- await this.stack.db.bulkDocs([doc]);
50
- return doc;
51
- }
52
- async persistJobMetadata(metadata) {
53
- if (!metadata)
54
- return;
55
- const current = await this.stack.db.get(this.model._id).catch(() => null);
56
- const nextDoc = Object.assign(Object.assign({}, this.model), { _rev: current === null || current === void 0 ? void 0 : current._rev, metadata });
57
- await this.stack.db.bulkDocs([nextDoc]);
58
- }
59
- async execute(runtimeArgs, triggerType = "manual") {
60
- let run = this.buildRun(triggerType, runtimeArgs);
61
- run = await this.persistRun(run);
62
- if (!this.model.isEnabled) {
63
- run.status = "SKIPPED";
64
- run.errorMessage = `Job ${this.model._id} is disabled`;
65
- run.endTime = now();
66
- run.durationMs = run.endTime - run.startTime;
67
- await this.persistRun(run);
68
- throw new Error(run.errorMessage);
69
- }
70
- if (await this.hasRunningInstance()) {
71
- run.status = "SKIPPED";
72
- run.errorMessage = `Job ${this.model._id} already has a running instance`;
73
- run.endTime = now();
74
- run.durationMs = run.endTime - run.startTime;
75
- await this.persistRun(run);
76
- throw new Error(run.errorMessage);
77
- }
78
- try {
79
- run.status = "RUNNING";
80
- run.startTime = now();
81
- run = await this.persistRun(run);
82
- const executor = this.hydrate();
83
- const params = Object.assign(Object.assign({}, (this.model.defaultParams || {})), (runtimeArgs || {}));
84
- const result = await executor(this.stack, params, this.model);
85
- const finalMetadata = (result && result.metadata) || this.model.metadata;
86
- if (finalMetadata) {
87
- run.finalMetadata = finalMetadata;
88
- this.model.metadata = finalMetadata;
89
- await this.persistJobMetadata(finalMetadata);
90
- }
91
- run.status = "SUCCESS";
92
- run.endTime = now();
93
- run.durationMs = run.endTime - run.startTime;
94
- return await this.persistRun(run);
95
- }
96
- catch (error) {
97
- run.status = "FAILURE";
98
- run.errorMessage = (error === null || error === void 0 ? void 0 : error.message) || String(error);
99
- run.errorStack = error === null || error === void 0 ? void 0 : error.stack;
100
- run.endTime = now();
101
- run.durationMs = run.endTime - run.startTime;
102
- return await this.persistRun(run);
103
- }
104
- }
105
- }
106
- export class JobEngine {
107
- constructor(stack) {
108
- this.stack = stack;
109
- }
110
- async executeJob(jobId, runtimeArgs, triggerType = "manual") {
111
- const jobDoc = await this.stack.db.get(jobId);
112
- const job = new Job(jobDoc, this.stack);
113
- return job.execute(runtimeArgs, triggerType);
114
- }
115
- }
116
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/job-engine/index.ts"],"names":[],"mappings":"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"}
@@ -1,150 +0,0 @@
1
- const SYSTEM_CLASSES = new Set([
2
- "~Policy",
3
- "~Job",
4
- "~JobRun",
5
- "~AuthModule",
6
- "~UserSession",
7
- "class",
8
- "domain"
9
- ]);
10
- export class PolicyEngine {
11
- constructor(stack) {
12
- this.stack = stack;
13
- }
14
- getSessionProof() {
15
- return this.stack.authSession;
16
- }
17
- shouldBypass(targetClass) {
18
- if (SYSTEM_CLASSES.has(targetClass))
19
- return true;
20
- const normalized = targetClass.startsWith("~") ? targetClass.slice(1) : `~${targetClass}`;
21
- return SYSTEM_CLASSES.has(normalized);
22
- }
23
- async loadPolicies(targetClass, aliases = []) {
24
- const identifiers = new Set([targetClass, ...aliases]);
25
- const result = await this.stack.findDocuments({ "~class": "~Policy" });
26
- return result.docs.filter((doc) => {
27
- if (!Array.isArray(doc.targetClass))
28
- return false;
29
- return doc.targetClass.some((entry) => identifiers.has(entry));
30
- });
31
- }
32
- getTargetIdentifiers(targetId, targetName) {
33
- const identifiers = new Set();
34
- const variants = [targetId, targetName];
35
- for (const value of variants) {
36
- identifiers.add(value);
37
- if (value.startsWith("~")) {
38
- identifiers.add(value.slice(1));
39
- }
40
- else {
41
- identifiers.add(`~${value}`);
42
- }
43
- }
44
- return Array.from(identifiers);
45
- }
46
- async resolveClassTarget(targetClass) {
47
- var _a, _b;
48
- const classModel = await this.stack.getClassModel(targetClass).catch(() => null);
49
- return {
50
- id: (_a = classModel === null || classModel === void 0 ? void 0 : classModel._id) !== null && _a !== void 0 ? _a : targetClass,
51
- name: (_b = classModel === null || classModel === void 0 ? void 0 : classModel.name) !== null && _b !== void 0 ? _b : targetClass,
52
- };
53
- }
54
- async evaluateRule(policy, document, session) {
55
- const executor = new Function("document", "session", "groupId", `"use strict"; ${policy.rule}`);
56
- const result = executor(document || {}, session.session, session.session.groupId);
57
- if (result instanceof Promise) {
58
- return Boolean(await result);
59
- }
60
- return Boolean(result);
61
- }
62
- filterPoliciesForSession(policies, session) {
63
- const sessionUserId = session.session.userId || session.session.username;
64
- const sessionGroups = Array.isArray(session.session.groupId)
65
- ? session.session.groupId
66
- : session.session.groupId
67
- ? [session.session.groupId]
68
- : [];
69
- return policies.filter((policy) => {
70
- const matchesUser = !policy.userId || policy.userId === sessionUserId || policy.userId === session.session.username;
71
- const matchesGroup = !policy.groupId || sessionGroups.includes(policy.groupId);
72
- return matchesUser && matchesGroup;
73
- });
74
- }
75
- async authorize(targetClass, operation, document) {
76
- const { id: targetId, name: targetName } = await this.resolveClassTarget(targetClass);
77
- const identifiers = this.getTargetIdentifiers(targetId, targetName);
78
- if (this.shouldBypass(targetName)) {
79
- return true;
80
- }
81
- const policies = await this.loadPolicies(targetId, identifiers);
82
- if (policies.length === 0) {
83
- return true;
84
- }
85
- const session = this.getSessionProof();
86
- if (!session) {
87
- throw new Error("Stack is not authenticated for policy evaluation");
88
- }
89
- const targetedPolicies = policies.filter((policy) => policy.userId || policy.groupId);
90
- const basePolicies = policies.filter((policy) => !policy.userId && !policy.groupId);
91
- const matchingPolicies = targetedPolicies.length > 0
92
- ? this.filterPoliciesForSession(targetedPolicies, session)
93
- : this.filterPoliciesForSession(basePolicies, session);
94
- if (targetedPolicies.length > 0 && matchingPolicies.length === 0) {
95
- throw new Error(`No matching policy allowed ${operation} on class '${targetClass}'`);
96
- }
97
- let allowed = false;
98
- for (const policy of matchingPolicies) {
99
- const result = await this.evaluateRule(policy, document, session);
100
- if (result === false) {
101
- throw new Error(`Policy '${policy._id}' denied ${operation} on class '${targetClass}'`);
102
- }
103
- if (result === true) {
104
- allowed = true;
105
- }
106
- }
107
- return allowed;
108
- }
109
- async ensureWriteAllowed(targetClass, document) {
110
- const allowed = await this.authorize(targetClass, "write", document);
111
- if (!allowed) {
112
- throw new Error(`No matching policy allowed write on class '${targetClass}'`);
113
- }
114
- }
115
- async isReadableDocument(document) {
116
- const targetClass = document === null || document === void 0 ? void 0 : document["~class"];
117
- const { id: targetId, name: targetName } = await this.resolveClassTarget(targetClass);
118
- if (!targetClass || this.shouldBypass(targetName)) {
119
- return true;
120
- }
121
- const policies = await this.loadPolicies(targetId, this.getTargetIdentifiers(targetId, targetName));
122
- if (policies.length === 0) {
123
- return true;
124
- }
125
- const session = this.getSessionProof();
126
- if (!session) {
127
- throw new Error("Stack is not authenticated for policy evaluation");
128
- }
129
- const targetedPolicies = policies.filter((policy) => policy.userId || policy.groupId);
130
- const basePolicies = policies.filter((policy) => !policy.userId && !policy.groupId);
131
- const matchingPolicies = targetedPolicies.length > 0
132
- ? this.filterPoliciesForSession(targetedPolicies, session)
133
- : this.filterPoliciesForSession(basePolicies, session);
134
- if (targetedPolicies.length > 0 && matchingPolicies.length === 0) {
135
- return false;
136
- }
137
- let permitted = false;
138
- for (const policy of matchingPolicies) {
139
- const result = await this.evaluateRule(policy, document, session);
140
- if (result === false) {
141
- return false;
142
- }
143
- if (result === true) {
144
- permitted = true;
145
- }
146
- }
147
- return permitted;
148
- }
149
- }
150
- //# sourceMappingURL=index.js.map