@rebasepro/server-mongo 0.13.0 → 0.13.1-canary.g06dbe5b

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 (35) hide show
  1. package/dist/MongoBootstrapper.d.ts.map +1 -1
  2. package/dist/auth/ensure-collections.d.ts.map +1 -1
  3. package/dist/db/MongoConditionBuilder.d.ts +28 -1
  4. package/dist/db/MongoConditionBuilder.d.ts.map +1 -1
  5. package/dist/db/MongoDataService.d.ts +19 -1
  6. package/dist/db/MongoDataService.d.ts.map +1 -1
  7. package/dist/db/securityRuleFilter.d.ts +65 -0
  8. package/dist/db/securityRuleFilter.d.ts.map +1 -0
  9. package/dist/ensure-collections-Bl12bSwO.js +130 -0
  10. package/dist/ensure-collections-Bl12bSwO.js.map +1 -0
  11. package/dist/factory.d.ts +11 -1
  12. package/dist/factory.d.ts.map +1 -1
  13. package/dist/index.es.js +487 -249
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/services/MongoDriver.d.ts +37 -5
  16. package/dist/services/MongoDriver.d.ts.map +1 -1
  17. package/dist/services/MongoRealtimeService.d.ts +23 -14
  18. package/dist/services/MongoRealtimeService.d.ts.map +1 -1
  19. package/dist/{websocket-74DDOdK0.js → websocket-Bs54-gR-.js} +32 -11
  20. package/dist/websocket-Bs54-gR-.js.map +1 -0
  21. package/dist/websocket.d.ts +2 -2
  22. package/dist/websocket.d.ts.map +1 -1
  23. package/package.json +5 -5
  24. package/src/MongoBootstrapper.ts +10 -2
  25. package/src/auth/ensure-collections.ts +61 -13
  26. package/src/db/MongoConditionBuilder.ts +112 -40
  27. package/src/db/MongoDataService.ts +51 -14
  28. package/src/db/securityRuleFilter.ts +398 -0
  29. package/src/factory.ts +17 -4
  30. package/src/services/MongoDriver.ts +101 -262
  31. package/src/services/MongoRealtimeService.ts +124 -66
  32. package/src/websocket.ts +66 -15
  33. package/dist/ensure-collections-Bkx_O5CQ.js +0 -94
  34. package/dist/ensure-collections-Bkx_O5CQ.js.map +0 -1
  35. package/dist/websocket-74DDOdK0.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"MongoBootstrapper.d.ts","sourceRoot":"","sources":["../src/MongoBootstrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EACR,mBAAmB,EAQtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAIpD,MAAM,WAAW,iBAAiB;IAC9B,UAAU,EAAE,EAAE,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,uBAAuB,CAAC;IAClC,eAAe,EAAE,oBAAoB,CAAC;IACtC,MAAM,EAAE,WAAW,CAAC;CACvB;AAcD,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,iBAAiB,GAAG,mBAAmB,CAyJ3F"}
