diff --git a/server/src/plugins/service-store/pg-adapter.ts b/server/src/plugins/service-store/pg-adapter.ts index 8f30537..5bc2cef 100644 --- a/server/src/plugins/service-store/pg-adapter.ts +++ b/server/src/plugins/service-store/pg-adapter.ts @@ -59,19 +59,6 @@ export class PgAdapter implements DbAdapter { return out; } - private coerceParams(params: ReadonlyArray): unknown[] { - return params.map((v) => { - if (v === 0 || v === 1) { - // Could be integer or boolean. PG is strict about boolean columns - // receiving integer values. We can't know the column type here, but - // the `pg` driver accepts JS booleans for both INTEGER and BOOLEAN - // columns, so converting 0/1 to false/true is always safe. - return v === 1; - } - return v; - }); - } - private async runner(fn: (c: PoolClient) => Promise): Promise { if (this.currentTxClient) return fn(this.currentTxClient); const client = await this.pool.connect(); @@ -81,9 +68,8 @@ export class PgAdapter implements DbAdapter { async run(sql: string, params: ReadonlyArray = []): Promise { const pgSql = this.rewriteSql(sql); - const pgParams = this.coerceParams(params); return this.runner(async (c) => { - const res = await c.query(pgSql, pgParams); + const res = await c.query(pgSql, params as unknown[]); let lastInsertRowid = 0n; // If the caller added RETURNING id, pluck it. if (res.rows.length > 0 && res.rows[0] && "id" in res.rows[0]) { @@ -98,18 +84,16 @@ export class PgAdapter implements DbAdapter { async get(sql: string, params: ReadonlyArray = []): Promise { const pgSql = this.rewriteSql(sql); - const pgParams = this.coerceParams(params); return this.runner(async (c) => { - const res = await c.query(pgSql, pgParams); + const res = await c.query(pgSql, params as unknown[]); return (res.rows[0] as T | undefined); }); } async all(sql: string, params: ReadonlyArray = []): Promise { const pgSql = this.rewriteSql(sql); - const pgParams = this.coerceParams(params); return this.runner(async (c) => { - const res = await c.query(pgSql, pgParams); + const res = await c.query(pgSql, params as unknown[]); return res.rows as T[]; }); } diff --git a/server/src/plugins/service-store/repository.ts b/server/src/plugins/service-store/repository.ts index efa4388..cdf3440 100644 --- a/server/src/plugins/service-store/repository.ts +++ b/server/src/plugins/service-store/repository.ts @@ -81,7 +81,7 @@ import { rowToSetupState, rowToUser, } from "./mappers.js"; -import { B, J, isoIn, isoNow, j } from "./util.js"; +import { J, isoIn, isoNow, j } from "./util.js"; type NotifyFn = ( table: string, @@ -189,12 +189,13 @@ export class Repository { const role: UserRole = input.role ?? "operator"; const result = await this._run( `INSERT INTO users (username, password_hash, role, is_active, must_change_password) - VALUES (?, ?, ?, 1, ?)`, + VALUES (?, ?, ?, ?, ?)`, [ input.username, input.password_hash, role, - B(Boolean(input.must_change_password)), + true, + Boolean(input.must_change_password), ], ); const id = Number(result.lastInsertRowid); @@ -213,7 +214,7 @@ export class Repository { } if ("totp_enabled" in patch) { cols.push("totp_enabled = ?"); - vals.push(B(Boolean(patch.totp_enabled))); + vals.push(Boolean(patch.totp_enabled)); } if ("totp_secret_encrypted" in patch) { cols.push("totp_secret_encrypted = ?"); @@ -225,7 +226,7 @@ export class Repository { } if ("must_change_password" in patch) { cols.push("must_change_password = ?"); - vals.push(B(Boolean(patch.must_change_password))); + vals.push(Boolean(patch.must_change_password)); } if ("failed_login_count" in patch) { cols.push("failed_login_count = ?"); @@ -241,7 +242,7 @@ export class Repository { } if ("is_active" in patch) { cols.push("is_active = ?"); - vals.push(B(Boolean(patch.is_active))); + vals.push(Boolean(patch.is_active)); } if (cols.length === 0) return; vals.push(id); @@ -270,7 +271,7 @@ export class Repository { input.id, input.user_id, input.csrf_token, - B(input.totp_pending), + Boolean(input.totp_pending), input.user_agent, input.ip_address, input.expires_at, @@ -295,7 +296,7 @@ export class Repository { async setSessionTotpPending(id: string, pending: boolean): Promise { await this._run("UPDATE sessions SET totp_pending = ? WHERE id = ?", [ - B(pending), + pending, id, ]); } @@ -573,7 +574,7 @@ export class Repository { input.priority ?? "normal", input.cooling_timeout_seconds ?? null, J(input.preload_camera_ids ?? []), - B(input.resets_idle_timer ?? true), + Boolean(input.resets_idle_timer ?? true), ], ); const id = Number(result.lastInsertRowid); @@ -590,7 +591,7 @@ export class Repository { if (k === "id" || k === "display_id") continue; // display_id deprecated sets.push(`${k} = ?`); if (k === "preload_camera_ids" || k === "regions") vals.push(J(v)); - else if (typeof v === "boolean") vals.push(B(v)); + else if (typeof v === "boolean") vals.push(v); else vals.push(v === undefined ? null : v); } if (sets.length === 0) return; @@ -936,7 +937,7 @@ export class Repository { const cam = rowToCamera(existing as Record); await this._run( `UPDATE cameras SET name = ?, cloud_stream_url = ?, cloud_stream_type = ?, enabled = ? WHERE id = ?`, - [input.name, input.cloud_stream_url, input.cloud_stream_type, B(input.enabled), cam.id], + [input.name, input.cloud_stream_url, input.cloud_stream_type, Boolean(input.enabled), cam.id], ); void this.notify("cameras", "update", cam.id); return (await this.getCameraById(cam.id))!; @@ -946,7 +947,7 @@ export class Repository { (name, type, cloud_account_id, cloud_vendor_camera_id, cloud_stream_url, cloud_stream_type, enabled) VALUES (?, 'cloud', ?, ?, ?, ?, ?)`, [input.name, input.cloud_account_id, input.cloud_vendor_camera_id, - input.cloud_stream_url, input.cloud_stream_type, B(input.enabled)], + input.cloud_stream_url, input.cloud_stream_type, Boolean(input.enabled)], ); const id = Number(result.lastInsertRowid); void this.notify("cameras", "create", id); @@ -1017,7 +1018,7 @@ export class Repository { input.encoding ?? null, input.framerate ?? null, input.bitrate_kbps ?? null, - B(Boolean(input.is_discovered)), + Boolean(input.is_discovered), ], ); const id = Number(result.lastInsertRowid); @@ -1829,7 +1830,7 @@ export class Repository { input.topic, input.property_op, J(input.payload), - B(input.forwarded_to_nodered), + Boolean(input.forwarded_to_nodered), ], ); return Number(result.lastInsertRowid); @@ -2099,7 +2100,7 @@ export class Repository { if (k === "id" || k === "created_at") continue; sets.push(`${k} = ?`); if (k === "capabilities") vals.push(J(v)); - else if (typeof v === "boolean") vals.push(B(v)); + else if (typeof v === "boolean") vals.push(v); else vals.push(v === undefined ? null : v); } if (sets.length === 0) return;