From 8c4a8d91a275ce58f0f53f1f8cb7bcc0872e10fb Mon Sep 17 00:00:00 2001 From: dswbx Date: Thu, 18 Sep 2025 09:47:47 +0200 Subject: [PATCH] fix: secret handling and relation naming logic Implemented improved handling for secrets in `DbModuleManager`, allowing secret merging and building before saving. Enhanced `ManyToManyRelation` naming to produce valid identifiers and ensured better testing coverage for both changes. --- .../specs/relations/EntityRelation.spec.ts | 13 +++++ app/__test__/modules/DbModuleManager.spec.ts | 54 +++++++++++++++++++ app/src/data/relations/ManyToManyRelation.ts | 11 +++- app/src/modules/db/DbModuleManager.ts | 34 ++++++++++-- 4 files changed, 106 insertions(+), 6 deletions(-) diff --git a/app/__test__/data/specs/relations/EntityRelation.spec.ts b/app/__test__/data/specs/relations/EntityRelation.spec.ts index 489a5be..12a8325 100644 --- a/app/__test__/data/specs/relations/EntityRelation.spec.ts +++ b/app/__test__/data/specs/relations/EntityRelation.spec.ts @@ -4,8 +4,10 @@ import { type BaseRelationConfig, EntityRelation, EntityRelationAnchor, + ManyToManyRelation, RelationTypes, } from "data/relations"; +import * as proto from "data/prototype"; class TestEntityRelation extends EntityRelation { constructor(config?: BaseRelationConfig) { @@ -75,4 +77,15 @@ describe("[data] EntityRelation", async () => { const relation2 = new TestEntityRelation({ required: true }); expect(relation2.required).toBe(true); }); + + it("correctly produces the relation name", async () => { + const relation = new ManyToManyRelation(new Entity("apps"), new Entity("organizations")); + expect(relation.getName()).not.toContain(","); + expect(relation.getName()).toBe("mn_apps_organizations"); + + const relation2 = new ManyToManyRelation(new Entity("apps"), new Entity("organizations"), { + connectionTableMappedName: "appOrganizations", + }); + expect(relation2.getName()).toBe("mn_apps_organizations_appOrganizations"); + }); }); diff --git a/app/__test__/modules/DbModuleManager.spec.ts b/app/__test__/modules/DbModuleManager.spec.ts index a148192..31c5bee 100644 --- a/app/__test__/modules/DbModuleManager.spec.ts +++ b/app/__test__/modules/DbModuleManager.spec.ts @@ -1,6 +1,7 @@ import { it, expect, describe } from "bun:test"; import { DbModuleManager } from "modules/db/DbModuleManager"; import { getDummyConnection } from "../helper"; +import { TABLE_NAME } from "modules/db/migrations"; describe("DbModuleManager", () => { it("should extract secrets", async () => { @@ -19,4 +20,57 @@ describe("DbModuleManager", () => { expect(m.toJSON(true).auth.jwt.secret).toBe("test"); await m.save(); }); + + it("should work with initial secrets", async () => { + const { dummyConnection } = getDummyConnection(false); + const db = dummyConnection.kysely; + const m = new DbModuleManager(dummyConnection, { + initial: { + auth: { + enabled: true, + jwt: { + secret: "", + }, + }, + }, + secrets: { + "auth.jwt.secret": "test", + }, + }); + await m.build(); + expect(m.toJSON(true).auth.jwt.secret).toBe("test"); + + const getSecrets = () => + db + .selectFrom(TABLE_NAME) + .selectAll() + .where("type", "=", "secrets") + .executeTakeFirst() + .then((r) => r?.json); + + expect(await getSecrets()).toEqual({ "auth.jwt.secret": "test" }); + + // also after rebuild + await m.build(); + await m.save(); + expect(await getSecrets()).toEqual({ "auth.jwt.secret": "test" }); + + // and ignore if already present + const m2 = new DbModuleManager(dummyConnection, { + initial: { + auth: { + enabled: true, + jwt: { + secret: "", + }, + }, + }, + secrets: { + "auth.jwt.secret": "something completely different", + }, + }); + await m2.build(); + await m2.save(); + expect(await getSecrets()).toEqual({ "auth.jwt.secret": "test" }); + }); }); diff --git a/app/src/data/relations/ManyToManyRelation.ts b/app/src/data/relations/ManyToManyRelation.ts index 99b5740..e7a1233 100644 --- a/app/src/data/relations/ManyToManyRelation.ts +++ b/app/src/data/relations/ManyToManyRelation.ts @@ -180,8 +180,15 @@ export class ManyToManyRelation extends EntityRelation