@nextage/nx-frame-be 1.0.46 → 1.0.47

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.
@@ -32,6 +32,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
32
32
  const constants_1 = require("../../constants");
33
33
  const base_model_1 = require("../base.model");
34
34
  const mongo_utils_1 = require("../mongo-utils");
35
+ const mongo_utils_2 = require("../mongo-utils");
35
36
  const enums_1 = require("../../enums");
36
37
  /** Marks a document every tenant shares, as an application would mark it. */
37
38
  const SHARED = '__GLOBAL__';
@@ -125,6 +126,17 @@ describe('a model that overrides nothing is scoped anyway', () => {
125
126
  yield expect(unaware.remove(doc.id, outsider)).rejects.toBeDefined();
126
127
  expect(yield unaware.mgModel.collection.countDocuments({})).toBe(1);
127
128
  }));
129
+ // A refusal that only happens when the document EXISTS is an oracle: delete an id at
130
+ // random and the answer tells you whether it names something in somebody else's tenant.
131
+ // The two outcomes must therefore be indistinguishable - the existence of another
132
+ // tenant's document is not a fact this caller is entitled to learn.
133
+ it('refuses a delete the same way whether the document is missing or another tenant\'s', () => __awaiter(void 0, void 0, void 0, function* () {
134
+ const doc = yield unaware.create({ code: 'A' }, owner);
135
+ const missing = (0, mongo_utils_2.genObjectId)().toHexString();
136
+ const foreign = yield unaware.remove(doc.id, outsider).then(() => null, (e) => e.constructor.name);
137
+ const absent = yield unaware.remove(missing, outsider).then(() => null, (e) => e.constructor.name);
138
+ expect(absent).toBe(foreign);
139
+ }));
128
140
  it('refuses to update another tenant document', () => __awaiter(void 0, void 0, void 0, function* () {
129
141
  const doc = yield unaware.create({ code: 'A' }, owner);
130
142
  yield expect(unaware.update(doc.id, { code: 'B' }, outsider)).rejects.toBeDefined();
@@ -214,6 +214,13 @@ export declare class BaseModel<TAttrs, TDoc extends BaseMongoDoc, TMongoModel ex
214
214
  * id. The document is re-read unscoped on purpose - the point is to judge its real
215
215
  * owner, and a scoped read would hide the very case being guarded against.
216
216
  *
217
+ * A MISSING document is refused in exactly the same way as a foreign one, and that is
218
+ * not defensive coding: refusing only when the document exists turns this hook into an
219
+ * oracle. Delete an id at random and the outcome answers a question the caller was
220
+ * never entitled to ask - whether that id names something in somebody else's tenant.
221
+ * The two cases are therefore made indistinguishable, which costs nothing: deleting an
222
+ * id that matches nothing had no effect to begin with.
223
+ *
217
224
  * @param {*} id
218
225
  */
219
226
  beforeRemove(id: string, context: NxContext): Promise<string>;
@@ -410,12 +410,21 @@ class BaseModel extends events_1.EventEmitter {
410
410
  * id. The document is re-read unscoped on purpose - the point is to judge its real
411
411
  * owner, and a scoped read would hide the very case being guarded against.
412
412
  *
413
+ * A MISSING document is refused in exactly the same way as a foreign one, and that is
414
+ * not defensive coding: refusing only when the document exists turns this hook into an
415
+ * oracle. Delete an id at random and the outcome answers a question the caller was
416
+ * never entitled to ask - whether that id names something in somebody else's tenant.
417
+ * The two cases are therefore made indistinguishable, which costs nothing: deleting an
418
+ * id that matches nothing had no effect to begin with.
419
+ *
413
420
  * @param {*} id
414
421
  */
415
422
  beforeRemove(id, context) {
416
423
  return __awaiter(this, void 0, void 0, function* () {
417
424
  if (this.tenancy && id) {
418
425
  const doc = yield this.mgModel.findOne({ _id: (0, mongo_utils_1.toObjectId)(id) });
426
+ if (!doc)
427
+ throw new errors_1.ForbiddenError();
419
428
  this.assertWritable(doc, context);
420
429
  }
421
430
  return id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextage/nx-frame-be",
3
- "version": "1.0.46",
3
+ "version": "1.0.47",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",