- Added AuthRepository for user and settings management with CRUD operations. - Introduced CertificateRepository to handle domains, certificates, and requirements. - Created MetricsRepository for managing metrics and logs. - Developed PlatformRepository for platform services and resources management. - Established RegistryRepository for registry and token operations. - Implemented ServiceRepository for CRUD operations on services. - Defined types and interfaces in types.ts for database interactions.
124 lines
4.0 KiB
TypeScript
124 lines
4.0 KiB
TypeScript
/**
|
|
* Registry Repository
|
|
* Handles CRUD operations for registries and registry_tokens tables
|
|
*/
|
|
|
|
import { BaseRepository } from '../base.repository.ts';
|
|
import type { IRegistry, IRegistryToken } from '../../types.ts';
|
|
|
|
export class RegistryRepository extends BaseRepository {
|
|
// ============ Registries ============
|
|
|
|
async createRegistry(registry: Omit<IRegistry, 'id'>): Promise<IRegistry> {
|
|
const now = Date.now();
|
|
this.query(
|
|
'INSERT INTO registries (url, username, password_encrypted, created_at) VALUES (?, ?, ?, ?)',
|
|
[registry.url, registry.username, registry.passwordEncrypted, now]
|
|
);
|
|
|
|
return this.getRegistryByURL(registry.url)!;
|
|
}
|
|
|
|
getRegistryByURL(url: string): IRegistry | null {
|
|
const rows = this.query('SELECT * FROM registries WHERE url = ?', [url]);
|
|
return rows.length > 0 ? this.rowToRegistry(rows[0]) : null;
|
|
}
|
|
|
|
getAllRegistries(): IRegistry[] {
|
|
const rows = this.query('SELECT * FROM registries ORDER BY created_at DESC');
|
|
return rows.map((row) => this.rowToRegistry(row));
|
|
}
|
|
|
|
deleteRegistry(url: string): void {
|
|
this.query('DELETE FROM registries WHERE url = ?', [url]);
|
|
}
|
|
|
|
private rowToRegistry(row: any): IRegistry {
|
|
return {
|
|
id: Number(row.id || row[0]),
|
|
url: String(row.url || row[1]),
|
|
username: String(row.username || row[2]),
|
|
passwordEncrypted: String(row.password_encrypted || row[3]),
|
|
createdAt: Number(row.created_at || row[4]),
|
|
};
|
|
}
|
|
|
|
// ============ Registry Tokens ============
|
|
|
|
createToken(token: Omit<IRegistryToken, 'id'>): IRegistryToken {
|
|
const scopeJson = Array.isArray(token.scope) ? JSON.stringify(token.scope) : token.scope;
|
|
|
|
this.query(
|
|
`INSERT INTO registry_tokens (name, token_hash, token_type, scope, expires_at, created_at, last_used_at, created_by)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
[
|
|
token.name,
|
|
token.tokenHash,
|
|
token.type,
|
|
scopeJson,
|
|
token.expiresAt,
|
|
token.createdAt,
|
|
token.lastUsedAt,
|
|
token.createdBy,
|
|
]
|
|
);
|
|
|
|
const rows = this.query('SELECT * FROM registry_tokens WHERE id = last_insert_rowid()');
|
|
return this.rowToToken(rows[0]);
|
|
}
|
|
|
|
getTokenById(id: number): IRegistryToken | null {
|
|
const rows = this.query('SELECT * FROM registry_tokens WHERE id = ?', [id]);
|
|
return rows.length > 0 ? this.rowToToken(rows[0]) : null;
|
|
}
|
|
|
|
getTokenByHash(tokenHash: string): IRegistryToken | null {
|
|
const rows = this.query('SELECT * FROM registry_tokens WHERE token_hash = ?', [tokenHash]);
|
|
return rows.length > 0 ? this.rowToToken(rows[0]) : null;
|
|
}
|
|
|
|
getAllTokens(): IRegistryToken[] {
|
|
const rows = this.query('SELECT * FROM registry_tokens ORDER BY created_at DESC');
|
|
return rows.map((row) => this.rowToToken(row));
|
|
}
|
|
|
|
getTokensByType(type: 'global' | 'ci'): IRegistryToken[] {
|
|
const rows = this.query('SELECT * FROM registry_tokens WHERE token_type = ? ORDER BY created_at DESC', [type]);
|
|
return rows.map((row) => this.rowToToken(row));
|
|
}
|
|
|
|
updateTokenLastUsed(id: number): void {
|
|
this.query('UPDATE registry_tokens SET last_used_at = ? WHERE id = ?', [Date.now(), id]);
|
|
}
|
|
|
|
deleteToken(id: number): void {
|
|
this.query('DELETE FROM registry_tokens WHERE id = ?', [id]);
|
|
}
|
|
|
|
private rowToToken(row: any): IRegistryToken {
|
|
let scope: 'all' | string[];
|
|
const scopeRaw = row.scope || row[4];
|
|
if (scopeRaw === 'all') {
|
|
scope = 'all';
|
|
} else {
|
|
try {
|
|
scope = JSON.parse(String(scopeRaw));
|
|
} catch {
|
|
scope = 'all';
|
|
}
|
|
}
|
|
|
|
return {
|
|
id: Number(row.id || row[0]),
|
|
name: String(row.name || row[1]),
|
|
tokenHash: String(row.token_hash || row[2]),
|
|
type: String(row.token_type || row[3]) as IRegistryToken['type'],
|
|
scope,
|
|
expiresAt: row.expires_at || row[5] ? Number(row.expires_at || row[5]) : null,
|
|
createdAt: Number(row.created_at || row[6]),
|
|
lastUsedAt: row.last_used_at || row[7] ? Number(row.last_used_at || row[7]) : null,
|
|
createdBy: String(row.created_by || row[8]),
|
|
};
|
|
}
|
|
}
|