mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-18 05:28:45 -04:00
251 lines
7.2 KiB
TypeScript
251 lines
7.2 KiB
TypeScript
import { COMPLETE_SCHEMA_SQL, MIGRATION_SCRIPTS } from './SqlConstants';
|
|
import { VAULT_VERSIONS } from './VaultVersions';
|
|
import { type VaultVersion } from '../types/VaultVersion';
|
|
|
|
/**
|
|
* Result of SQL generation operations
|
|
*/
|
|
export type SqlGenerationResult = {
|
|
success: boolean;
|
|
sqlCommands: string[];
|
|
version: string;
|
|
migrationNumber: number;
|
|
error?: string;
|
|
}
|
|
|
|
/**
|
|
* Information about vault version requirements
|
|
*/
|
|
export type VaultVersionInfo = {
|
|
currentVersion: string;
|
|
currentMigrationNumber: number;
|
|
targetVersion: string;
|
|
targetMigrationNumber: number;
|
|
needsUpgrade: boolean;
|
|
availableUpgrades: VaultVersion[];
|
|
}
|
|
|
|
/**
|
|
* Vault SQL generator utility class
|
|
* Provides SQL statements for vault creation and migration without database execution
|
|
*/
|
|
export class VaultSqlGenerator {
|
|
/**
|
|
* Get SQL commands to create a new vault with the latest schema
|
|
*/
|
|
getCreateVaultSql(): SqlGenerationResult {
|
|
try {
|
|
const sqlCommands = [
|
|
COMPLETE_SCHEMA_SQL,
|
|
];
|
|
|
|
return {
|
|
success: true,
|
|
sqlCommands,
|
|
version: VAULT_VERSIONS[VAULT_VERSIONS.length - 1].version,
|
|
migrationNumber: VAULT_VERSIONS[VAULT_VERSIONS.length - 1].revision
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
sqlCommands: [],
|
|
version: '0.0.0',
|
|
migrationNumber: 0,
|
|
error: error instanceof Error ? error.message : 'Unknown error creating vault SQL'
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get SQL commands to upgrade vault from current version to target version
|
|
*/
|
|
getUpgradeVaultSql(currentMigrationNumber: number, targetMigrationNumber?: number): SqlGenerationResult {
|
|
try {
|
|
const targetMigration = targetMigrationNumber ?? VAULT_VERSIONS[VAULT_VERSIONS.length - 1].revision;
|
|
const targetVersionInfo = VAULT_VERSIONS.find(v => v.revision === targetMigration);
|
|
|
|
if (!targetVersionInfo) {
|
|
return {
|
|
success: false,
|
|
sqlCommands: [],
|
|
version: '0.0.0',
|
|
migrationNumber: 0,
|
|
error: `Target migration number ${targetMigration} not found`
|
|
};
|
|
}
|
|
|
|
// If already at target version or beyond, no upgrade needed
|
|
if (currentMigrationNumber >= targetMigration) {
|
|
return {
|
|
success: true,
|
|
sqlCommands: [],
|
|
version: targetVersionInfo.version,
|
|
migrationNumber: targetMigration
|
|
};
|
|
}
|
|
|
|
/*
|
|
* Get migrations to apply.
|
|
* Note: when migrating from 9 to 10, we need to execute migration 9 (not 10)
|
|
* because the migration key represents the migration that gets you FROM the source to the next version.
|
|
*/
|
|
const migrationsToApply = VAULT_VERSIONS.filter(
|
|
v => v.revision > currentMigrationNumber &&
|
|
v.revision <= targetMigration
|
|
);
|
|
|
|
const sqlCommands: string[] = [];
|
|
|
|
// Add migration SQL commands
|
|
for (const migration of migrationsToApply) {
|
|
// Use the previous migration number as the key
|
|
const migrationKey = migration.revision - 1;
|
|
const migrationSql = MIGRATION_SCRIPTS[migrationKey];
|
|
if (migrationSql) {
|
|
sqlCommands.push(migrationSql);
|
|
}
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
sqlCommands,
|
|
version: targetVersionInfo.version,
|
|
migrationNumber: targetMigration
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
sqlCommands: [],
|
|
version: '0.0.0',
|
|
migrationNumber: 0,
|
|
error: error instanceof Error ? error.message : 'Unknown error generating upgrade SQL'
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get SQL commands to upgrade vault to latest version
|
|
*/
|
|
getUpgradeToLatestSql(currentMigrationNumber: number): SqlGenerationResult {
|
|
return this.getUpgradeVaultSql(currentMigrationNumber);
|
|
}
|
|
|
|
/**
|
|
* Get SQL commands to upgrade vault to a specific version
|
|
*/
|
|
getUpgradeToVersionSql(currentMigrationNumber: number, targetVersion: string): SqlGenerationResult {
|
|
const targetVersionInfo = VAULT_VERSIONS.find(v => v.version === targetVersion);
|
|
|
|
if (!targetVersionInfo) {
|
|
return {
|
|
success: false,
|
|
sqlCommands: [],
|
|
version: '0.0.0',
|
|
migrationNumber: 0,
|
|
error: `Target version ${targetVersion} not found`
|
|
};
|
|
}
|
|
|
|
return this.getUpgradeVaultSql(currentMigrationNumber, targetVersionInfo.revision);
|
|
}
|
|
|
|
/**
|
|
* Get SQL commands to check current vault version
|
|
*/
|
|
getVersionCheckSql(): string[] {
|
|
return [
|
|
// Check if Settings table exists
|
|
"SELECT name FROM sqlite_master WHERE type='table' AND name='Settings';",
|
|
// Get vault version
|
|
"SELECT Value FROM Settings WHERE Key = 'vault_version' AND IsDeleted = 0 LIMIT 1;",
|
|
// Get migration number
|
|
"SELECT Value FROM Settings WHERE Key = 'vault_migration_number' AND IsDeleted = 0 LIMIT 1;"
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get SQL command to validate vault structure
|
|
*/
|
|
getVaultValidationSql(): string {
|
|
return `SELECT name FROM sqlite_master WHERE type='table' AND name IN
|
|
('Aliases', 'Services', 'Credentials', 'Passwords', 'Attachments', 'EncryptionKeys', 'Settings', 'TotpCodes');`;
|
|
}
|
|
|
|
/**
|
|
* Parse vault version information from query results
|
|
*/
|
|
parseVaultVersionInfo(
|
|
settingsTableExists: boolean,
|
|
versionResult?: string,
|
|
migrationResult?: string
|
|
): VaultVersionInfo {
|
|
let currentVersion = '0.0.0';
|
|
let currentMigrationNumber = 0;
|
|
|
|
if (settingsTableExists) {
|
|
if (versionResult) {
|
|
currentVersion = versionResult;
|
|
} else {
|
|
// Has Settings table but no version info - likely v1.0.0 or v1.1.0
|
|
currentVersion = '1.0.0';
|
|
currentMigrationNumber = 1;
|
|
}
|
|
|
|
if (migrationResult) {
|
|
currentMigrationNumber = parseInt(migrationResult, 10);
|
|
}
|
|
}
|
|
|
|
const latestVersion = VAULT_VERSIONS[VAULT_VERSIONS.length - 1];
|
|
const needsUpgrade = currentMigrationNumber < latestVersion.revision;
|
|
const availableUpgrades = VAULT_VERSIONS.filter(v => v.revision > currentMigrationNumber);
|
|
|
|
return {
|
|
currentVersion,
|
|
currentMigrationNumber,
|
|
targetVersion: latestVersion.version,
|
|
targetMigrationNumber: latestVersion.revision,
|
|
needsUpgrade,
|
|
availableUpgrades
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Validate vault structure from table names
|
|
*/
|
|
validateVaultStructure(tableNames: string[]): boolean {
|
|
const requiredTables = ['Aliases', 'Services', 'Credentials', 'Passwords', 'Attachments', 'EncryptionKeys', 'Settings', 'TotpCodes'];
|
|
const foundTables = tableNames.filter(name => requiredTables.includes(name));
|
|
|
|
// Should have at least 5 core tables (some might not exist in older versions)
|
|
return foundTables.length >= 5;
|
|
}
|
|
|
|
/**
|
|
* Get all available vault versions
|
|
*/
|
|
getAllVersions(): VaultVersion[] {
|
|
return [...VAULT_VERSIONS];
|
|
}
|
|
|
|
/**
|
|
* Get current/latest vault version info
|
|
*/
|
|
getLatestVersion(): VaultVersion {
|
|
return VAULT_VERSIONS[VAULT_VERSIONS.length - 1];
|
|
}
|
|
|
|
/**
|
|
* Get specific migration SQL by migration number
|
|
*/
|
|
getMigrationSql(migrationNumber: number): string | undefined {
|
|
return MIGRATION_SCRIPTS[migrationNumber];
|
|
}
|
|
|
|
/**
|
|
* Get complete schema SQL for creating new vault
|
|
*/
|
|
getCompleteSchemaSql(): string {
|
|
return COMPLETE_SCHEMA_SQL;
|
|
}
|
|
} |