refactor(nest): inject DatabaseService in db-using services

This commit is contained in:
jubnl
2026-07-25 18:15:04 +02:00
parent def6b84938
commit fbe200424d
36 changed files with 345 additions and 223 deletions
@@ -1,5 +1,5 @@
import { readEnv } from '../../../app-config';
import { db } from '../../../db/database';
import { DatabaseService } from '../../database/database.service';
import { discoverPlugins } from '../install/discovery';
import { hostSatisfies, hostVersion, normalizedHost } from '../install/host-compat';
import type { PluginDependency } from '../install/manifest';
@@ -147,6 +147,12 @@ export class RegistryError extends Error {
@Injectable()
export class PluginRegistryService {
constructor(private readonly dbs: DatabaseService) {}
private get db() {
return this.dbs.connection;
}
/**
* Fetch the aggregated registry (cached, soft-fail, stale-serve). Pass
* force=true (the admin "rescan" button) to bypass the 30-min cache and also
@@ -435,8 +441,8 @@ export class PluginRegistryService {
fs.renameSync(pluginRoot, dest);
// 7. register INACTIVE (record provenance)
discoverPlugins(db);
db.prepare('UPDATE plugins SET source_repo = ?, source_commit = ?, sha256 = ?, reviewed_at = ? WHERE id = ?').run(
discoverPlugins(this.db);
this.db.prepare('UPDATE plugins SET source_repo = ?, source_commit = ?, sha256 = ?, reviewed_at = ? WHERE id = ?').run(
entry.repo,
ver.commitSha,
ver.sha256,
@@ -448,7 +454,7 @@ export class PluginRegistryService {
// to a key the artifact just verified under; NEVER cleared to NULL, because a
// NULL pin re-opens the "was never signed" path that accepts an unsigned update.
if (entry.authorPublicKey) {
db.prepare('UPDATE plugins SET author_pubkey = ? WHERE id = ?').run(entry.authorPublicKey, id);
this.db.prepare('UPDATE plugins SET author_pubkey = ? WHERE id = ?').run(entry.authorPublicKey, id);
}
// The plugin is now on new code that passed every check — whatever refusal was
// recorded before no longer describes reality.
@@ -471,7 +477,7 @@ export class PluginRegistryService {
constraint?: string,
): Promise<{ installed: string[]; requiredAddons: string[] }> {
const installedNow = new Set(
(db.prepare('SELECT id FROM plugins').all() as Array<{ id: string }>).map((r) => r.id),
(this.db.prepare('SELECT id FROM plugins').all() as Array<{ id: string }>).map((r) => r.id),
);
const done = new Set<string>();
const installed: string[] = [];
@@ -536,7 +542,7 @@ export class PluginRegistryService {
fs.mkdirSync(pluginsCodeRoot(), { recursive: true });
fs.rmSync(dest, { recursive: true, force: true });
fs.renameSync(staged.root, dest);
discoverPlugins(db);
discoverPlugins(this.db);
// Provenance for a sideload, plus a hard INACTIVE floor: discoverPlugins keeps
// an existing row's status, so replacing a plugin that was active must not
// leave the new code marked active — the admin re-activates (and re-consents
@@ -546,7 +552,7 @@ export class PluginRegistryService {
// plugin has just left the registry trust model entirely — the code is now whatever
// the admin uploaded. Leaving the block would have the row insist an update was
// blocked over a signing key that no longer applies to the code that is running.
db.prepare(
this.db.prepare(
`UPDATE plugins SET source_repo = ?, source_commit = ?, sha256 = ?, reviewed_at = ?, author_pubkey = NULL,
update_block_code = NULL, update_block_detail = NULL, update_block_version = NULL,
status = 'inactive', enabled = 0
@@ -585,7 +591,7 @@ export class PluginRegistryService {
retrustKey?: string,
): void {
const pinned =
(db.prepare('SELECT author_pubkey FROM plugins WHERE id = ?').get(id) as { author_pubkey?: string } | undefined)
(this.db.prepare('SELECT author_pubkey FROM plugins WHERE id = ?').get(id) as { author_pubkey?: string } | undefined)
?.author_pubkey ?? null;
if (!entry.authorPublicKey && !ver.signature) {
@@ -637,7 +643,7 @@ export class PluginRegistryService {
* rendered, the admin would be blessing a key they never saw.
*/
async assertRetrustable(id: string, publicKey: string): Promise<RegistryEntry> {
const row = db.prepare('SELECT source_repo, author_pubkey FROM plugins WHERE id = ?').get(id) as
const row = this.db.prepare('SELECT source_repo, author_pubkey FROM plugins WHERE id = ?').get(id) as
| { source_repo?: string | null; author_pubkey?: string | null }
| undefined;
if (!row) throw new RegistryError(`plugin ${id} not found`, 'NOT_FOUND');