mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-04 14:54:11 -04:00
Refactor vault sql to include release info (#955)
This commit is contained in:
committed by
Leendert de Borst
parent
41b2a959ed
commit
822b95d940
@@ -12,4 +12,5 @@
|
||||
global using AliasVault.Client.Main.Models;
|
||||
global using AliasVault.Client.Services;
|
||||
global using AliasVault.Client.Services.Auth;
|
||||
global using AliasVault.Client.Services.JsInterop;
|
||||
global using AliasVault.Client.Services.Database;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
@inject HttpClient HttpClient
|
||||
@inject JsInteropService JsInteropService
|
||||
@inject DbService DbService
|
||||
@inject Config Config
|
||||
@inject EmailService EmailService
|
||||
@using AliasVault.Shared.Core
|
||||
@inject ILogger<RecentEmails> Logger
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
@inject CredentialService CredentialService
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject AliasVault.Client.Services.QuickCreateStateService QuickCreateStateService
|
||||
@using AliasVault.Client.Services.JsInterop.Models
|
||||
@implements IAsyncDisposable
|
||||
|
||||
<PageHeader
|
||||
@@ -359,13 +360,13 @@ else
|
||||
private async Task GenerateRandomUsername()
|
||||
{
|
||||
// If current object is null, then we create a new random identity.
|
||||
JsInteropService.AliasVaultIdentity identity;
|
||||
AliasVaultIdentity identity;
|
||||
if (Obj.Alias.FirstName is null && Obj.Alias.LastName is null && Obj.Alias.BirthDate == DateTime.MinValue)
|
||||
{
|
||||
// Create new Credential object to avoid modifying the original object
|
||||
var randomIdentity = await CredentialService.GenerateRandomIdentityAsync(CreateNewCredentialObject());
|
||||
|
||||
identity = new JsInteropService.AliasVaultIdentity
|
||||
identity = new AliasVaultIdentity
|
||||
{
|
||||
FirstName = randomIdentity.Alias.FirstName ?? string.Empty,
|
||||
LastName = randomIdentity.Alias.LastName ?? string.Empty,
|
||||
@@ -377,7 +378,7 @@ else
|
||||
else
|
||||
{
|
||||
// Assemble identity model with the current values
|
||||
identity = new JsInteropService.AliasVaultIdentity
|
||||
identity = new AliasVaultIdentity
|
||||
{
|
||||
FirstName = Obj.Alias.FirstName ?? string.Empty,
|
||||
LastName = Obj.Alias.LastName ?? string.Empty,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@inject DbService DbService
|
||||
@using AliasVault.Client.Services.JsInterop.Models
|
||||
@inject DbService DbService
|
||||
@inject GlobalNotificationService GlobalNotificationService
|
||||
|
||||
<div class="relative p-6 sm:p-8 bg-white dark:bg-gray-700 rounded-lg sm:shadow-xl max-w-md w-full mx-auto">
|
||||
@@ -14,11 +15,11 @@
|
||||
<div class="space-y-2">
|
||||
<p class="flex justify-between items-center">
|
||||
<span class="text-sm font-medium text-gray-600 dark:text-gray-400">Your vault:</span>
|
||||
<span class="text-base font-bold text-blue-600 dark:text-blue-400">@CurrentVersion</span>
|
||||
<span class="text-base font-bold text-blue-600 dark:text-blue-400">@(CurrentVersion?.ReleaseVersion ?? "...")</span>
|
||||
</p>
|
||||
<p class="flex justify-between items-center">
|
||||
<span class="text-sm font-medium text-gray-600 dark:text-gray-400">AliasVault latest version:</span>
|
||||
<span class="text-base font-bold text-green-600 dark:text-green-400">@LatestVersion</span>
|
||||
<span class="text-base font-bold text-green-600 dark:text-green-400">@(LatestVersion?.ReleaseVersion ?? "...")</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,8 +48,8 @@
|
||||
@code {
|
||||
private bool IsPendingMigrations { get; set; } = false;
|
||||
private string ErrorMessage { get; set; } = string.Empty;
|
||||
private string CurrentVersion { get; set; } = string.Empty;
|
||||
private string LatestVersion { get; set; } = string.Empty;
|
||||
private SqlVaultVersion? CurrentVersion { get; set; }
|
||||
private SqlVaultVersion? LatestVersion { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task OnInitializedAsync()
|
||||
|
||||
@@ -10,7 +10,9 @@ namespace AliasVault.Client.Services.Database;
|
||||
using System.Data;
|
||||
using System.Net.Http.Json;
|
||||
using AliasClientDb;
|
||||
using AliasVault.Client.Services;
|
||||
using AliasVault.Client.Services.Auth;
|
||||
using AliasVault.Client.Services.JsInterop.Models;
|
||||
using AliasVault.Shared.Models.Enums;
|
||||
using AliasVault.Shared.Models.WebApi.Vault;
|
||||
using Microsoft.Data.Sqlite;
|
||||
@@ -346,9 +348,15 @@ public sealed class DbService : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get current version of database.
|
||||
var currentVersion = await GetCurrentDatabaseVersionAsync();
|
||||
|
||||
// Get latest version from JsInteropService.
|
||||
var latestVersion = await _jsInteropService.GetLatestVaultVersionAsync();
|
||||
|
||||
// TODO: migrate database to the latest version via JS interop...
|
||||
// Call JS interop to get SQL commands to create a new vault with the latest schema.
|
||||
var sqlCommands = await _jsInteropService.GetCreateVaultSqlAsync();
|
||||
var sqlCommands = await _jsInteropService.GetUpgradeVaultSqlAsync(currentVersion.Revision, latestVersion.Revision);
|
||||
|
||||
// Execute the SQL commands to create a new vault with the latest schema.
|
||||
foreach (var sqlCommand in sqlCommands.SqlCommands)
|
||||
@@ -372,10 +380,11 @@ public sealed class DbService : IDisposable
|
||||
/// Get the current version (applied migration) of the database that is loaded in memory.
|
||||
/// </summary>
|
||||
/// <returns>Version as string.</returns>
|
||||
public async Task<string> GetCurrentDatabaseVersionAsync()
|
||||
public async Task<SqlVaultVersion> GetCurrentDatabaseVersionAsync()
|
||||
{
|
||||
var migrations = await _dbContext.Database.GetAppliedMigrationsAsync();
|
||||
var lastMigration = migrations.LastOrDefault();
|
||||
var currentVersion = "Unknown";
|
||||
|
||||
// Convert migration Id in the form of "20240708094944_1.0.0-InitialMigration" to "1.0.0".
|
||||
if (lastMigration is not null)
|
||||
@@ -386,38 +395,41 @@ public sealed class DbService : IDisposable
|
||||
var versionPart = parts[1].Split('-')[0];
|
||||
if (Version.TryParse(versionPart, out _))
|
||||
{
|
||||
return versionPart;
|
||||
currentVersion = versionPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
// Get all available vault versions to get the revision number of the current version.
|
||||
var allVersions = await _jsInteropService.GetAllVaultVersionsAsync();
|
||||
var currentVersionRevision = allVersions.FirstOrDefault(v => v.Version == currentVersion);
|
||||
|
||||
return currentVersionRevision ?? new SqlVaultVersion
|
||||
{
|
||||
Revision = 0,
|
||||
Version = "Unknown",
|
||||
Description = "Unknown",
|
||||
ReleaseDate = DateTime.MinValue,
|
||||
ReleaseVersion = "Unknown",
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the latest available version (EF migration) as defined in code.
|
||||
/// </summary>
|
||||
/// <returns>Version as string.</returns>
|
||||
public async Task<string> GetLatestDatabaseVersionAsync()
|
||||
public async Task<SqlVaultVersion> GetLatestDatabaseVersionAsync()
|
||||
{
|
||||
var migrations = await _dbContext.Database.GetPendingMigrationsAsync();
|
||||
var lastMigration = migrations.LastOrDefault();
|
||||
var allVersions = await _jsInteropService.GetAllVaultVersionsAsync();
|
||||
var latestVersion = allVersions.LastOrDefault();
|
||||
|
||||
// Convert migration Id in the form of "20240708094944_1.0.0-InitialMigration" to "1.0.0".
|
||||
if (lastMigration is not null)
|
||||
return latestVersion ?? new SqlVaultVersion
|
||||
{
|
||||
var parts = lastMigration.Split('_');
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
var versionPart = parts[1].Split('-')[0];
|
||||
if (Version.TryParse(versionPart, out _))
|
||||
{
|
||||
return versionPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
Revision = 0,
|
||||
Version = "Unknown",
|
||||
Description = "Unknown",
|
||||
ReleaseDate = DateTime.MinValue,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -436,7 +448,7 @@ public sealed class DbService : IDisposable
|
||||
{
|
||||
Username = username,
|
||||
Blob = encryptedDatabase,
|
||||
Version = databaseVersion,
|
||||
Version = databaseVersion.Version,
|
||||
CurrentRevisionNumber = _vaultRevisionNumber,
|
||||
EncryptionPublicKey = encryptionKey.PublicKey,
|
||||
CredentialsCount = credentialsCount,
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace AliasVault.Client.Services;
|
||||
namespace AliasVault.Client.Services.JsInterop;
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using AliasVault.Client.Services.JsInterop.Models;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
/// <summary>
|
||||
@@ -454,34 +455,58 @@ public sealed class JsInteropService(IJSRuntime jsRuntime)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all available vault versions.
|
||||
/// </summary>
|
||||
/// <returns>List of vault versions.</returns>
|
||||
public async Task<List<SqlVaultVersion>> GetAllVaultVersionsAsync()
|
||||
{
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
await InitializeAsync();
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to initialize identity generator module");
|
||||
}
|
||||
}
|
||||
|
||||
var vaultGenerator = await _vaultSqlInteropModule.InvokeAsync<IJSObjectReference>("CreateVaultSqlGenerator");
|
||||
var result = await vaultGenerator.InvokeAsync<JsonElement>("getAllVersions");
|
||||
return result.EnumerateArray().Select(x => new SqlVaultVersion
|
||||
{
|
||||
Revision = x.GetProperty("revision").GetInt32(),
|
||||
Version = x.GetProperty("version").GetString() ?? string.Empty,
|
||||
Description = x.GetProperty("description").GetString() ?? string.Empty,
|
||||
ReleaseDate = DateTime.Parse(x.GetProperty("releaseDate").GetString() ?? string.Empty),
|
||||
ReleaseVersion = x.GetProperty("releaseVersion").GetString() ?? string.Empty,
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets SQL commands to check current vault version.
|
||||
/// </summary>
|
||||
/// <returns>Array of SQL commands to execute.</returns>
|
||||
public async Task<string[]> GetVersionCheckSqlAsync()
|
||||
public async Task<SqlVaultVersion> GetLatestVaultVersionAsync()
|
||||
{
|
||||
try
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
await InitializeAsync();
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
await InitializeAsync();
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to initialize identity generator module");
|
||||
}
|
||||
throw new InvalidOperationException("Failed to initialize identity generator module");
|
||||
}
|
||||
}
|
||||
|
||||
var vaultGenerator = await _vaultSqlInteropModule.InvokeAsync<IJSObjectReference>("CreateVaultSqlGenerator");
|
||||
var result = await vaultGenerator.InvokeAsync<JsonElement>("getVersionCheckSql");
|
||||
return result.EnumerateArray()
|
||||
.Select(x => x.GetString() ?? string.Empty)
|
||||
.Where(x => !string.IsNullOrEmpty(x))
|
||||
.ToArray();
|
||||
}
|
||||
catch (JSException)
|
||||
var vaultGenerator = await _vaultSqlInteropModule.InvokeAsync<IJSObjectReference>("CreateVaultSqlGenerator");
|
||||
var result = await vaultGenerator.InvokeAsync<JsonElement>("getLatestVersion");
|
||||
return new SqlVaultVersion
|
||||
{
|
||||
return [];
|
||||
}
|
||||
Revision = result.GetProperty("revision").GetInt32(),
|
||||
Version = result.GetProperty("version").GetString() ?? string.Empty,
|
||||
Description = result.GetProperty("description").GetString() ?? string.Empty,
|
||||
ReleaseDate = DateTime.Parse(result.GetProperty("releaseDate").GetString() ?? string.Empty),
|
||||
ReleaseVersion = result.GetProperty("releaseVersion").GetString() ?? string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -558,52 +583,6 @@ public sealed class JsInteropService(IJSRuntime jsRuntime)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses vault version information from query results.
|
||||
/// </summary>
|
||||
/// <param name="settingsTableExists">Whether Settings table exists.</param>
|
||||
/// <param name="versionResult">Version query result.</param>
|
||||
/// <param name="migrationResult">Migration number query result.</param>
|
||||
/// <returns>Parsed vault version information.</returns>
|
||||
public async Task<VaultVersionInfo> ParseVaultVersionInfoAsync(bool settingsTableExists, string? versionResult = null, string? migrationResult = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
await InitializeAsync();
|
||||
if (_vaultSqlInteropModule == null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to initialize identity generator module");
|
||||
}
|
||||
}
|
||||
|
||||
var vaultGenerator = await _vaultSqlInteropModule.InvokeAsync<IJSObjectReference>("CreateVaultSqlGenerator");
|
||||
var result = await vaultGenerator.InvokeAsync<JsonElement>("parseVaultVersionInfo", settingsTableExists, versionResult, migrationResult);
|
||||
|
||||
return new VaultVersionInfo
|
||||
{
|
||||
CurrentVersion = result.GetProperty("currentVersion").GetString() ?? "0.0.0",
|
||||
CurrentMigrationNumber = result.GetProperty("currentMigrationNumber").GetInt32(),
|
||||
TargetVersion = result.GetProperty("targetVersion").GetString() ?? "0.0.0",
|
||||
TargetMigrationNumber = result.GetProperty("targetMigrationNumber").GetInt32(),
|
||||
NeedsUpgrade = result.GetProperty("needsUpgrade").GetBoolean(),
|
||||
};
|
||||
}
|
||||
catch (JSException ex)
|
||||
{
|
||||
return new VaultVersionInfo
|
||||
{
|
||||
CurrentVersion = "0.0.0",
|
||||
CurrentMigrationNumber = 0,
|
||||
TargetVersion = "0.0.0",
|
||||
TargetMigrationNumber = 0,
|
||||
NeedsUpgrade = true,
|
||||
Error = $"JavaScript error: {ex.Message}",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates vault structure from table names.
|
||||
/// </summary>
|
||||
@@ -631,109 +610,6 @@ public sealed class JsInteropService(IJSRuntime jsRuntime)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of a JavaScript identity generator operation.
|
||||
/// </summary>
|
||||
public sealed class AliasVaultIdentity
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the first name.
|
||||
/// </summary>
|
||||
public string? FirstName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last name.
|
||||
/// </summary>
|
||||
public string? LastName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the birth date.
|
||||
/// </summary>
|
||||
public string? BirthDate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the email prefix.
|
||||
/// </summary>
|
||||
public string? EmailPrefix { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nickname.
|
||||
/// </summary>
|
||||
public string? NickName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gender.
|
||||
/// </summary>
|
||||
public string? Gender { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of SQL generation for vault operations.
|
||||
/// </summary>
|
||||
public sealed class SqlGenerationResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the SQL generation was successful.
|
||||
/// </summary>
|
||||
public bool Success { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the generated SQL commands to execute.
|
||||
/// </summary>
|
||||
public List<string> SqlCommands { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vault version.
|
||||
/// </summary>
|
||||
public string Version { get; init; } = "0.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the migration number.
|
||||
/// </summary>
|
||||
public int MigrationNumber { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional error message.
|
||||
/// </summary>
|
||||
public string? Error { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents vault version information.
|
||||
/// </summary>
|
||||
public sealed class VaultVersionInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current vault version.
|
||||
/// </summary>
|
||||
public string CurrentVersion { get; init; } = "0.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current migration number.
|
||||
/// </summary>
|
||||
public int CurrentMigrationNumber { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target vault version.
|
||||
/// </summary>
|
||||
public string TargetVersion { get; init; } = "0.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target migration number.
|
||||
/// </summary>
|
||||
public int TargetMigrationNumber { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the vault needs to be upgraded.
|
||||
/// </summary>
|
||||
public bool NeedsUpgrade { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional error message.
|
||||
/// </summary>
|
||||
public string? Error { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of a WebAuthn get credential operation.
|
||||
/// </summary>
|
||||
@@ -0,0 +1,44 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="AliasVaultIdentity.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace AliasVault.Client.Services.JsInterop.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of a JavaScript identity generator operation.
|
||||
/// </summary>
|
||||
public sealed class AliasVaultIdentity
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the first name.
|
||||
/// </summary>
|
||||
public string? FirstName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last name.
|
||||
/// </summary>
|
||||
public string? LastName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the birth date.
|
||||
/// </summary>
|
||||
public string? BirthDate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the email prefix.
|
||||
/// </summary>
|
||||
public string? EmailPrefix { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nickname.
|
||||
/// </summary>
|
||||
public string? NickName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gender.
|
||||
/// </summary>
|
||||
public string? Gender { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SqlGenerationResult.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace AliasVault.Client.Services.JsInterop.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of SQL generation for vault operations.
|
||||
/// </summary>
|
||||
public sealed class SqlGenerationResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the SQL generation was successful.
|
||||
/// </summary>
|
||||
public bool Success { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the generated SQL commands to execute.
|
||||
/// </summary>
|
||||
public List<string> SqlCommands { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vault version.
|
||||
/// </summary>
|
||||
public string Version { get; init; } = "0.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the migration number.
|
||||
/// </summary>
|
||||
public int MigrationNumber { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional error message.
|
||||
/// </summary>
|
||||
public string? Error { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SqlVaultVersion.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace AliasVault.Client.Services.JsInterop.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a vault version.
|
||||
/// </summary>
|
||||
public sealed class SqlVaultVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the revision number.
|
||||
/// </summary>
|
||||
public int Revision { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version.
|
||||
/// </summary>
|
||||
public string Version { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
public string Description { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the release date.
|
||||
/// </summary>
|
||||
public DateTime ReleaseDate { get; init; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AliasVault release version that this vault version was introduced in.
|
||||
/// </summary>
|
||||
public string ReleaseVersion { get; init; } = string.Empty;
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
@using AliasVault.Client.Services
|
||||
@using AliasVault.Client.Services.Auth
|
||||
@using AliasVault.Client.Services.Database
|
||||
@using AliasVault.Client.Services.JsInterop;
|
||||
@using AliasVault.RazorComponents
|
||||
@using AliasVault.RazorComponents.Alerts
|
||||
@using AliasVault.RazorComponents.Buttons
|
||||
|
||||
@@ -15,9 +15,16 @@ interface IVaultVersion {
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Release date
|
||||
* Date that this vault version was released.
|
||||
*/
|
||||
releaseDate: string;
|
||||
/**
|
||||
* The AliasVault release that this vault version was introduced in (e.g., "0.14.0").
|
||||
* This value is shown to the user in the UI instead of the actual vault version in order to
|
||||
* avoid potential confusion. The "version" field is the actual vault database version. While
|
||||
* this field is just for display purposes.
|
||||
*/
|
||||
releaseVersion: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,11 +88,11 @@ declare class VaultSqlGenerator {
|
||||
/**
|
||||
* Get all available vault versions
|
||||
*/
|
||||
getAvailableVersions(): IVaultVersion[];
|
||||
getAllVersions(): IVaultVersion[];
|
||||
/**
|
||||
* Get current/latest vault version info
|
||||
*/
|
||||
getCurrentVersion(): IVaultVersion;
|
||||
getLatestVersion(): IVaultVersion;
|
||||
/**
|
||||
* Get specific migration SQL by migration number
|
||||
*/
|
||||
@@ -102,7 +109,9 @@ declare class VaultSqlGenerator {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Available vault versions in chronological order
|
||||
* All vault migrations/versions in chronological order. When adding a new migration, make sure to
|
||||
* update the "releaseVersion" field to the correct AliasVault release version that introduced this
|
||||
* migration.
|
||||
*/
|
||||
declare const VAULT_VERSIONS: IVaultVersion[];
|
||||
|
||||
|
||||
@@ -15,9 +15,16 @@ interface IVaultVersion {
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Release date
|
||||
* Date that this vault version was released.
|
||||
*/
|
||||
releaseDate: string;
|
||||
/**
|
||||
* The AliasVault release that this vault version was introduced in (e.g., "0.14.0").
|
||||
* This value is shown to the user in the UI instead of the actual vault version in order to
|
||||
* avoid potential confusion. The "version" field is the actual vault database version. While
|
||||
* this field is just for display purposes.
|
||||
*/
|
||||
releaseVersion: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,11 +88,11 @@ declare class VaultSqlGenerator {
|
||||
/**
|
||||
* Get all available vault versions
|
||||
*/
|
||||
getAvailableVersions(): IVaultVersion[];
|
||||
getAllVersions(): IVaultVersion[];
|
||||
/**
|
||||
* Get current/latest vault version info
|
||||
*/
|
||||
getCurrentVersion(): IVaultVersion;
|
||||
getLatestVersion(): IVaultVersion;
|
||||
/**
|
||||
* Get specific migration SQL by migration number
|
||||
*/
|
||||
@@ -102,7 +109,9 @@ declare class VaultSqlGenerator {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Available vault versions in chronological order
|
||||
* All vault migrations/versions in chronological order. When adding a new migration, make sure to
|
||||
* update the "releaseVersion" field to the correct AliasVault release version that introduced this
|
||||
* migration.
|
||||
*/
|
||||
declare const VAULT_VERSIONS: IVaultVersion[];
|
||||
|
||||
|
||||
@@ -480,55 +480,64 @@ var VAULT_VERSIONS = [
|
||||
revision: 1,
|
||||
version: "1.0.1",
|
||||
description: "Empty Test Migration",
|
||||
releaseDate: "2024-07-08"
|
||||
releaseDate: "2024-07-08",
|
||||
releaseVersion: "0.2.0"
|
||||
},
|
||||
{
|
||||
revision: 2,
|
||||
version: "1.0.2",
|
||||
description: "Change Email Column",
|
||||
releaseDate: "2024-07-11"
|
||||
releaseDate: "2024-07-11",
|
||||
releaseVersion: "0.3.0"
|
||||
},
|
||||
{
|
||||
revision: 3,
|
||||
version: "1.1.0",
|
||||
description: "Add Pki Tables",
|
||||
releaseDate: "2024-07-29"
|
||||
releaseDate: "2024-07-29",
|
||||
releaseVersion: "0.4.0"
|
||||
},
|
||||
{
|
||||
revision: 4,
|
||||
version: "1.2.0",
|
||||
description: "Add Settings Table",
|
||||
releaseDate: "2024-08-05"
|
||||
releaseDate: "2024-08-05",
|
||||
releaseVersion: "0.4.0"
|
||||
},
|
||||
{
|
||||
revision: 5,
|
||||
version: "1.3.0",
|
||||
description: "Update Identity Structure",
|
||||
releaseDate: "2024-08-05"
|
||||
releaseDate: "2024-08-05",
|
||||
releaseVersion: "0.5.0"
|
||||
},
|
||||
{
|
||||
revision: 6,
|
||||
version: "1.3.1",
|
||||
description: "Make Username Optional",
|
||||
releaseDate: "2024-08-12"
|
||||
releaseDate: "2024-08-12",
|
||||
releaseVersion: "0.5.0"
|
||||
},
|
||||
{
|
||||
revision: 7,
|
||||
version: "1.4.0",
|
||||
description: "Add Sync Support",
|
||||
releaseDate: "2024-09-16"
|
||||
releaseDate: "2024-09-16",
|
||||
releaseVersion: "0.6.0"
|
||||
},
|
||||
{
|
||||
revision: 8,
|
||||
version: "1.4.1",
|
||||
description: "Rename Attachments Plural",
|
||||
releaseDate: "2024-09-17"
|
||||
releaseDate: "2024-09-17",
|
||||
releaseVersion: "0.6.0"
|
||||
},
|
||||
{
|
||||
revision: 9,
|
||||
version: "1.5.0",
|
||||
description: "Add Totp Codes",
|
||||
releaseDate: "2025-03-10"
|
||||
releaseDate: "2025-03-10",
|
||||
releaseVersion: "0.14.0"
|
||||
}
|
||||
];
|
||||
|
||||
@@ -704,13 +713,13 @@ var VaultSqlGenerator = class {
|
||||
/**
|
||||
* Get all available vault versions
|
||||
*/
|
||||
getAvailableVersions() {
|
||||
getAllVersions() {
|
||||
return [...VAULT_VERSIONS];
|
||||
}
|
||||
/**
|
||||
* Get current/latest vault version info
|
||||
*/
|
||||
getCurrentVersion() {
|
||||
getLatestVersion() {
|
||||
return VAULT_VERSIONS[VAULT_VERSIONS.length - 1];
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -451,55 +451,64 @@ var VAULT_VERSIONS = [
|
||||
revision: 1,
|
||||
version: "1.0.1",
|
||||
description: "Empty Test Migration",
|
||||
releaseDate: "2024-07-08"
|
||||
releaseDate: "2024-07-08",
|
||||
releaseVersion: "0.2.0"
|
||||
},
|
||||
{
|
||||
revision: 2,
|
||||
version: "1.0.2",
|
||||
description: "Change Email Column",
|
||||
releaseDate: "2024-07-11"
|
||||
releaseDate: "2024-07-11",
|
||||
releaseVersion: "0.3.0"
|
||||
},
|
||||
{
|
||||
revision: 3,
|
||||
version: "1.1.0",
|
||||
description: "Add Pki Tables",
|
||||
releaseDate: "2024-07-29"
|
||||
releaseDate: "2024-07-29",
|
||||
releaseVersion: "0.4.0"
|
||||
},
|
||||
{
|
||||
revision: 4,
|
||||
version: "1.2.0",
|
||||
description: "Add Settings Table",
|
||||
releaseDate: "2024-08-05"
|
||||
releaseDate: "2024-08-05",
|
||||
releaseVersion: "0.4.0"
|
||||
},
|
||||
{
|
||||
revision: 5,
|
||||
version: "1.3.0",
|
||||
description: "Update Identity Structure",
|
||||
releaseDate: "2024-08-05"
|
||||
releaseDate: "2024-08-05",
|
||||
releaseVersion: "0.5.0"
|
||||
},
|
||||
{
|
||||
revision: 6,
|
||||
version: "1.3.1",
|
||||
description: "Make Username Optional",
|
||||
releaseDate: "2024-08-12"
|
||||
releaseDate: "2024-08-12",
|
||||
releaseVersion: "0.5.0"
|
||||
},
|
||||
{
|
||||
revision: 7,
|
||||
version: "1.4.0",
|
||||
description: "Add Sync Support",
|
||||
releaseDate: "2024-09-16"
|
||||
releaseDate: "2024-09-16",
|
||||
releaseVersion: "0.6.0"
|
||||
},
|
||||
{
|
||||
revision: 8,
|
||||
version: "1.4.1",
|
||||
description: "Rename Attachments Plural",
|
||||
releaseDate: "2024-09-17"
|
||||
releaseDate: "2024-09-17",
|
||||
releaseVersion: "0.6.0"
|
||||
},
|
||||
{
|
||||
revision: 9,
|
||||
version: "1.5.0",
|
||||
description: "Add Totp Codes",
|
||||
releaseDate: "2025-03-10"
|
||||
releaseDate: "2025-03-10",
|
||||
releaseVersion: "0.14.0"
|
||||
}
|
||||
];
|
||||
|
||||
@@ -675,13 +684,13 @@ var VaultSqlGenerator = class {
|
||||
/**
|
||||
* Get all available vault versions
|
||||
*/
|
||||
getAvailableVersions() {
|
||||
getAllVersions() {
|
||||
return [...VAULT_VERSIONS];
|
||||
}
|
||||
/**
|
||||
* Get current/latest vault version info
|
||||
*/
|
||||
getCurrentVersion() {
|
||||
getLatestVersion() {
|
||||
return VAULT_VERSIONS[VAULT_VERSIONS.length - 1];
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -151,63 +151,6 @@ EOF
|
||||
echo "TypeScript constants file generated: $OUTPUT_FILE"
|
||||
echo "Total migrations processed: ${#migration_files[@]}"
|
||||
|
||||
# Now generate the vault versions file
|
||||
echo ""
|
||||
echo "Generating vault versions mapping..."
|
||||
|
||||
# Start building the vault versions file
|
||||
cat > "$VERSIONS_FILE" << 'EOF'
|
||||
/**
|
||||
* Vault version information
|
||||
* Auto-generated from EF Core migration filenames
|
||||
*/
|
||||
|
||||
import { IVaultVersion } from "../types/VaultVersion";
|
||||
|
||||
/**
|
||||
* Available vault versions in chronological order
|
||||
*/
|
||||
export const VAULT_VERSIONS: IVaultVersion[] = [
|
||||
EOF
|
||||
|
||||
# Remove: declare -A versions_seen
|
||||
last_version=""
|
||||
for file in "${migration_files[@]}"; do
|
||||
filename=$(basename "$file")
|
||||
# Extract revision from filename prefix
|
||||
revision=$(echo "$filename" | sed -n 's/^0*\([0-9]*\)_.*$/\1/p')
|
||||
# Debug: print filename
|
||||
echo "DEBUG: Processing file $filename"
|
||||
last_segment=$(echo "$filename" | awk -F'_to_' '{print $NF}' | sed 's/\.sql$//')
|
||||
echo "DEBUG: Last segment: $last_segment"
|
||||
version_info=$(extract_version_info "$filename")
|
||||
version=$(echo "$version_info" | cut -d'|' -f1)
|
||||
description=$(echo "$version_info" | cut -d'|' -f2)
|
||||
release_date=$(echo "$version_info" | cut -d'|' -f3)
|
||||
|
||||
echo "DEBUG: $filename -> revision='$revision', version='$version', description='$description', release_date='$release_date'"
|
||||
|
||||
# Only output if version is not empty and not a duplicate of the last one
|
||||
if [ -n "$version" ] && [ -n "$description" ] && [ "$version" != "$last_version" ]; then
|
||||
last_version="$version"
|
||||
echo "Found version $version: $description ($release_date)"
|
||||
cat >> "$VERSIONS_FILE" << EOF
|
||||
{
|
||||
revision: $revision,
|
||||
version: '$version',
|
||||
description: '$description',
|
||||
releaseDate: '$release_date'
|
||||
},
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
# Close the vault versions file
|
||||
cat >> "$VERSIONS_FILE" << 'EOF'
|
||||
];
|
||||
EOF
|
||||
|
||||
echo "Vault versions file generated: $VERSIONS_FILE"
|
||||
|
||||
# Copy generated files to shared vault-sql directory
|
||||
echo ""
|
||||
@@ -223,9 +166,6 @@ fi
|
||||
# Copy SqlConstants.ts
|
||||
copy_to_shared_sql "$OUTPUT_FILE" "$SHARED_SQL_DIR/SqlConstants.ts"
|
||||
|
||||
# Copy VaultVersions.ts
|
||||
copy_to_shared_sql "$VERSIONS_FILE" "$SHARED_SQL_DIR/VaultVersions.ts"
|
||||
|
||||
echo ""
|
||||
echo "Done!"
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ echo "- SQL files: MigrationSql/"
|
||||
echo "- TypeScript files: MigrationTs/"
|
||||
echo ""
|
||||
echo "The TypeScript files have been copied to the shared vault-sql directory."
|
||||
echo "Make sure to rebuild the vault-sql library and test it in the client apps."
|
||||
echo ""
|
||||
echo "Next, make sure to add the new vault SQL migrations to the VaultVersions.ts file in the vault-sql library."
|
||||
echo ""
|
||||
echo "Afterwards, run the following command to build and distribute the vault-sql library:"
|
||||
echo "shared/build-and-distribute.sh"
|
||||
@@ -12,11 +12,12 @@ This guide explains how to upgrade the AliasVault client database structure. The
|
||||
|
||||
## Overview
|
||||
|
||||
The upgrade process involves three main steps:
|
||||
The upgrade process involves four main steps:
|
||||
|
||||
1. **Update .NET Entity Framework model** - Modify the EF model and create migrations
|
||||
2. **Generate SQL scripts** - Convert EF migrations to SQL scripts for cross-platform use
|
||||
3. **Rebuild vault-sql shared library** - Compile and distribute the updated SQL scripts
|
||||
3. **Add new migrations to VaultVersions** - Manually update the TypeScript version list
|
||||
4. **Rebuild vault-sql shared library** - Compile and distribute the updated SQL scripts
|
||||
|
||||
---
|
||||
|
||||
@@ -55,16 +56,25 @@ The script will:
|
||||
|
||||
---
|
||||
|
||||
## 3. Rebuild vault-sql Shared Library
|
||||
## 3. Add New Migrations to VaultVersions
|
||||
|
||||
### Step 3.1: Compile and Distribute
|
||||
### Step 3.1: Update VaultVersions.ts
|
||||
Manually update the `shared/vault-sql/src/sql/VaultVersions.ts` file to include the new migration(s) with the proper fields.
|
||||
|
||||
This step ensures that the TypeScript version list is synchronized with the generated SQL scripts and maintains proper version tracking across all client platforms. This list is also used by the client app to detect if there are new migrations that should be applied, and what information to show to the user.
|
||||
|
||||
---
|
||||
|
||||
## 4. Rebuild vault-sql Shared Library
|
||||
|
||||
### Step 4.1: Compile and Distribute
|
||||
The vault-sql TypeScript library is consumed by web apps, browser extensions, and mobile apps for vault creation and updates. After generating the SQL scripts, rebuild the library:
|
||||
|
||||
```bash
|
||||
shared/build-and-distribute.sh
|
||||
```
|
||||
|
||||
### Step 3.2: Verify Distribution
|
||||
### Step 4.2: Verify Distribution
|
||||
Ensure the updated library is properly distributed to all consuming applications.
|
||||
|
||||
---
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { VaultSqlGenerator } from '../sql/VaultSqlGenerator.js';
|
||||
import { CURRENT_VAULT_VERSION } from '../types/VaultVersion.js';
|
||||
import { VaultSqlGenerator } from '../sql/VaultSqlGenerator';
|
||||
|
||||
describe('VaultSqlGenerator', () => {
|
||||
const generator = new VaultSqlGenerator();
|
||||
|
||||
describe('getCreateVaultSql', () => {
|
||||
it('should return SQL commands for creating a new vault', () => {
|
||||
const result = VaultSqlGenerator.getCreateVaultSql();
|
||||
const result = generator.getCreateVaultSql();
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.sqlCommands.length).toBeGreaterThan(0);
|
||||
expect(result.version).toBe(CURRENT_VAULT_VERSION.version);
|
||||
expect(result.migrationNumber).toBe(CURRENT_VAULT_VERSION.migrationNumber);
|
||||
expect(result.version).toBe(generator.getLatestVersion().version);
|
||||
expect(result.migrationNumber).toBe(generator.getLatestVersion().revision);
|
||||
|
||||
// Should include PRAGMA and schema creation
|
||||
expect(result.sqlCommands[0]).toBe('PRAGMA foreign_keys = ON;');
|
||||
@@ -21,16 +22,16 @@ describe('VaultSqlGenerator', () => {
|
||||
|
||||
describe('getUpgradeVaultSql', () => {
|
||||
it('should return empty commands when vault is already at target version', () => {
|
||||
const result = VaultSqlGenerator.getUpgradeVaultSql(CURRENT_VAULT_VERSION.migrationNumber);
|
||||
const result = generator.getUpgradeVaultSql(generator.getLatestVersion().revision);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.sqlCommands).toEqual([]);
|
||||
expect(result.version).toBe(CURRENT_VAULT_VERSION.version);
|
||||
expect(result.migrationNumber).toBe(CURRENT_VAULT_VERSION.migrationNumber);
|
||||
expect(result.version).toBe(generator.getLatestVersion().version);
|
||||
expect(result.migrationNumber).toBe(generator.getLatestVersion().revision);
|
||||
});
|
||||
|
||||
it('should return upgrade commands for older version', () => {
|
||||
const result = VaultSqlGenerator.getUpgradeVaultSql(1, 3); // Upgrade from v1.0.0 to v1.1.0
|
||||
const result = generator.getUpgradeVaultSql(1, 3); // Upgrade from v1.0.0 to v1.1.0
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.sqlCommands.length).toBeGreaterThan(0);
|
||||
@@ -41,7 +42,7 @@ describe('VaultSqlGenerator', () => {
|
||||
});
|
||||
|
||||
it('should handle invalid target migration number', () => {
|
||||
const result = VaultSqlGenerator.getUpgradeVaultSql(1, 999);
|
||||
const result = generator.getUpgradeVaultSql(1, 999);
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('not found');
|
||||
@@ -50,14 +51,14 @@ describe('VaultSqlGenerator', () => {
|
||||
|
||||
describe('getUpgradeToVersionSql', () => {
|
||||
it('should upgrade to specific version', () => {
|
||||
const result = VaultSqlGenerator.getUpgradeToVersionSql(1, '1.2.0');
|
||||
const result = generator.getUpgradeToVersionSql(1, '1.2.0');
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.sqlCommands.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should handle invalid version', () => {
|
||||
const result = VaultSqlGenerator.getUpgradeToVersionSql(1, '99.99.99');
|
||||
const result = generator.getUpgradeToVersionSql(1, '99.99.99');
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('not found');
|
||||
@@ -66,7 +67,7 @@ describe('VaultSqlGenerator', () => {
|
||||
|
||||
describe('getVersionCheckSql', () => {
|
||||
it('should return SQL commands to check vault version', () => {
|
||||
const commands = VaultSqlGenerator.getVersionCheckSql();
|
||||
const commands = generator.getVersionCheckSql();
|
||||
|
||||
expect(commands.length).toBe(3);
|
||||
expect(commands[0]).toContain('sqlite_master');
|
||||
@@ -77,7 +78,7 @@ describe('VaultSqlGenerator', () => {
|
||||
|
||||
describe('getVaultValidationSql', () => {
|
||||
it('should return SQL to validate vault structure', () => {
|
||||
const sql = VaultSqlGenerator.getVaultValidationSql();
|
||||
const sql = generator.getVaultValidationSql();
|
||||
|
||||
expect(sql).toContain('sqlite_master');
|
||||
expect(sql).toContain('Aliases');
|
||||
@@ -88,15 +89,15 @@ describe('VaultSqlGenerator', () => {
|
||||
|
||||
describe('parseVaultVersionInfo', () => {
|
||||
it('should parse vault version info correctly', () => {
|
||||
const info = VaultSqlGenerator.parseVaultVersionInfo(true, '1.2.0', '4');
|
||||
const info = generator.parseVaultVersionInfo(true, '1.2.0', '4');
|
||||
|
||||
expect(info.currentVersion).toBe('1.2.0');
|
||||
expect(info.currentMigrationNumber).toBe(4);
|
||||
expect(info.needsUpgrade).toBe(info.currentMigrationNumber < CURRENT_VAULT_VERSION.migrationNumber);
|
||||
expect(info.needsUpgrade).toBe(info.currentMigrationNumber < generator.getLatestVersion().revision);
|
||||
});
|
||||
|
||||
it('should handle missing Settings table', () => {
|
||||
const info = VaultSqlGenerator.parseVaultVersionInfo(false);
|
||||
const info = generator.parseVaultVersionInfo(false);
|
||||
|
||||
expect(info.currentVersion).toBe('0.0.0');
|
||||
expect(info.currentMigrationNumber).toBe(0);
|
||||
@@ -104,7 +105,7 @@ describe('VaultSqlGenerator', () => {
|
||||
});
|
||||
|
||||
it('should handle Settings table without version info', () => {
|
||||
const info = VaultSqlGenerator.parseVaultVersionInfo(true);
|
||||
const info = generator.parseVaultVersionInfo(true);
|
||||
|
||||
expect(info.currentVersion).toBe('1.0.0');
|
||||
expect(info.currentMigrationNumber).toBe(1);
|
||||
@@ -114,21 +115,21 @@ describe('VaultSqlGenerator', () => {
|
||||
describe('validateVaultStructure', () => {
|
||||
it('should validate vault with all required tables', () => {
|
||||
const tables = ['Aliases', 'Services', 'Credentials', 'Passwords', 'Settings'];
|
||||
const isValid = VaultSqlGenerator.validateVaultStructure(tables);
|
||||
const isValid = generator.validateVaultStructure(tables);
|
||||
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should reject vault with missing core tables', () => {
|
||||
const tables = ['Aliases', 'Services'];
|
||||
const isValid = VaultSqlGenerator.validateVaultStructure(tables);
|
||||
const isValid = generator.validateVaultStructure(tables);
|
||||
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle case-insensitive table names', () => {
|
||||
const tables = ['aliases', 'services', 'credentials', 'passwords'];
|
||||
const isValid = VaultSqlGenerator.validateVaultStructure(tables);
|
||||
const isValid = generator.validateVaultStructure(tables);
|
||||
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
@@ -136,27 +137,27 @@ describe('VaultSqlGenerator', () => {
|
||||
|
||||
describe('utility methods', () => {
|
||||
it('should return available versions', () => {
|
||||
const versions = VaultSqlGenerator.getAvailableVersions();
|
||||
const versions = generator.getAllVersions();
|
||||
|
||||
expect(versions.length).toBeGreaterThan(0);
|
||||
expect(versions[0].version).toBe('1.0.0');
|
||||
});
|
||||
|
||||
it('should return current version', () => {
|
||||
const version = VaultSqlGenerator.getCurrentVersion();
|
||||
const version = generator.getLatestVersion();
|
||||
|
||||
expect(version).toEqual(CURRENT_VAULT_VERSION);
|
||||
expect(version).toEqual(generator.getLatestVersion());
|
||||
});
|
||||
|
||||
it('should return migration SQL by number', () => {
|
||||
const sql = VaultSqlGenerator.getMigrationSql(1);
|
||||
const sql = generator.getMigrationSql(1);
|
||||
|
||||
expect(sql).toBeDefined();
|
||||
expect(sql).toContain('CREATE TABLE');
|
||||
});
|
||||
|
||||
it('should return complete schema SQL', () => {
|
||||
const sql = VaultSqlGenerator.getCompleteSchemaeSql();
|
||||
const sql = generator.getCompleteSchemaSql();
|
||||
|
||||
expect(sql).toBeDefined();
|
||||
expect(sql).toContain('CREATE TABLE "Aliases"');
|
||||
|
||||
@@ -234,14 +234,14 @@ export class VaultSqlGenerator {
|
||||
/**
|
||||
* Get all available vault versions
|
||||
*/
|
||||
getAvailableVersions(): IVaultVersion[] {
|
||||
getAllVersions(): IVaultVersion[] {
|
||||
return [...VAULT_VERSIONS];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current/latest vault version info
|
||||
*/
|
||||
getCurrentVersion(): IVaultVersion {
|
||||
getLatestVersion(): IVaultVersion {
|
||||
return VAULT_VERSIONS[VAULT_VERSIONS.length - 1];
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ export class VaultSqlGenerator {
|
||||
/**
|
||||
* Get complete schema SQL for creating new vault
|
||||
*/
|
||||
getCompleteSchemaeSql(): string {
|
||||
getCompleteSchemaSql(): string {
|
||||
return COMPLETE_SCHEMA_SQL;
|
||||
}
|
||||
}
|
||||
@@ -6,61 +6,72 @@
|
||||
import { IVaultVersion } from "../types/VaultVersion";
|
||||
|
||||
/**
|
||||
* Available vault versions in chronological order
|
||||
* All vault migrations/versions in chronological order. When adding a new migration, make sure to
|
||||
* update the "releaseVersion" field to the correct AliasVault release version that introduced this
|
||||
* migration.
|
||||
*/
|
||||
export const VAULT_VERSIONS: IVaultVersion[] = [
|
||||
{
|
||||
revision: 1,
|
||||
version: '1.0.1',
|
||||
description: 'Empty Test Migration',
|
||||
releaseDate: '2024-07-08'
|
||||
releaseDate: '2024-07-08',
|
||||
releaseVersion: '0.2.0',
|
||||
},
|
||||
{
|
||||
revision: 2,
|
||||
version: '1.0.2',
|
||||
description: 'Change Email Column',
|
||||
releaseDate: '2024-07-11'
|
||||
releaseDate: '2024-07-11',
|
||||
releaseVersion: '0.3.0',
|
||||
},
|
||||
{
|
||||
revision: 3,
|
||||
version: '1.1.0',
|
||||
description: 'Add Pki Tables',
|
||||
releaseDate: '2024-07-29'
|
||||
releaseDate: '2024-07-29',
|
||||
releaseVersion: '0.4.0',
|
||||
},
|
||||
{
|
||||
revision: 4,
|
||||
version: '1.2.0',
|
||||
description: 'Add Settings Table',
|
||||
releaseDate: '2024-08-05'
|
||||
releaseDate: '2024-08-05',
|
||||
releaseVersion: '0.4.0',
|
||||
},
|
||||
{
|
||||
revision: 5,
|
||||
version: '1.3.0',
|
||||
description: 'Update Identity Structure',
|
||||
releaseDate: '2024-08-05'
|
||||
releaseDate: '2024-08-05',
|
||||
releaseVersion: '0.5.0',
|
||||
},
|
||||
{
|
||||
revision: 6,
|
||||
version: '1.3.1',
|
||||
description: 'Make Username Optional',
|
||||
releaseDate: '2024-08-12'
|
||||
releaseDate: '2024-08-12',
|
||||
releaseVersion: '0.5.0',
|
||||
},
|
||||
{
|
||||
revision: 7,
|
||||
version: '1.4.0',
|
||||
description: 'Add Sync Support',
|
||||
releaseDate: '2024-09-16'
|
||||
releaseDate: '2024-09-16',
|
||||
releaseVersion: '0.6.0',
|
||||
},
|
||||
{
|
||||
revision: 8,
|
||||
version: '1.4.1',
|
||||
description: 'Rename Attachments Plural',
|
||||
releaseDate: '2024-09-17'
|
||||
releaseDate: '2024-09-17',
|
||||
releaseVersion: '0.6.0',
|
||||
},
|
||||
{
|
||||
revision: 9,
|
||||
version: '1.5.0',
|
||||
description: 'Add Totp Codes',
|
||||
releaseDate: '2025-03-10'
|
||||
releaseDate: '2025-03-10',
|
||||
releaseVersion: '0.14.0',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -18,7 +18,15 @@ export interface IVaultVersion {
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* Release date
|
||||
* Date that this vault version was released.
|
||||
*/
|
||||
releaseDate: string;
|
||||
|
||||
/**
|
||||
* The AliasVault release that this vault version was introduced in (e.g., "0.14.0").
|
||||
* This value is shown to the user in the UI instead of the actual vault version in order to
|
||||
* avoid potential confusion. The "version" field is the actual vault database version. While
|
||||
* this field is just for display purposes.
|
||||
*/
|
||||
releaseVersion: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user