@frogfish/k2db 3.0.7 → 3.0.8
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.
- package/db.d.ts +1 -1
- package/db.js +24 -10
- package/package.json +1 -1
package/db.d.ts
CHANGED
|
@@ -288,7 +288,7 @@ export declare class K2DB {
|
|
|
288
288
|
private static normalizeCriteriaIds;
|
|
289
289
|
/** Uppercase helper for `_uuid` field supporting operators like $in/$nin/$eq/$ne and arrays. */
|
|
290
290
|
private static normalizeUuidField;
|
|
291
|
-
/**
|
|
291
|
+
/** Trim helper for `_owner` field supporting operators like $in/$nin/$eq/$ne and arrays. */
|
|
292
292
|
private static normalizeOwnerField;
|
|
293
293
|
/** Strip any user-provided fields that start with '_' (reserved). */
|
|
294
294
|
private static stripReservedFields;
|
package/db.js
CHANGED
|
@@ -398,7 +398,9 @@ export class K2DB {
|
|
|
398
398
|
return undefined;
|
|
399
399
|
if (s === "*")
|
|
400
400
|
return "*";
|
|
401
|
-
|
|
401
|
+
// Scope maps to `_owner` (usually another record's `_uuid`), which is case-sensitive.
|
|
402
|
+
// Our `_uuid` is UUIDv7 Crockford Base32 (uppercase), so normalize to that form.
|
|
403
|
+
return K2DB.normalizeId(s);
|
|
402
404
|
}
|
|
403
405
|
/**
|
|
404
406
|
* Apply a scope constraint to criteria for ownership enforcement.
|
|
@@ -418,8 +420,13 @@ export class K2DB {
|
|
|
418
420
|
// If caller already provided _owner in criteria, ensure it matches the scope to avoid ambiguity/bypass.
|
|
419
421
|
if (criteria && typeof criteria === "object" && Object.prototype.hasOwnProperty.call(criteria, "_owner")) {
|
|
420
422
|
const existing = criteria._owner;
|
|
421
|
-
if (typeof existing === "string"
|
|
422
|
-
|
|
423
|
+
if (typeof existing === "string") {
|
|
424
|
+
const ex = existing.trim();
|
|
425
|
+
// Treat any explicit "*" as mismatched here (caller should omit _owner or set scope="*").
|
|
426
|
+
const existingNorm = ex === "*" ? "*" : K2DB.normalizeId(ex);
|
|
427
|
+
if (existingNorm !== normalizedScope) {
|
|
428
|
+
throw new K2Error(ServiceError.BAD_REQUEST, "Conflicting _owner in criteria and provided scope", "sys_mdb_scope_conflict");
|
|
429
|
+
}
|
|
423
430
|
}
|
|
424
431
|
// If it matches (or is non-string), prefer the explicit scope value.
|
|
425
432
|
}
|
|
@@ -1412,13 +1419,15 @@ export class K2DB {
|
|
|
1412
1419
|
if (typeof owner !== "string") {
|
|
1413
1420
|
throw new K2Error(ServiceError.BAD_REQUEST, "Owner must be of a string type", "sys_mdb_crv2");
|
|
1414
1421
|
}
|
|
1415
|
-
const
|
|
1416
|
-
if (!
|
|
1422
|
+
const ownerTrimmed = owner.trim();
|
|
1423
|
+
if (!ownerTrimmed) {
|
|
1417
1424
|
throw new K2Error(ServiceError.BAD_REQUEST, "Owner must be a non-empty string", "sys_mdb_owner_empty");
|
|
1418
1425
|
}
|
|
1419
|
-
if (
|
|
1426
|
+
if (ownerTrimmed === "*") {
|
|
1420
1427
|
throw new K2Error(ServiceError.BAD_REQUEST, "Owner cannot be '*'", "sys_mdb_owner_star");
|
|
1421
1428
|
}
|
|
1429
|
+
// `_owner` is typically another record's `_uuid` (case-sensitive). Normalize to the canonical ID form.
|
|
1430
|
+
const normalizedOwner = K2DB.normalizeId(ownerTrimmed);
|
|
1422
1431
|
const collection = await this.getCollection(collectionName);
|
|
1423
1432
|
const timestamp = Date.now();
|
|
1424
1433
|
// Generate a new UUIDv7 encoded as Crockford Base32 with hyphens
|
|
@@ -1560,6 +1569,11 @@ export class K2DB {
|
|
|
1560
1569
|
}, {});
|
|
1561
1570
|
// Merge the preserved fields into the data
|
|
1562
1571
|
data = { ...data, ...fieldsToPreserve };
|
|
1572
|
+
// Update _owner if scope is provided
|
|
1573
|
+
const normalizedScope = this.normalizeScope(scope);
|
|
1574
|
+
if (normalizedScope) {
|
|
1575
|
+
data._owner = normalizedScope;
|
|
1576
|
+
}
|
|
1563
1577
|
data._updated = Date.now();
|
|
1564
1578
|
// Encrypt secure-prefixed fields at rest (no-op unless encryption is configured)
|
|
1565
1579
|
data = this.encryptSecureFieldsDeep(data, `k2db|${collectionName}|${id}`);
|
|
@@ -1936,12 +1950,12 @@ export class K2DB {
|
|
|
1936
1950
|
}
|
|
1937
1951
|
return val;
|
|
1938
1952
|
}
|
|
1939
|
-
/**
|
|
1953
|
+
/** Trim helper for `_owner` field supporting operators like $in/$nin/$eq/$ne and arrays. */
|
|
1940
1954
|
static normalizeOwnerField(val) {
|
|
1941
1955
|
if (typeof val === "string")
|
|
1942
|
-
return val.trim()
|
|
1956
|
+
return val.trim();
|
|
1943
1957
|
if (Array.isArray(val)) {
|
|
1944
|
-
return val.map((x) => (typeof x === "string" ? x.trim()
|
|
1958
|
+
return val.map((x) => (typeof x === "string" ? x.trim() : x));
|
|
1945
1959
|
}
|
|
1946
1960
|
if (val && typeof val === "object") {
|
|
1947
1961
|
const out = { ...val };
|
|
@@ -1972,7 +1986,7 @@ export class K2DB {
|
|
|
1972
1986
|
}
|
|
1973
1987
|
/** Uppercase incoming IDs for case-insensitive lookups. */
|
|
1974
1988
|
static normalizeId(id) {
|
|
1975
|
-
return id.
|
|
1989
|
+
return id.trim();
|
|
1976
1990
|
}
|
|
1977
1991
|
/**
|
|
1978
1992
|
* Run an async DB operation with timing, slow logging, and hooks.
|