1
+ {"version":3,"file":"MongoBootstrapper.d.ts","sourceRoot":"","sources":["../src/MongoBootstrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAER,mBAAmB,EAQtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAIpD,MAAM,WAAW,iBAAiB;IAC9B,UAAU,EAAE,EAAE,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,uBAAuB,CAAC;IAClC,eAAe,EAAE,oBAAoB,CAAC;IACtC,MAAM,EAAE,WAAW,CAAC;CACvB;AAcD,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,iBAAiB,GAAG,mBAAmB,CAgK3F"}
@@ -1 +1 @@
1
- {"version":3,"file":"ensure-collections.d.ts","sourceRoot":"","sources":["../../src/auth/ensure-collections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AA0C7B,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCtE"}
1
+ {"version":3,"file":"ensure-collections.d.ts","sourceRoot":"","sources":["../../src/auth/ensure-collections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAiE7B,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDtE"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Translates Rebase filter conditions to MongoDB query operators.
5
5
  */
6
- import { CollectionConfig, FilterValues } from "@rebasepro/types";
6
+ import { CollectionConfig, FilterValues, LogicalCondition } from "@rebasepro/types";
7
7
  import { Filter, Document } from "mongodb";
8
8
  /**
9
9
  * MongoDB Condition Builder
@@ -19,6 +19,26 @@ export declare class MongoConditionBuilder {
19
19
  * @returns Array of MongoDB filter objects
20
20
  */
21
21
  static buildFilterConditions<M extends Record<string, any>>(filter: FilterValues<Extract<keyof M, string>>): Filter<Document>[];
22
+ /**
23
+ * One field, one operator, one value.
24
+ *
25
+ * Extracted so that `logical` groups translate through exactly this code.
26
+ * A group written as a second dialect is a group where `array-contains` or
27
+ * `ilike` quietly means something else than it does in `filter`, which is
28
+ * the kind of difference nobody finds until a query returns the wrong rows.
29
+ *
30
+ * Always returns a condition or throws: there is no operator this can be
31
+ * given that legitimately means "no condition".
32
+ */
33
+ private static buildCondition;
34
+ /**
35
+ * Translate an `or(...)` / `and(...)` group, nesting included.
36
+ *
37
+ * Returns `undefined` for a group with nothing in it. `$or: []` is an error
38
+ * in Mongo and `$and: []` matches every document, so neither is a
39
+ * defensible reading of "no conditions".
40
+ */
41
+ static buildLogicalConditions(logical: LogicalCondition | undefined): Filter<Document> | undefined;
22
42
  /**
23
43
  * Build search conditions for text search
24
44
  *
@@ -49,6 +69,13 @@ export declare class MongoConditionBuilder {
49
69
  */
50
70
  static buildQuery<M extends Record<string, any>>(options: {
51
71
  filter?: FilterValues<Extract<keyof M, string>>;
72
+ /**
73
+ * An `or(...)`/`and(...)` group, AND-ed with `filter` and
74
+ * `searchString` — the three are independent, as `FindParams`
75
+ * documents. Absent here until now, so a group that reached this
76
+ * driver was dropped and the read ran unfiltered.
77
+ */
78
+ logical?: LogicalCondition;
52
79
  searchString?: string;
53
80
  properties?: CollectionConfig["properties"];
54
81
  }): Filter<Document>;
@@ -1 +1 @@
1
- {"version":3,"file":"MongoConditionBuilder.d.ts","sourceRoot":"","sources":["../../src/db/MongoConditionBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAiB,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAsC3C;;;;;GAKG;AACH,qBAAa,qBAAqB;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtD,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAC/C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAqDrB;;;;;;OAMG;IACH,MAAM,CAAC,qBAAqB,CACxB,YAAY,EAAE,MAAM,EAKpB,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GAC3C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAkCrB;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM7F;;;;;OAKG;IACH,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM5F;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QACtD,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KAC/C,GAAG,MAAM,CAAC,QAAQ,CAAC;IA2BpB;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CACZ,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GACvB,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;CAIxC"}
1
+ {"version":3,"file":"MongoConditionBuilder.d.ts","sourceRoot":"","sources":["../../src/db/MongoConditionBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAmB,YAAY,EAAE,gBAAgB,EAAiB,MAAM,kBAAkB,CAAC;AAEpH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkD3C;;;;;GAKG;AACH,qBAAa,qBAAqB;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtD,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAC/C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAqBrB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAwC7B;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAuBlG;;;;;;OAMG;IACH,MAAM,CAAC,qBAAqB,CACxB,YAAY,EAAE,MAAM,EAKpB,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,GAC3C,MAAM,CAAC,QAAQ,CAAC,EAAE;IAkCrB;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM7F;;;;;OAKG;IACH,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAM5F;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QACtD,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChD;;;;;WAKG;QACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KAC/C,GAAG,MAAM,CAAC,QAAQ,CAAC;IA8BpB;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CACZ,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GACvB,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;CAIxC"}
@@ -5,7 +5,7 @@
5
5
  * Provides all CRUD operations for rows.
6
6
  */
7
7
  import { Db, Document, Filter } from "mongodb";
8
- import { FilterValues, DataRepository, CollectionConfig } from "@rebasepro/types";
8
+ import { FilterValues, DataRepository, CollectionConfig, LogicalCondition } from "@rebasepro/types";
9
9
  /**
10
10
  * MongoDB Row Service
11
11
  *
@@ -52,9 +52,12 @@ export declare class MongoDataService implements DataRepository {
52
52
  */
53
53
  fetchCollection<M extends Record<string, any>>(collectionPath: string, options?: {
54
54
  filter?: FilterValues<Extract<keyof M, string>>;
55
+ /** An `or(...)`/`and(...)` group, AND-ed with `filter`. */
56
+ logical?: LogicalCondition;
55
57
  orderBy?: string;
56
58
  order?: "desc" | "asc";
57
59
  limit?: number;
60
+ offset?: number;
58
61
  startAfter?: any;
59
62
  searchString?: string;
60
63
  databaseId?: string;
@@ -78,13 +81,28 @@ export declare class MongoDataService implements DataRepository {
78
81
  */
79
82
  count<M extends Record<string, any>>(collectionPath: string, options?: {
80
83
  filter?: FilterValues<Extract<keyof M, string>>;
84
+ /** An `or(...)`/`and(...)` group, AND-ed with `filter`. */
85
+ logical?: LogicalCondition;
86
+ searchString?: string;
87
+ collection?: CollectionConfig;
81
88
  databaseId?: string;
82
89
  rawQuery?: Filter<Document>;
83
90
  }): Promise<number>;
84
91
  /**
85
92
  * Save an row (create or update)
93
+ *
94
+ * Returns the **stored** document, not the values that were sent. A partial
95
+ * update sends only the fields that changed, and returning those was a
96
+ * partial row everywhere it went: the REST response, `afterSave`, the
97
+ * history entry a revert restores from, and the row pushed to realtime
98
+ * subscribers. Postgres returns the whole row here (`RETURNING *`).
86
99
  */
87
100
  save<M extends Record<string, any>>(collectionPath: string, values: Partial<M>, id?: string | number, _databaseId?: string): Promise<Record<string, unknown>>;
101
+ /**
102
+ * Read the document back after a write, falling back to the caller's own
103
+ * values if it has already been removed by a concurrent delete.
104
+ */
105
+ private readBack;
88
106
  /**
89
107
  * Delete an row by ID
90
108
  */
@@ -1 +1 @@
1
- {"version":3,"file":"MongoDataService.d.ts","sourceRoot":"","sources":["../../src/db/MongoDataService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MongoDataService.d.ts","sourceRoot":"","sources":["../../src/db/MongoDataService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Row security for MongoDB.
3
+ *
4
+ * MongoDB has no RLS, so this driver enforces `securityRules` in-process. That
5
+ * makes the translation from a rule to a query the enforcement boundary, and it
6
+ * has exactly one safe failure mode: refuse.
7
+ *
8
+ * Two properties this file exists to hold:
9
+ *
10
+ * 1. **One predicate, one implementation.** The rules are compiled through the
11
+ * same {@link securityRuleToConditions} the Postgres DDL generator and the
12
+ * admin UI's `checkOperation` use, so "what does this rule mean" is answered
13
+ * in one place. The previous translator re-parsed the raw SQL itself and
14
+ * recognised four shapes — a second, smaller parser that disagreed with the
15
+ * first about the same rule.
16
+ * 2. **Fail closed, out loud.** An expression with no MongoDB equivalent (raw
17
+ * SQL, a membership subquery, a negated row predicate) used to become `{}` —
18
+ * "match every document". It now raises {@link SECURITY_RULE_UNSUPPORTED},
19
+ * the same shape the REST layer uses to refuse bulk writes this driver
20
+ * cannot perform: a request that cannot be authorized is not served.
21
+ */
22
+ import { Document, Filter } from "mongodb";
23
+ import { CollectionConfig, PolicyExpression, SecurityOperation, User } from "@rebasepro/types";
24
+ import { ApiError } from "@rebasepro/server";
25
+ /** The expression has no MongoDB equivalent — the caller must refuse. */
26
+ declare const UNTRANSLATABLE: "untranslatable";
27
+ type TranslationResult = Filter<Document> | typeof UNTRANSLATABLE;
28
+ /** The error code a caller sees when a rule cannot be honoured. */
29
+ export declare const SECURITY_RULE_UNSUPPORTED = "SECURITY_RULE_UNSUPPORTED";
30
+ /**
31
+ * The refusal. Names the collection, the clause and the expression, because the
32
+ * only useful thing an operator can do with this is rewrite that rule — or move
33
+ * the collection to an engine that can enforce it.
34
+ */
35
+ export declare function securityRuleUnsupported(collectionSlug: string, clause: "using" | "withCheck", detail: string): ApiError;
36
+ /**
37
+ * Translate one {@link PolicyExpression} into a MongoDB filter, or
38
+ * {@link UNTRANSLATABLE}.
39
+ *
40
+ * The JavaScript twin of `evaluatePolicy`, one level up: where that decides a
41
+ * single row, this narrows a query. `"unknown"` there and `UNTRANSLATABLE` here
42
+ * are the same condition, and both are resolved fail-closed by their callers.
43
+ */
44
+ export declare function policyToMongoFilter(expr: PolicyExpression, user: User | undefined): TranslationResult;
45
+ /**
46
+ * Refuse up front when this collection's rules cannot be enforced for
47
+ * `targetOperation`.
48
+ *
49
+ * The row-in-hand paths (`fetchOne`, `save`, `delete`) resolve an undecidable
50
+ * rule through `checkOperation`'s `onUnknown: "deny"`, which is safe but
51
+ * indistinguishable from a plain "you may not do that". Calling this first
52
+ * turns the same condition into the refusal an operator can act on.
53
+ */
54
+ export declare function assertSecurityRulesEnforceable(collection: CollectionConfig | undefined, targetOperation: SecurityOperation): void;
55
+ /**
56
+ * Build the MongoDB filter that narrows a query to the rows `user` may see
57
+ * under `collection`'s security rules.
58
+ *
59
+ * Returns `null` when no row can qualify (the caller answers with an empty
60
+ * result), `{}` when the rules impose no narrowing, and throws
61
+ * {@link SECURITY_RULE_UNSUPPORTED} when a rule cannot be translated.
62
+ */
63
+ export declare function buildMongoFilterFromSecurityRules<M extends Record<string, any>>(collection: CollectionConfig<M> | undefined, user: User | undefined, targetOperation: SecurityOperation): Filter<Document> | null;
64
+ export {};
65
+ //# sourceMappingURL=securityRuleFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityRuleFilter.d.ts","sourceRoot":"","sources":["../../src/db/securityRuleFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAEH,gBAAgB,EAChB,gBAAgB,EAEhB,iBAAiB,EAEjB,IAAI,EAEP,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAY7C,yEAAyE;AACzE,QAAA,MAAM,cAAc,EAAG,gBAAyB,CAAC;AAEjD,KAAK,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,OAAO,cAAc,CAAC;AAUlE,mEAAmE;AACnE,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE;;;;GAIG;AACH,wBAAgB,uBAAuB,CACnC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,GAAG,WAAW,EAC7B,MAAM,EAAE,MAAM,GACf,QAAQ,CAQV;AAoHD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,iBAAiB,CAuErG;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC1C,UAAU,EAAE,gBAAgB,GAAG,SAAS,EACxC,eAAe,EAAE,iBAAiB,GACnC,IAAI,CAiBN;AAED;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3E,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,EAC3C,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,eAAe,EAAE,iBAAiB,GACnC,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAqDzB"}
@@ -0,0 +1,130 @@
1
+ import { logger } from "@rebasepro/server";
2
+ //#region src/auth/ensure-collections.ts
3
+ /**
4
+ * Default roles to seed on first run
5
+ */
6
+ var DEFAULT_ROLES = [
7
+ {
8
+ _id: "admin",
9
+ id: "admin",
10
+ name: "Admin",
11
+ isAdmin: true,
12
+ defaultPermissions: {
13
+ read: true,
14
+ create: true,
15
+ edit: true,
16
+ delete: true
17
+ },
18
+ createdAt: /* @__PURE__ */ new Date()
19
+ },
20
+ {
21
+ _id: "editor",
22
+ id: "editor",
23
+ name: "Editor",
24
+ isAdmin: false,
25
+ defaultPermissions: {
26
+ read: true,
27
+ create: true,
28
+ edit: true,
29
+ delete: true
30
+ },
31
+ createdAt: /* @__PURE__ */ new Date()
32
+ },
33
+ {
34
+ _id: "viewer",
35
+ id: "viewer",
36
+ name: "Viewer",
37
+ isAdmin: false,
38
+ defaultPermissions: {
39
+ read: true,
40
+ create: false,
41
+ edit: false,
42
+ delete: false
43
+ },
44
+ createdAt: /* @__PURE__ */ new Date()
45
+ }
46
+ ];
47
+ /**
48
+ * Indexes created by releases up to 0.13.0, on snake_case field names the auth
49
+ * services never wrote.
50
+ *
51
+ * MongoDB indexes an absent field as `null`, so a unique index whose every key
52
+ * component is always missing admits exactly **one** document per collection:
53
+ * the second login on the whole deployment failed with `E11000`, as did the
54
+ * second role assignment and the second outstanding password-reset token.
55
+ * Dropping them is therefore part of the fix, not tidying — creating the
56
+ * correct index alongside a broken one leaves the deployment just as broken.
57
+ *
58
+ * `{user_id, user_agent, ip_address}` has a second reason to go: it is the
59
+ * reverted Postgres constraint. `MongoRefreshTokenService.createToken` explains
60
+ * why evicting by that triple signs a second browser out; the unique index
61
+ * expressing the same rule was left behind here.
62
+ */
63
+ var LEGACY_INDEX_NAMES = {
64
+ rebase_user_identities: ["provider_1_provider_id_1", "user_id_1"],
65
+ rebase_user_roles: ["user_id_1_role_id_1", "user_id_1"],
66
+ rebase_refresh_tokens: [
67
+ "token_hash_1",
68
+ "user_id_1_user_agent_1_ip_address_1",
69
+ "user_id_1"
70
+ ],
71
+ rebase_password_reset_tokens: ["token_hash_1", "user_id_1"]
72
+ };
73
+ async function ensureAuthCollectionsExist(db) {
74
+ logger.info("🔍 Checking MongoDB auth collections and indexes...");
75
+ try {
76
+ await dropLegacyIndexes(db);
77
+ const users = db.collection("rebase_users");
78
+ await users.createIndex({ email: 1 }, { unique: true });
79
+ await users.createIndex({ id: 1 });
80
+ const identities = db.collection("rebase_user_identities");
81
+ await identities.createIndex({
82
+ provider: 1,
83
+ providerId: 1
84
+ }, { unique: true });
85
+ await identities.createIndex({ uid: 1 });
86
+ const userRoles = db.collection("rebase_user_roles");
87
+ await userRoles.createIndex({
88
+ uid: 1,
89
+ roleId: 1
90
+ }, { unique: true });
91
+ await userRoles.createIndex({ roleId: 1 });
92
+ const refreshTokens = db.collection("rebase_refresh_tokens");
93
+ await refreshTokens.createIndex({ tokenHash: 1 }, { unique: true });
94
+ await refreshTokens.createIndex({ uid: 1 });
95
+ await refreshTokens.createIndex({ sessionId: 1 });
96
+ const resetTokens = db.collection("rebase_password_reset_tokens");
97
+ await resetTokens.createIndex({ tokenHash: 1 }, { unique: true });
98
+ await resetTokens.createIndex({ uid: 1 });
99
+ await seedDefaultRoles(db);
100
+ logger.info("✅ MongoDB Auth collections ready");
101
+ } catch (error) {
102
+ logger.error("❌ Failed to set up MongoDB auth collections", { error });
103
+ throw error;
104
+ }
105
+ }
106
+ /** Drop the indexes of {@link LEGACY_INDEX_NAMES} that this database still has. */
107
+ async function dropLegacyIndexes(db) {
108
+ for (const [collectionName, indexNames] of Object.entries(LEGACY_INDEX_NAMES)) {
109
+ const collection = db.collection(collectionName);
110
+ for (const indexName of indexNames) try {
111
+ await collection.dropIndex(indexName);
112
+ logger.info(`🧹 Dropped stale auth index ${collectionName}.${indexName}`);
113
+ } catch {}
114
+ }
115
+ }
116
+ async function seedDefaultRoles(db) {
117
+ const roles = db.collection("rebase_roles");
118
+ const count = await roles.countDocuments();
119
+ if (count > 0) {
120
+ logger.info(`📋 Found ${count} existing roles`);
121
+ return;
122
+ }
123
+ logger.info("🌱 Seeding default roles...");
124
+ for (const role of DEFAULT_ROLES) await roles.updateOne({ id: role.id }, { $setOnInsert: role }, { upsert: true });
125
+ logger.info("✅ Default roles created: admin, editor, viewer");
126
+ }
127
+ //#endregion
128
+ export { ensureAuthCollectionsExist };
129
+
130
+ //# sourceMappingURL=ensure-collections-Bl12bSwO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure-collections-Bl12bSwO.js","names":[],"sources":["../src/auth/ensure-collections.ts"],"sourcesContent":["import { Db } from \"mongodb\";\nimport { logger } from \"@rebasepro/server\";\n\n/**\n * Default roles to seed on first run\n */\nconst DEFAULT_ROLES = [\n {\n _id: \"admin\",\n id: \"admin\",\n name: \"Admin\",\n isAdmin: true,\n defaultPermissions: { read: true,\ncreate: true,\nedit: true,\ndelete: true },\n createdAt: new Date()\n },\n {\n _id: \"editor\",\n id: \"editor\",\n name: \"Editor\",\n isAdmin: false,\n defaultPermissions: { read: true,\ncreate: true,\nedit: true,\ndelete: true },\n createdAt: new Date()\n },\n {\n _id: \"viewer\",\n id: \"viewer\",\n name: \"Viewer\",\n isAdmin: false,\n defaultPermissions: { read: true,\ncreate: false,\nedit: false,\ndelete: false },\n createdAt: new Date()\n }\n];\n\n/**\n * Indexes created by releases up to 0.13.0, on snake_case field names the auth\n * services never wrote.\n *\n * MongoDB indexes an absent field as `null`, so a unique index whose every key\n * component is always missing admits exactly **one** document per collection:\n * the second login on the whole deployment failed with `E11000`, as did the\n * second role assignment and the second outstanding password-reset token.\n * Dropping them is therefore part of the fix, not tidying — creating the\n * correct index alongside a broken one leaves the deployment just as broken.\n *\n * `{user_id, user_agent, ip_address}` has a second reason to go: it is the\n * reverted Postgres constraint. `MongoRefreshTokenService.createToken` explains\n * why evicting by that triple signs a second browser out; the unique index\n * expressing the same rule was left behind here.\n */\nconst LEGACY_INDEX_NAMES: Record<string, string[]> = {\n rebase_user_identities: [\"provider_1_provider_id_1\", \"user_id_1\"],\n rebase_user_roles: [\"user_id_1_role_id_1\", \"user_id_1\"],\n rebase_refresh_tokens: [\"token_hash_1\", \"user_id_1_user_agent_1_ip_address_1\", \"user_id_1\"],\n rebase_password_reset_tokens: [\"token_hash_1\", \"user_id_1\"]\n};\n\nexport async function ensureAuthCollectionsExist(db: Db): Promise<void> {\n logger.info(\"🔍 Checking MongoDB auth collections and indexes...\");\n\n try {\n await dropLegacyIndexes(db);\n\n // Every key below is a field `auth/services.ts` actually writes —\n // camelCase, matching the documents. Verified by\n // `test/MongoAuthServices.test.ts`, which now runs this function.\n\n // Users\n const users = db.collection(\"rebase_users\");\n await users.createIndex({ email: 1 }, { unique: true });\n await users.createIndex({ id: 1 });\n\n // User Identities\n const identities = db.collection(\"rebase_user_identities\");\n await identities.createIndex({ provider: 1,\nproviderId: 1 }, { unique: true });\n await identities.createIndex({ uid: 1 });\n\n // User Roles (junction collection)\n const userRoles = db.collection(\"rebase_user_roles\");\n await userRoles.createIndex({ uid: 1,\nroleId: 1 }, { unique: true });\n await userRoles.createIndex({ roleId: 1 });\n\n // Refresh Tokens. No unique index on (uid, userAgent, ipAddress):\n // tokens of one sign-in accumulate under a shared sessionId.\n const refreshTokens = db.collection(\"rebase_refresh_tokens\");\n await refreshTokens.createIndex({ tokenHash: 1 }, { unique: true });\n await refreshTokens.createIndex({ uid: 1 });\n await refreshTokens.createIndex({ sessionId: 1 });\n\n // Password Reset Tokens\n const resetTokens = db.collection(\"rebase_password_reset_tokens\");\n await resetTokens.createIndex({ tokenHash: 1 }, { unique: true });\n await resetTokens.createIndex({ uid: 1 });\n\n // Seed roles\n await seedDefaultRoles(db);\n\n logger.info(\"✅ MongoDB Auth collections ready\");\n } catch (error) {\n // Not swallowed. Every index here is load-bearing for auth — a boot\n // that logs this and carries on is a deployment whose second login\n // fails, with a green boot log to say nothing is wrong.\n logger.error(\"❌ Failed to set up MongoDB auth collections\", { error: error });\n throw error;\n }\n}\n\n/** Drop the indexes of {@link LEGACY_INDEX_NAMES} that this database still has. */\nasync function dropLegacyIndexes(db: Db): Promise<void> {\n for (const [collectionName, indexNames] of Object.entries(LEGACY_INDEX_NAMES)) {\n const collection = db.collection(collectionName);\n for (const indexName of indexNames) {\n try {\n await collection.dropIndex(indexName);\n logger.info(`🧹 Dropped stale auth index ${collectionName}.${indexName}`);\n } catch {\n // NamespaceNotFound / IndexNotFound — nothing to drop here.\n }\n }\n }\n}\n\nasync function seedDefaultRoles(db: Db): Promise<void> {\n const roles = db.collection(\"rebase_roles\");\n const count = await roles.countDocuments();\n\n if (count > 0) {\n logger.info(`📋 Found ${count} existing roles`);\n return;\n }\n\n logger.info(\"🌱 Seeding default roles...\");\n\n for (const role of DEFAULT_ROLES) {\n await roles.updateOne(\n { id: role.id },\n { $setOnInsert: role },\n { upsert: true }\n );\n }\n\n logger.info(\"✅ Default roles created: admin, editor, viewer\");\n}\n"],"mappings":";;;;;AAMA,IAAM,gBAAgB;CAClB;EACI,KAAK;EACL,IAAI;EACJ,MAAM;EACN,SAAS;EACT,oBAAoB;GAAE,MAAM;GACpC,QAAQ;GACR,MAAM;GACN,QAAQ;EAAK;EACL,2BAAW,IAAI,KAAK;CACxB;CACA;EACI,KAAK;EACL,IAAI;EACJ,MAAM;EACN,SAAS;EACT,oBAAoB;GAAE,MAAM;GACpC,QAAQ;GACR,MAAM;GACN,QAAQ;EAAK;EACL,2BAAW,IAAI,KAAK;CACxB;CACA;EACI,KAAK;EACL,IAAI;EACJ,MAAM;EACN,SAAS;EACT,oBAAoB;GAAE,MAAM;GACpC,QAAQ;GACR,MAAM;GACN,QAAQ;EAAM;EACN,2BAAW,IAAI,KAAK;CACxB;AACJ;;;;;;;;;;;;;;;;;AAkBA,IAAM,qBAA+C;CACjD,wBAAwB,CAAC,4BAA4B,WAAW;CAChE,mBAAmB,CAAC,uBAAuB,WAAW;CACtD,uBAAuB;EAAC;EAAgB;EAAuC;CAAW;CAC1F,8BAA8B,CAAC,gBAAgB,WAAW;AAC9D;AAEA,eAAsB,2BAA2B,IAAuB;CACpE,OAAO,KAAK,qDAAqD;CAEjE,IAAI;EACA,MAAM,kBAAkB,EAAE;EAO1B,MAAM,QAAQ,GAAG,WAAW,cAAc;EAC1C,MAAM,MAAM,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,CAAC;EACtD,MAAM,MAAM,YAAY,EAAE,IAAI,EAAE,CAAC;EAGjC,MAAM,aAAa,GAAG,WAAW,wBAAwB;EACzD,MAAM,WAAW,YAAY;GAAE,UAAU;GACjD,YAAY;EAAE,GAAG,EAAE,QAAQ,KAAK,CAAC;EACzB,MAAM,WAAW,YAAY,EAAE,KAAK,EAAE,CAAC;EAGvC,MAAM,YAAY,GAAG,WAAW,mBAAmB;EACnD,MAAM,UAAU,YAAY;GAAE,KAAK;GAC3C,QAAQ;EAAE,GAAG,EAAE,QAAQ,KAAK,CAAC;EACrB,MAAM,UAAU,YAAY,EAAE,QAAQ,EAAE,CAAC;EAIzC,MAAM,gBAAgB,GAAG,WAAW,uBAAuB;EAC3D,MAAM,cAAc,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,KAAK,CAAC;EAClE,MAAM,cAAc,YAAY,EAAE,KAAK,EAAE,CAAC;EAC1C,MAAM,cAAc,YAAY,EAAE,WAAW,EAAE,CAAC;EAGhD,MAAM,cAAc,GAAG,WAAW,8BAA8B;EAChE,MAAM,YAAY,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,KAAK,CAAC;EAChE,MAAM,YAAY,YAAY,EAAE,KAAK,EAAE,CAAC;EAGxC,MAAM,iBAAiB,EAAE;EAEzB,OAAO,KAAK,kCAAkC;CAClD,SAAS,OAAO;EAIZ,OAAO,MAAM,+CAA+C,EAAS,MAAM,CAAC;EAC5E,MAAM;CACV;AACJ;;AAGA,eAAe,kBAAkB,IAAuB;CACpD,KAAK,MAAM,CAAC,gBAAgB,eAAe,OAAO,QAAQ,kBAAkB,GAAG;EAC3E,MAAM,aAAa,GAAG,WAAW,cAAc;EAC/C,KAAK,MAAM,aAAa,YACpB,IAAI;GACA,MAAM,WAAW,UAAU,SAAS;GACpC,OAAO,KAAK,+BAA+B,eAAe,GAAG,WAAW;EAC5E,QAAQ,CAER;CAER;AACJ;AAEA,eAAe,iBAAiB,IAAuB;CACnD,MAAM,QAAQ,GAAG,WAAW,cAAc;CAC1C,MAAM,QAAQ,MAAM,MAAM,eAAe;CAEzC,IAAI,QAAQ,GAAG;EACX,OAAO,KAAK,YAAY,MAAM,gBAAgB;EAC9C;CACJ;CAEA,OAAO,KAAK,6BAA6B;CAEzC,KAAK,MAAM,QAAQ,eACf,MAAM,MAAM,UACR,EAAE,IAAI,KAAK,GAAG,GACd,EAAE,cAAc,KAAK,GACrB,EAAE,QAAQ,KAAK,CACnB;CAGJ,OAAO,KAAK,gDAAgD;AAChE"}
package/dist/factory.d.ts CHANGED
@@ -46,10 +46,20 @@ export interface MongoBackendInstance extends BackendInstance {
46
46
  * Simple in-memory collection registry for MongoDB.
47
47
  */
48
48
  export declare class MongoCollectionRegistry implements CollectionRegistryInterface {
49
+ /** Every addressable key → collection. See {@link register}. */
49
50
  private collections;
51
+ /** Registration order, so `getCollections()` returns each collection once. */
52
+ private registered;
50
53
  private _globalCallbacks?;
51
54
  /**
52
- * Register a collection
55
+ * Register a collection under every name it can be addressed by.
56
+ *
57
+ * A Mongo collection has up to three: `slug` (the routing key), `path` (the
58
+ * MongoDB collection-name override, which is what `getCollectionDataPath`
59
+ * hands the driver) and `name` (the human label). Registering only `name`
60
+ * meant every `getCollectionByPath` lookup missed — and the realtime path,
61
+ * whose only source of the collection is this registry, ran with no
62
+ * `securityRules`, no `properties` and no callbacks.
53
63
  */
54
64
  register(collection: CollectionConfig): void;
55
65
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,2BAA2B,EAAE,cAAc,EAAwC,aAAa,EAAiD,MAAM,kBAAkB,CAAC;AAEnN;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACrD,IAAI,EAAE,SAAS,CAAC;IAChB,gCAAgC;IAChC,UAAU,EAAE,EAAE,CAAC;IACf,iDAAiD;IACjD,MAAM,EAAE,WAAW,CAAC;IACpB,kEAAkE;IAClE,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IACzD,oCAAoC;IACpC,EAAE,EAAE,EAAE,CAAC;IACP,yBAAyB;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,6CAA6C;IAC7C,MAAM,EAAE,UAAU,CAAC;IACnB,oDAAoD;IACpD,WAAW,EAAE,gBAAgB,CAAC;IAC9B,yCAAyC;IACzC,eAAe,EAAE,oBAAoB,CAAC;IACtC,uDAAuD;IACvD,KAAK,EAAE,aAAa,CAAC;CACxB;AAMD;;GAEG;AACH,qBAAa,uBAAwB,YAAW,2BAA2B;IACvE,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,gBAAgB,CAAC,CAAM;IAE/B;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAI5C;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAI/D;;OAEG;IACH,cAAc,IAAI,gBAAgB,EAAE;IAIpC;;OAEG;IACH,kBAAkB,IAAI,GAAG,GAAG,SAAS;IAIrC;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;CAG3C;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,oBAAoB,CAgGnF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAC/B,EAAE,EAAE,EAAE,EACN,eAAe,CAAC,EAAE,oBAAoB,EACtC,cAAc,CAAC,EAAE,mBAAmB,EACpC,QAAQ,CAAC,EAAE,2BAA2B,GACvC,WAAW,CAIb;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,EAAE,GAAG,oBAAoB,CAEvE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,EAAE,GAAG,cAAc,CAElE;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,IAAI,kBAAkB,CAIxF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAOjH"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}