From 78bc6040ca1b06027efc62f9b8548760c6e26d1e Mon Sep 17 00:00:00 2001 From: Ewout Stortenbeker Date: Mon, 24 Apr 2023 22:51:19 +0200 Subject: [PATCH] Fix schema validation of update on higher path --- src/storage/index.ts | 6 +++++- src/test/schema.spec.ts | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/storage/index.ts b/src/storage/index.ts index 9aff6f3..bb066e4 100644 --- a/src/storage/index.ts +++ b/src/storage/index.ts @@ -2281,7 +2281,7 @@ export class Storage extends SimpleEventEmitter { pathInfo.isOnTrailOf(s.path), //pathInfo.equals(s.path) || pathInfo.isAncestorOf(s.path) ).every(s => { if (pathInfo.isDescendantOf(s.path)) { - // Given check path is a descendant of this schema definition's path + // Given check path is a descendant of this schema definition's path const ancestorPath = PathInfo.fillVariables(s.path, path); const trailKeys = pathInfo.keys.slice(PathInfo.getPathKeys(s.path).length); result = s.schema.check(ancestorPath, value, options.updates, trailKeys); @@ -2290,6 +2290,10 @@ export class Storage extends SimpleEventEmitter { // Given check path is on schema definition's path or on a higher path const trailKeys = PathInfo.getPathKeys(s.path).slice(pathInfo.keys.length); + if (options.updates === true && trailKeys.length > 0 && !(trailKeys[0] in value)) { + // Fixes #217: this update on a higher path does not affect any data at schema's target path + return result.ok; + } const partial = options.updates === true && trailKeys.length === 0; const check = (path: string, value: any, trailKeys: Array): ISchemaCheckResult => { if (trailKeys.length === 0) { diff --git a/src/test/schema.spec.ts b/src/test/schema.spec.ts index 2874eef..3a3176b 100644 --- a/src/test/schema.spec.ts +++ b/src/test/schema.spec.ts @@ -96,6 +96,10 @@ describe('schema', () => { result = await db.schema.check('clients/client1', { unknown: null }, true); expect(result).toEqual({ ok: true }); + // Test updating a higher path that does not have a schema set (#217) + result = await db.schema.check('', { test: 'Test' }, true); + expect(result).toEqual({ ok: true }); + // Try using classnames & regular expressions const emailRegex = /[a-z.\-_]+@(?:[a-z\-_]+\.){1,}[a-z]{2,}$/i; const clientSchema2 = {