From 985ee2469e417e2ae1ebfb675343c9ec175e3e65 Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Tue, 2 Dec 2025 14:36:08 +0100 Subject: [PATCH] Cleanup FieldKey const (#1404) --- .../utils/dist/shared/models/vault/index.d.ts | 10 ----- .../utils/dist/shared/models/vault/index.js | 25 ----------- .../utils/dist/shared/vault-sql/index.d.mts | 2 +- .../utils/dist/shared/vault-sql/index.d.ts | 2 +- .../src/utils/dist/shared/vault-sql/index.js | 44 +++++++++---------- .../src/utils/dist/shared/vault-sql/index.mjs | 44 +++++++++---------- .../utils/dist/shared/models/vault/index.d.ts | 10 ----- .../utils/dist/shared/models/vault/index.js | 25 ----------- .../utils/dist/shared/vault-sql/index.d.mts | 2 +- .../utils/dist/shared/vault-sql/index.d.ts | 2 +- .../utils/dist/shared/vault-sql/index.js | 44 +++++++++---------- .../utils/dist/shared/vault-sql/index.mjs | 44 +++++++++---------- .../js/dist/shared/vault-sql/index.d.mts | 2 +- .../js/dist/shared/vault-sql/index.d.ts | 2 +- .../wwwroot/js/dist/shared/vault-sql/index.js | 44 +++++++++---------- .../js/dist/shared/vault-sql/index.mjs | 44 +++++++++---------- .../AliasClientDb/FieldDefinition.cs | 3 +- ...6211441_1.7.0-FieldBasedDataModelUpdate.cs | 2 +- .../Scripts/MigrationSql/000_FullSchema.sql | 22 +++++----- ...211441_1.7.0-FieldBasedDataModelUpdate.sql | 22 +++++----- shared/models/src/vault/FieldKey.ts | 32 -------------- shared/vault-sql/src/sql/SqlConstants.ts | 44 +++++++++---------- 22 files changed, 184 insertions(+), 287 deletions(-) diff --git a/apps/browser-extension/src/utils/dist/shared/models/vault/index.d.ts b/apps/browser-extension/src/utils/dist/shared/models/vault/index.d.ts index ef085bb22..f343835b8 100644 --- a/apps/browser-extension/src/utils/dist/shared/models/vault/index.d.ts +++ b/apps/browser-extension/src/utils/dist/shared/models/vault/index.d.ts @@ -266,16 +266,6 @@ declare const FieldKey: { * Type: Text */ readonly IdentityCountry: "identity.country"; - /** - * API key value field - * Type: Password - */ - readonly ApiKeyKey: "apikey.key"; - /** - * API key type/provider field (e.g., "OpenAI", "Stripe") - * Type: Text - */ - readonly ApiKeyType: "apikey.type"; /** * Alias email field * Type: Email diff --git a/apps/browser-extension/src/utils/dist/shared/models/vault/index.js b/apps/browser-extension/src/utils/dist/shared/models/vault/index.js index 220509d74..bfd93ec24 100644 --- a/apps/browser-extension/src/utils/dist/shared/models/vault/index.js +++ b/apps/browser-extension/src/utils/dist/shared/models/vault/index.js @@ -4,9 +4,6 @@ // src/vault/FieldKey.ts var FieldKey = { - // ============================================================ - // Login Fields - // ============================================================ /** * Login username field * Type: Text @@ -32,9 +29,6 @@ var FieldKey = { * Type: Text */ LoginRecoveryCodes: "login.recovery_codes", - // ============================================================ - // Credit Card Fields - // ============================================================ /** * Credit card number field * Type: Text @@ -65,9 +59,6 @@ var FieldKey = { * Type: Password */ CardPin: "card.pin", - // ============================================================ - // Identity Fields - // ============================================================ /** * Identity title field (e.g., Mr., Mrs., Dr.) * Type: Text @@ -128,22 +119,6 @@ var FieldKey = { * Type: Text */ IdentityCountry: "identity.country", - // ============================================================ - // API Key Fields - // ============================================================ - /** - * API key value field - * Type: Password - */ - ApiKeyKey: "apikey.key", - /** - * API key type/provider field (e.g., "OpenAI", "Stripe") - * Type: Text - */ - ApiKeyType: "apikey.type", - // ============================================================ - // Alias Fields (Legacy - from old Alias table) - // ============================================================ /** * Alias email field * Type: Email diff --git a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.mts b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.mts index bdecdd221..1baf54f74 100644 --- a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.mts +++ b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.mts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\",\"ApiKey\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n \n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n \n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n \n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n\n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n\n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n\n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n\n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n\n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.ts b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.ts index bdecdd221..1baf54f74 100644 --- a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.ts +++ b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.d.ts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\",\"ApiKey\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n \n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n \n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n \n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n\n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n\n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n\n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n\n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n\n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.js b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.js index 713315360..52177ea15 100644 --- a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.js +++ b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.js @@ -830,7 +830,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -841,7 +841,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -856,7 +856,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -872,7 +872,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -888,7 +888,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -904,7 +904,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -919,7 +919,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -934,7 +934,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -953,7 +953,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -975,7 +975,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1067,7 +1067,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1945,7 +1945,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1956,7 +1956,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1971,7 +1971,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1987,7 +1987,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -2003,7 +2003,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2019,7 +2019,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2034,7 +2034,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2049,7 +2049,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2068,7 +2068,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2090,7 +2090,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2182,7 +2182,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.mjs b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.mjs index 1b1b417d8..d1f406b14 100644 --- a/apps/browser-extension/src/utils/dist/shared/vault-sql/index.mjs +++ b/apps/browser-extension/src/utils/dist/shared/vault-sql/index.mjs @@ -798,7 +798,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -809,7 +809,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -824,7 +824,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -840,7 +840,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -856,7 +856,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -872,7 +872,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -887,7 +887,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -902,7 +902,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -921,7 +921,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -943,7 +943,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1035,7 +1035,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1913,7 +1913,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1924,7 +1924,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1939,7 +1939,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1955,7 +1955,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -1971,7 +1971,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -1987,7 +1987,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2002,7 +2002,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2017,7 +2017,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2036,7 +2036,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2058,7 +2058,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2150,7 +2150,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/mobile-app/utils/dist/shared/models/vault/index.d.ts b/apps/mobile-app/utils/dist/shared/models/vault/index.d.ts index ef085bb22..f343835b8 100644 --- a/apps/mobile-app/utils/dist/shared/models/vault/index.d.ts +++ b/apps/mobile-app/utils/dist/shared/models/vault/index.d.ts @@ -266,16 +266,6 @@ declare const FieldKey: { * Type: Text */ readonly IdentityCountry: "identity.country"; - /** - * API key value field - * Type: Password - */ - readonly ApiKeyKey: "apikey.key"; - /** - * API key type/provider field (e.g., "OpenAI", "Stripe") - * Type: Text - */ - readonly ApiKeyType: "apikey.type"; /** * Alias email field * Type: Email diff --git a/apps/mobile-app/utils/dist/shared/models/vault/index.js b/apps/mobile-app/utils/dist/shared/models/vault/index.js index 220509d74..bfd93ec24 100644 --- a/apps/mobile-app/utils/dist/shared/models/vault/index.js +++ b/apps/mobile-app/utils/dist/shared/models/vault/index.js @@ -4,9 +4,6 @@ // src/vault/FieldKey.ts var FieldKey = { - // ============================================================ - // Login Fields - // ============================================================ /** * Login username field * Type: Text @@ -32,9 +29,6 @@ var FieldKey = { * Type: Text */ LoginRecoveryCodes: "login.recovery_codes", - // ============================================================ - // Credit Card Fields - // ============================================================ /** * Credit card number field * Type: Text @@ -65,9 +59,6 @@ var FieldKey = { * Type: Password */ CardPin: "card.pin", - // ============================================================ - // Identity Fields - // ============================================================ /** * Identity title field (e.g., Mr., Mrs., Dr.) * Type: Text @@ -128,22 +119,6 @@ var FieldKey = { * Type: Text */ IdentityCountry: "identity.country", - // ============================================================ - // API Key Fields - // ============================================================ - /** - * API key value field - * Type: Password - */ - ApiKeyKey: "apikey.key", - /** - * API key type/provider field (e.g., "OpenAI", "Stripe") - * Type: Text - */ - ApiKeyType: "apikey.type", - // ============================================================ - // Alias Fields (Legacy - from old Alias table) - // ============================================================ /** * Alias email field * Type: Email diff --git a/apps/mobile-app/utils/dist/shared/vault-sql/index.d.mts b/apps/mobile-app/utils/dist/shared/vault-sql/index.d.mts index bdecdd221..1baf54f74 100644 --- a/apps/mobile-app/utils/dist/shared/vault-sql/index.d.mts +++ b/apps/mobile-app/utils/dist/shared/vault-sql/index.d.mts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\",\"ApiKey\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n \n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n \n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n \n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n\n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n\n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n\n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n\n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n\n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/mobile-app/utils/dist/shared/vault-sql/index.d.ts b/apps/mobile-app/utils/dist/shared/vault-sql/index.d.ts index bdecdd221..1baf54f74 100644 --- a/apps/mobile-app/utils/dist/shared/vault-sql/index.d.ts +++ b/apps/mobile-app/utils/dist/shared/vault-sql/index.d.ts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\",\"ApiKey\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n \n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n \n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n \n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n\n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n\n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n\n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n\n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n\n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/mobile-app/utils/dist/shared/vault-sql/index.js b/apps/mobile-app/utils/dist/shared/vault-sql/index.js index 713315360..52177ea15 100644 --- a/apps/mobile-app/utils/dist/shared/vault-sql/index.js +++ b/apps/mobile-app/utils/dist/shared/vault-sql/index.js @@ -830,7 +830,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -841,7 +841,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -856,7 +856,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -872,7 +872,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -888,7 +888,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -904,7 +904,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -919,7 +919,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -934,7 +934,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -953,7 +953,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -975,7 +975,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1067,7 +1067,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1945,7 +1945,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1956,7 +1956,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1971,7 +1971,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1987,7 +1987,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -2003,7 +2003,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2019,7 +2019,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2034,7 +2034,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2049,7 +2049,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2068,7 +2068,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2090,7 +2090,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2182,7 +2182,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/mobile-app/utils/dist/shared/vault-sql/index.mjs b/apps/mobile-app/utils/dist/shared/vault-sql/index.mjs index 1b1b417d8..d1f406b14 100644 --- a/apps/mobile-app/utils/dist/shared/vault-sql/index.mjs +++ b/apps/mobile-app/utils/dist/shared/vault-sql/index.mjs @@ -798,7 +798,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -809,7 +809,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -824,7 +824,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -840,7 +840,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -856,7 +856,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -872,7 +872,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -887,7 +887,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -902,7 +902,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -921,7 +921,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -943,7 +943,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1035,7 +1035,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1913,7 +1913,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1924,7 +1924,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1939,7 +1939,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1955,7 +1955,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -1971,7 +1971,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -1987,7 +1987,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2002,7 +2002,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2017,7 +2017,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2036,7 +2036,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2058,7 +2058,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2150,7 +2150,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.mts b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.mts index bdecdd221..1baf54f74 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.mts +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.mts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\",\"ApiKey\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n \n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n \n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n \n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n\n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n\n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n\n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n\n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n\n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.ts b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.ts index bdecdd221..1baf54f74 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.ts +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.d.ts @@ -122,7 +122,7 @@ declare const VAULT_VERSIONS: VaultVersion[]; * Complete database schema SQL (latest version) * Auto-generated from EF Core migrations */ -declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\",\"ApiKey\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n \n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n \n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n \n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n \n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; +declare const COMPLETE_SCHEMA_SQL = "\n\uFEFFCREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nBEGIN TRANSACTION;\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"Gender\" VARCHAR NULL,\n \"FirstName\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"BirthDate\" TEXT NOT NULL,\n \"AddressStreet\" VARCHAR NULL,\n \"AddressCity\" VARCHAR NULL,\n \"AddressState\" VARCHAR NULL,\n \"AddressZipCode\" VARCHAR NULL,\n \"AddressCountry\" VARCHAR NULL,\n \"Hobbies\" TEXT NULL,\n \"EmailPrefix\" TEXT NULL,\n \"PhoneMobile\" TEXT NULL,\n \"BankAccountIBAN\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"Username\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"ServiceId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachment\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachment\" PRIMARY KEY,\n \"Filename\" TEXT NOT NULL,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachment_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Attachment_CredentialId\" ON \"Attachment\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708094944_1.0.0-InitialMigration', '9.0.4');\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240708224522_1.0.1-EmptyTestMigration', '9.0.4');\n\nALTER TABLE \"Aliases\" RENAME COLUMN \"EmailPrefix\" TO \"Email\";\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240711204207_1.0.2-ChangeEmailColumn', '9.0.4');\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240729105618_1.1.0-AddPkiTables', '9.0.4');\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805073413_1.2.0-AddSettingsTable', '9.0.4');\n\nCREATE TABLE \"ef_temp_Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL\n);\n\nINSERT INTO \"ef_temp_Aliases\" (\"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\")\nSELECT \"Id\", \"BirthDate\", \"CreatedAt\", \"Email\", \"FirstName\", \"Gender\", \"LastName\", \"NickName\", \"UpdatedAt\"\nFROM \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Aliases\";\n\nALTER TABLE \"ef_temp_Aliases\" RENAME TO \"Aliases\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240805122422_1.3.0-UpdateIdentityStructure', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"ef_temp_Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Credentials\" (\"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\")\nSELECT \"Id\", \"AliasId\", \"CreatedAt\", \"Notes\", \"ServiceId\", \"UpdatedAt\", \"Username\"\nFROM \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Credentials\";\n\nALTER TABLE \"ef_temp_Credentials\" RENAME TO \"Credentials\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\n\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240812141727_1.3.1-MakeUsernameOptional', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Settings\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Services\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Passwords\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"EncryptionKeys\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Credentials\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Attachment\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nALTER TABLE \"Aliases\" ADD \"IsDeleted\" INTEGER NOT NULL DEFAULT 0;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240916105320_1.4.0-AddSyncSupport', '9.0.4');\n\nALTER TABLE \"Attachment\" RENAME TO \"Attachments\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"CredentialId\", \"Filename\", \"IsDeleted\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20240917191243_1.4.1-RenameAttachmentsPlural', '9.0.4');\n\nBEGIN TRANSACTION;\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20250310131554_1.5.0-AddTotpCodes', '9.0.4');\n\n\nPRAGMA foreign_keys = OFF;\n\n-- Clean up any existing temp tables first\nDROP TABLE IF EXISTS \"__EFMigrationsHistory_temp\";\nDROP TABLE IF EXISTS \"Aliases_temp\";\nDROP TABLE IF EXISTS \"Services_temp\";\nDROP TABLE IF EXISTS \"EncryptionKeys_temp\";\nDROP TABLE IF EXISTS \"Settings_temp\";\nDROP TABLE IF EXISTS \"Credentials_temp\";\nDROP TABLE IF EXISTS \"Attachments_temp\";\nDROP TABLE IF EXISTS \"Passwords_temp\";\nDROP TABLE IF EXISTS \"TotpCodes_temp\";\n\n-- Create backup tables for all data\nCREATE TABLE \"__EFMigrationsHistory_temp\" AS SELECT * FROM \"__EFMigrationsHistory\";\nCREATE TABLE \"Aliases_temp\" AS SELECT * FROM \"Aliases\";\nCREATE TABLE \"Services_temp\" AS SELECT * FROM \"Services\";\nCREATE TABLE \"EncryptionKeys_temp\" AS SELECT * FROM \"EncryptionKeys\";\nCREATE TABLE \"Settings_temp\" AS SELECT * FROM \"Settings\";\nCREATE TABLE \"Credentials_temp\" AS SELECT * FROM \"Credentials\";\nCREATE TABLE \"Attachments_temp\" AS SELECT * FROM \"Attachments\";\nCREATE TABLE \"Passwords_temp\" AS SELECT * FROM \"Passwords\";\nCREATE TABLE \"TotpCodes_temp\" AS SELECT * FROM \"TotpCodes\";\n\n-- Delete orphaned records that do not have a valid FK to the credential object\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Delete orphaned credentials that do not have valid FKs to alias or service objects\nDELETE FROM \"Credentials_temp\" WHERE \"AliasId\" NOT IN (SELECT \"Id\" FROM \"Aliases_temp\");\nDELETE FROM \"Credentials_temp\" WHERE \"ServiceId\" NOT IN (SELECT \"Id\" FROM \"Services_temp\");\n\n-- After cleaning credentials, clean dependent tables again in case we removed credentials\nDELETE FROM \"Attachments_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"Passwords_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\nDELETE FROM \"TotpCodes_temp\" WHERE \"CredentialId\" NOT IN (SELECT \"Id\" FROM \"Credentials_temp\");\n\n-- Drop all existing tables\nDROP TABLE \"TotpCodes\";\nDROP TABLE \"Passwords\";\nDROP TABLE \"Attachments\";\nDROP TABLE \"Credentials\";\nDROP TABLE \"Settings\";\nDROP TABLE \"EncryptionKeys\";\nDROP TABLE \"Services\";\nDROP TABLE \"Aliases\";\nDROP TABLE \"__EFMigrationsHistory\";\n\n-- Recreate tables with proper constraints (no dependencies first)\nCREATE TABLE \"__EFMigrationsHistory\" (\n \"MigrationId\" TEXT NOT NULL CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY,\n \"ProductVersion\" TEXT NOT NULL\n);\n\nCREATE TABLE \"Aliases\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Aliases\" PRIMARY KEY,\n \"BirthDate\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Email\" TEXT NULL,\n \"FirstName\" VARCHAR NULL,\n \"Gender\" VARCHAR NULL,\n \"LastName\" VARCHAR NULL,\n \"NickName\" VARCHAR NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Services\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Services\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"Url\" TEXT NULL,\n \"Logo\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"EncryptionKeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_EncryptionKeys\" PRIMARY KEY,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"IsPrimary\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE \"Settings\" (\n \"Key\" TEXT NOT NULL CONSTRAINT \"PK_Settings\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0\n);\n\n-- Tables with foreign keys\nCREATE TABLE \"Credentials\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Credentials\" PRIMARY KEY,\n \"AliasId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Notes\" TEXT NULL,\n \"ServiceId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Username\" TEXT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Credentials_Aliases_AliasId\" FOREIGN KEY (\"AliasId\") REFERENCES \"Aliases\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_Credentials_Services_ServiceId\" FOREIGN KEY (\"ServiceId\") REFERENCES \"Services\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Passwords\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passwords\" PRIMARY KEY,\n \"Value\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_Passwords_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL DEFAULT 0,\n CONSTRAINT \"FK_TotpCodes_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\n\n-- Restore data from temp tables\nINSERT INTO \"__EFMigrationsHistory\" SELECT * FROM \"__EFMigrationsHistory_temp\";\nINSERT INTO \"Aliases\" SELECT * FROM \"Aliases_temp\";\nINSERT INTO \"Services\" SELECT * FROM \"Services_temp\";\nINSERT INTO \"EncryptionKeys\" SELECT * FROM \"EncryptionKeys_temp\";\nINSERT INTO \"Settings\" SELECT * FROM \"Settings_temp\";\nINSERT INTO \"Credentials\" SELECT * FROM \"Credentials_temp\";\nINSERT INTO \"Attachments\" SELECT * FROM \"Attachments_temp\";\nINSERT INTO \"Passwords\" SELECT * FROM \"Passwords_temp\";\nINSERT INTO \"TotpCodes\" SELECT * FROM \"TotpCodes_temp\";\n\n-- =====================================================================================\n-- Date Format Normalization Migration\n-- =====================================================================================\n-- This migration normalizes ALL date fields to the standard format: 'yyyy-MM-dd HH:mm:ss.fff'\n-- Previously the different clients used different date formats which complicate date parsing.\n-- From version 0.24.0 onwards, all new dates are stored in this standard format.\n\n-- Update Aliases table (CreatedAt, UpdatedAt, BirthDate)\nUPDATE \"Aliases\" SET \"CreatedAt\" =\n CASE\n -- Already in correct format (yyyy-MM-dd HH:mm:ss.fff) - no change\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n\n -- ISO 8601 with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ) -> Replace T with space, remove Z and everything after .fff\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n\n -- Without milliseconds (yyyy-MM-dd HH:mm:ss or yyyy-MM-ddTHH:mm:ssZ) -> Add .000\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n\n -- Fallback: if none match, keep as-is (edge case)\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Aliases\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- BirthDate: Always set time to 00:00:00 (no milliseconds for birth dates)\nUPDATE \"Aliases\" SET \"BirthDate\" =\n CASE\n -- If empty or already '0001-01-01 00:00:00', keep as-is\n WHEN \"BirthDate\" = '' OR \"BirthDate\" = '0001-01-01 00:00:00'\n THEN \"BirthDate\"\n\n -- If already in correct format (yyyy-MM-dd 00:00:00), keep as-is\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 00:00:00'\n THEN \"BirthDate\"\n\n -- Extract date part and set time to 00:00:00\n WHEN \"BirthDate\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'\n THEN substr(\"BirthDate\", 1, 10) || ' 00:00:00'\n\n -- Fallback\n ELSE \"BirthDate\"\n END;\n\n-- Update Services table (CreatedAt, UpdatedAt)\nUPDATE \"Services\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Services\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update EncryptionKeys table (CreatedAt, UpdatedAt)\nUPDATE \"EncryptionKeys\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"EncryptionKeys\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Settings table (CreatedAt, UpdatedAt)\nUPDATE \"Settings\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Settings\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Credentials table (CreatedAt, UpdatedAt)\nUPDATE \"Credentials\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Credentials\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Attachments table (CreatedAt, UpdatedAt)\nUPDATE \"Attachments\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Attachments\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update Passwords table (CreatedAt, UpdatedAt)\nUPDATE \"Passwords\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"Passwords\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- Update TotpCodes table (CreatedAt, UpdatedAt)\nUPDATE \"TotpCodes\" SET \"CreatedAt\" =\n CASE\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"CreatedAt\"\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(\"CreatedAt\", 12, 12)\n WHEN \"CreatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"CreatedAt\", 1, 10) || ' ' || substr(replace(\"CreatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"CreatedAt\"\n END;\n\nUPDATE \"TotpCodes\" SET \"UpdatedAt\" =\n CASE\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]'\n THEN \"UpdatedAt\"\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(\"UpdatedAt\", 12, 12)\n WHEN \"UpdatedAt\" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][T ][0-9][0-9]:[0-9][0-9]:[0-9][0-9]*'\n THEN substr(\"UpdatedAt\", 1, 10) || ' ' || substr(replace(\"UpdatedAt\", 'T', ' '), 12, 8) || '.000'\n ELSE \"UpdatedAt\"\n END;\n\n-- =====================================================================================\n-- End of Date Format Normalization Migration\n-- =====================================================================================\n\n-- Recreate indexes\nCREATE INDEX \"IX_Credentials_AliasId\" ON \"Credentials\" (\"AliasId\");\nCREATE INDEX \"IX_Credentials_ServiceId\" ON \"Credentials\" (\"ServiceId\");\nCREATE INDEX \"IX_Attachments_CredentialId\" ON \"Attachments\" (\"CredentialId\");\nCREATE INDEX \"IX_Passwords_CredentialId\" ON \"Passwords\" (\"CredentialId\");\nCREATE INDEX \"IX_TotpCodes_CredentialId\" ON \"TotpCodes\" (\"CredentialId\");\n\n-- Clean up temp tables\nDROP TABLE \"__EFMigrationsHistory_temp\";\nDROP TABLE \"Aliases_temp\";\nDROP TABLE \"Services_temp\";\nDROP TABLE \"EncryptionKeys_temp\";\nDROP TABLE \"Settings_temp\";\nDROP TABLE \"Credentials_temp\";\nDROP TABLE \"Attachments_temp\";\nDROP TABLE \"Passwords_temp\";\nDROP TABLE \"TotpCodes_temp\";\n\nPRAGMA foreign_keys = ON;\n\n\nCREATE TABLE \"Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"AdditionalData\" BLOB NULL,\n \"CredentialId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Passkeys_Credentials_CredentialId\" FOREIGN KEY (\"CredentialId\") REFERENCES \"Credentials\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_Passkeys_CredentialId\" ON \"Passkeys\" (\"CredentialId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251014122838_1.6.0-AddPasskeys', '9.0.4');\n\nALTER TABLE \"TotpCodes\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_TotpCodes_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nALTER TABLE \"Passkeys\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Passkeys_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nALTER TABLE \"Attachments\" RENAME COLUMN \"CredentialId\" TO \"ItemId\";\n\nDROP INDEX IF EXISTS \"IX_Attachments_CredentialId\";\n\nCREATE INDEX IF NOT EXISTS \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE TABLE \"FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"FieldKey\" TEXT NULL,\n \"EntityType\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"DefaultVisibility\" TEXT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Folders\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Folders\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"ParentFolderId\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Folders_Folders_ParentFolderId\" FOREIGN KEY (\"ParentFolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"Logos\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Logos\" PRIMARY KEY,\n \"Source\" TEXT NOT NULL,\n \"FileData\" BLOB NULL,\n \"MimeType\" TEXT NULL,\n \"FetchedAt\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL\n);\n\nCREATE TABLE \"Items\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Items\" PRIMARY KEY,\n \"Name\" TEXT NULL,\n \"ItemType\" TEXT NOT NULL,\n \"LogoId\" TEXT NULL,\n \"FolderId\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_Items_Folders_FolderId\" FOREIGN KEY (\"FolderId\") REFERENCES \"Folders\" (\"Id\") ON DELETE SET NULL,\n CONSTRAINT \"FK_Items_Logos_LogoId\" FOREIGN KEY (\"LogoId\") REFERENCES \"Logos\" (\"Id\") ON DELETE SET NULL\n);\n\nCREATE TABLE \"FieldHistories\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldHistories\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"ValueSnapshot\" TEXT NOT NULL,\n \"ChangedAt\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldHistories_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldHistories_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE TABLE \"FieldValues\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldValues\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"FieldDefinitionId\" TEXT NOT NULL,\n \"Value\" TEXT NULL,\n \"ValueIndex\" INTEGER NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_FieldValues_FieldDefinitions_FieldDefinitionId\" FOREIGN KEY (\"FieldDefinitionId\") REFERENCES \"FieldDefinitions\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_FieldValues_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldHistories_FieldDefinitionId\" ON \"FieldHistories\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldHistories_ItemId\" ON \"FieldHistories\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_FieldDefinitionId\" ON \"FieldValues\" (\"FieldDefinitionId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"ValueIndex\");\n\nCREATE INDEX \"IX_Folders_ParentFolderId\" ON \"Folders\" (\"ParentFolderId\");\n\nCREATE INDEX \"IX_Items_FolderId\" ON \"Items\" (\"FolderId\");\n\nCREATE INDEX \"IX_Items_LogoId\" ON \"Items\" (\"LogoId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\n\n -- Login fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n -- Alias fields\n INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted)\n VALUES\n (lower(hex(randomblob(16))), 'alias.email', 'Item', 'Email', 'Alias Email', 0, 'Visible', 1, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.first_name', 'Item', 'Text', 'First Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.last_name', 'Item', 'Text', 'Last Name', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0),\n (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '[\"Login\"]', datetime('now'), datetime('now'), 0);\n\n\n\n INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n c.Id,\n s.Name AS Name,\n 'Login' AS ItemType,\n NULL AS LogoId,\n NULL AS FolderId,\n c.CreatedAt,\n c.UpdatedAt,\n c.IsDeleted\n FROM Credentials c\n LEFT JOIN Services s ON s.Id = c.ServiceId;\n\n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n s.Url AS Source,\n s.Logo AS FileData,\n 'image/png' AS MimeType,\n NULL AS FetchedAt,\n MIN(s.CreatedAt) AS CreatedAt,\n MAX(s.UpdatedAt) AS UpdatedAt,\n 0 AS IsDeleted\n FROM Services s\n WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != ''\n GROUP BY s.Url;\n\n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON s.Url = l.Source\n INNER JOIN Credentials c ON c.ServiceId = s.Id\n WHERE c.Id = Items.Id\n LIMIT 1\n )\n WHERE EXISTS (\n SELECT 1 FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE c.Id = Items.Id AND s.Logo IS NOT NULL\n );\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.url' LIMIT 1) AS FieldDefinitionId,\n s.Url AS Value,\n 0 AS ValueIndex,\n s.UpdatedAt AS CreatedAt,\n s.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Services s ON s.Id = c.ServiceId\n WHERE s.Url IS NOT NULL AND s.Url != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.username' LIMIT 1) AS FieldDefinitionId,\n c.Username AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Username IS NOT NULL AND c.Username != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.notes' LIMIT 1) AS FieldDefinitionId,\n c.Notes AS Value,\n 0 AS ValueIndex,\n c.UpdatedAt AS CreatedAt,\n c.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n WHERE c.Notes IS NOT NULL AND c.Notes != '';\n\n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n p.Value AS Value,\n 0 AS ValueIndex,\n p.UpdatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated;\n\n\n\n INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'login.password' LIMIT 1) AS FieldDefinitionId,\n '{\"values\":[\"' || p.Value || '\"]}' AS ValueSnapshot,\n p.UpdatedAt AS ChangedAt,\n p.CreatedAt AS CreatedAt,\n p.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Passwords p\n WHERE p.Id NOT IN (\n SELECT p2.Id FROM Passwords p2\n INNER JOIN (\n SELECT CredentialId, MAX(UpdatedAt) AS MaxUpdated\n FROM Passwords\n GROUP BY CredentialId\n ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated\n );\n\n\n\n -- Migrate Alias.Email\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.email' LIMIT 1) AS FieldDefinitionId,\n a.Email AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Email IS NOT NULL AND a.Email != '';\n\n -- Migrate Alias.FirstName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.first_name' LIMIT 1) AS FieldDefinitionId,\n a.FirstName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.FirstName IS NOT NULL AND a.FirstName != '';\n\n -- Migrate Alias.LastName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.last_name' LIMIT 1) AS FieldDefinitionId,\n a.LastName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.LastName IS NOT NULL AND a.LastName != '';\n\n -- Migrate Alias.NickName\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.nickname' LIMIT 1) AS FieldDefinitionId,\n a.NickName AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.NickName IS NOT NULL AND a.NickName != '';\n\n -- Migrate Alias.Gender\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.gender' LIMIT 1) AS FieldDefinitionId,\n a.Gender AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.Gender IS NOT NULL AND a.Gender != '';\n\n -- Migrate Alias.BirthDate\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n (SELECT Id FROM FieldDefinitions WHERE FieldKey = 'alias.birthdate' LIMIT 1) AS FieldDefinitionId,\n a.BirthDate AS Value,\n 0 AS ValueIndex,\n a.UpdatedAt AS CreatedAt,\n a.UpdatedAt AS UpdatedAt,\n 0 AS IsDeleted\n FROM Credentials c\n INNER JOIN Aliases a ON a.Id = c.AliasId\n WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000';\n\n\nDROP TABLE \"Passwords\";\n\nDROP TABLE \"Credentials\";\n\nDROP TABLE \"Aliases\";\n\nDROP TABLE \"Services\";\n\nCREATE TABLE \"ef_temp_Attachments\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Attachments\" PRIMARY KEY,\n \"Blob\" BLOB NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"Filename\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_Attachments_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Attachments\" (\"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\")\nSELECT \"Id\", \"Blob\", \"CreatedAt\", \"Filename\", \"IsDeleted\", \"ItemId\", \"UpdatedAt\"\nFROM \"Attachments\";\n\nCREATE TABLE \"ef_temp_Passkeys\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Passkeys\" PRIMARY KEY,\n \"AdditionalData\" BLOB NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"DisplayName\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"PrfKey\" BLOB NULL,\n \"PrivateKey\" TEXT NOT NULL,\n \"PublicKey\" TEXT NOT NULL,\n \"RpId\" TEXT COLLATE NOCASE NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"UserHandle\" BLOB NOT NULL,\n CONSTRAINT \"FK_Passkeys_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_Passkeys\" (\"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\")\nSELECT \"Id\", \"AdditionalData\", \"CreatedAt\", \"DisplayName\", \"IsDeleted\", \"ItemId\", \"PrfKey\", \"PrivateKey\", \"PublicKey\", \"RpId\", \"UpdatedAt\", \"UserHandle\"\nFROM \"Passkeys\";\n\nCREATE TABLE \"ef_temp_TotpCodes\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_TotpCodes\" PRIMARY KEY,\n \"CreatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"ItemId\" TEXT NOT NULL,\n \"Name\" TEXT NOT NULL,\n \"SecretKey\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n CONSTRAINT \"FK_TotpCodes_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE\n);\n\nINSERT INTO \"ef_temp_TotpCodes\" (\"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\")\nSELECT \"Id\", \"CreatedAt\", \"IsDeleted\", \"ItemId\", \"Name\", \"SecretKey\", \"UpdatedAt\"\nFROM \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"Attachments\";\n\nALTER TABLE \"ef_temp_Attachments\" RENAME TO \"Attachments\";\n\nDROP TABLE \"Passkeys\";\n\nALTER TABLE \"ef_temp_Passkeys\" RENAME TO \"Passkeys\";\n\nDROP TABLE \"TotpCodes\";\n\nALTER TABLE \"ef_temp_TotpCodes\" RENAME TO \"TotpCodes\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_Attachments_ItemId\" ON \"Attachments\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_ItemId\" ON \"Passkeys\" (\"ItemId\");\n\nCREATE INDEX \"IX_Passkeys_RpId\" ON \"Passkeys\" (\"RpId\");\n\nCREATE INDEX \"IX_TotpCodes_ItemId\" ON \"TotpCodes\" (\"ItemId\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126211441_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n\nBEGIN TRANSACTION;\nALTER TABLE \"Folders\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldValues\" RENAME COLUMN \"ValueIndex\" TO \"Weight\";\n\nDROP INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_ValueIndex\";\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nALTER TABLE \"FieldDefinitions\" RENAME COLUMN \"DisplayOrder\" TO \"Weight\";\n\nALTER TABLE \"FieldDefinitions\" ADD \"IsHidden\" INTEGER NOT NULL DEFAULT 0;\n\nCREATE TABLE \"ef_temp_FieldDefinitions\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_FieldDefinitions\" PRIMARY KEY,\n \"ApplicableToTypes\" TEXT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"FieldKey\" TEXT NULL,\n \"FieldType\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"Weight\" INTEGER NOT NULL\n);\n\nINSERT INTO \"ef_temp_FieldDefinitions\" (\"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\")\nSELECT \"Id\", \"ApplicableToTypes\", \"CreatedAt\", \"EnableHistory\", \"FieldKey\", \"FieldType\", \"IsDeleted\", \"IsHidden\", \"IsMultiValue\", \"Label\", \"UpdatedAt\", \"Weight\"\nFROM \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 0;\n\nBEGIN TRANSACTION;\nDROP TABLE \"FieldDefinitions\";\n\nALTER TABLE \"ef_temp_FieldDefinitions\" RENAME TO \"FieldDefinitions\";\n\nCOMMIT;\n\nPRAGMA foreign_keys = 1;\n\nBEGIN TRANSACTION;\nCREATE INDEX \"IX_FieldDefinitions_FieldKey\" ON \"FieldDefinitions\" (\"FieldKey\");\n\nCOMMIT;\n\nINSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\")\nVALUES ('20251126221717_1.7.1-RenameColumns', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.js b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.js index 713315360..52177ea15 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.js +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.js @@ -830,7 +830,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -841,7 +841,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -856,7 +856,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -872,7 +872,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -888,7 +888,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -904,7 +904,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -919,7 +919,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -934,7 +934,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -953,7 +953,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -975,7 +975,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1067,7 +1067,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1945,7 +1945,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1956,7 +1956,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1971,7 +1971,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1987,7 +1987,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -2003,7 +2003,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2019,7 +2019,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2034,7 +2034,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2049,7 +2049,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2068,7 +2068,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2090,7 +2090,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2182,7 +2182,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.mjs b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.mjs index 1b1b417d8..d1f406b14 100644 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.mjs +++ b/apps/server/AliasVault.Client/wwwroot/js/dist/shared/vault-sql/index.mjs @@ -798,7 +798,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -809,7 +809,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -824,7 +824,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -840,7 +840,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -856,7 +856,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -872,7 +872,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -887,7 +887,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -902,7 +902,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -921,7 +921,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -943,7 +943,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1035,7 +1035,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1913,7 +1913,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1924,7 +1924,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1939,7 +1939,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1955,7 +1955,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -1971,7 +1971,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -1987,7 +1987,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2002,7 +2002,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2017,7 +2017,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2036,7 +2036,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2058,7 +2058,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2150,7 +2150,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/server/Databases/AliasClientDb/FieldDefinition.cs b/apps/server/Databases/AliasClientDb/FieldDefinition.cs index 527be90f7..4235fd43a 100644 --- a/apps/server/Databases/AliasClientDb/FieldDefinition.cs +++ b/apps/server/Databases/AliasClientDb/FieldDefinition.cs @@ -28,7 +28,6 @@ public class FieldDefinition : SyncableEntity /// - login.username, login.password, login.notes, login.url /// - card.number, card.cardholder_name, card.cvv /// - identity.first_name, identity.email, identity.phone_numbers - /// - apikey.key, apikey.type /// - alias.email, alias.first_name (legacy) /// Custom fields have FieldKey = NULL and are identified by their GUID and Label. /// @@ -70,7 +69,7 @@ public class FieldDefinition : SyncableEntity public int Weight { get; set; } = 0; /// - /// Gets or sets the applicable item types as JSON array (e.g., '["Login","ApiKey"]'). + /// Gets or sets the applicable item types as JSON array (e.g., '["Login","Identity"]'). /// Null means applicable to all types. /// public string? ApplicableToTypes { get; set; } diff --git a/apps/server/Databases/AliasClientDb/Migrations/20251126211441_1.7.0-FieldBasedDataModelUpdate.cs b/apps/server/Databases/AliasClientDb/Migrations/20251126211441_1.7.0-FieldBasedDataModelUpdate.cs index c488fab52..d5d1e77e9 100644 --- a/apps/server/Databases/AliasClientDb/Migrations/20251126211441_1.7.0-FieldBasedDataModelUpdate.cs +++ b/apps/server/Databases/AliasClientDb/Migrations/20251126211441_1.7.0-FieldBasedDataModelUpdate.cs @@ -293,7 +293,7 @@ namespace AliasClientDb.Migrations (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '[""Login""]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '[""Login""]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[""Login"",""ApiKey""]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '[""Login""]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) diff --git a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql index 3227f47d9..5527062e3 100644 --- a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql +++ b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/000_FullSchema.sql @@ -792,7 +792,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -803,7 +803,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -818,7 +818,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -834,7 +834,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -850,7 +850,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -866,7 +866,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -881,7 +881,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -896,7 +896,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -915,7 +915,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -937,7 +937,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1029,7 +1029,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251126211441_1.7.0-FieldBasedDataModelUpdate.sql b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251126211441_1.7.0-FieldBasedDataModelUpdate.sql index 2c2acb164..67e3bd99e 100644 --- a/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251126211441_1.7.0-FieldBasedDataModelUpdate.sql +++ b/apps/server/Databases/AliasClientDb/Scripts/MigrationSql/011_20251014122838_1.6.0-AddPasskeys_to_20251126211441_1.7.0-FieldBasedDataModelUpdate.sql @@ -121,7 +121,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -132,7 +132,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -147,7 +147,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -163,7 +163,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -179,7 +179,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -195,7 +195,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -210,7 +210,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -225,7 +225,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -244,7 +244,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -266,7 +266,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -358,7 +358,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; diff --git a/shared/models/src/vault/FieldKey.ts b/shared/models/src/vault/FieldKey.ts index dcf5af859..0e4b2426a 100644 --- a/shared/models/src/vault/FieldKey.ts +++ b/shared/models/src/vault/FieldKey.ts @@ -19,10 +19,6 @@ * ``` */ export const FieldKey = { - // ============================================================ - // Login Fields - // ============================================================ - /** * Login username field * Type: Text @@ -53,10 +49,6 @@ export const FieldKey = { */ LoginRecoveryCodes: 'login.recovery_codes', - // ============================================================ - // Credit Card Fields - // ============================================================ - /** * Credit card number field * Type: Text @@ -93,10 +85,6 @@ export const FieldKey = { */ CardPin: 'card.pin', - // ============================================================ - // Identity Fields - // ============================================================ - /** * Identity title field (e.g., Mr., Mrs., Dr.) * Type: Text @@ -169,26 +157,6 @@ export const FieldKey = { */ IdentityCountry: 'identity.country', - // ============================================================ - // API Key Fields - // ============================================================ - - /** - * API key value field - * Type: Password - */ - ApiKeyKey: 'apikey.key', - - /** - * API key type/provider field (e.g., "OpenAI", "Stripe") - * Type: Text - */ - ApiKeyType: 'apikey.type', - - // ============================================================ - // Alias Fields (Legacy - from old Alias table) - // ============================================================ - /** * Alias email field * Type: Email diff --git a/shared/vault-sql/src/sql/SqlConstants.ts b/shared/vault-sql/src/sql/SqlConstants.ts index 779f7c2c8..95eba78c7 100644 --- a/shared/vault-sql/src/sql/SqlConstants.ts +++ b/shared/vault-sql/src/sql/SqlConstants.ts @@ -799,7 +799,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -810,7 +810,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -825,7 +825,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -841,7 +841,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -857,7 +857,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -873,7 +873,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -888,7 +888,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -903,7 +903,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -922,7 +922,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -944,7 +944,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -1036,7 +1036,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords"; @@ -1918,7 +1918,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'login.username', 'Item', 'Text', 'Username', 0, 'Visible', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.password', 'Item', 'Password', 'Password', 0, 'Hidden', 1, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'login.notes', 'Item', 'Text', 'Notes', 0, 'Collapsed', 0, 0, NULL, datetime('now'), datetime('now'), 0), - (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login","ApiKey"]', datetime('now'), datetime('now'), 0); + (lower(hex(randomblob(16))), 'login.url', 'Item', 'URL', 'Website URLs', 1, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); -- Alias fields INSERT INTO FieldDefinitions (Id, FieldKey, EntityType, FieldType, Label, IsMultiValue, DefaultVisibility, EnableHistory, DisplayOrder, ApplicableToTypes, CreatedAt, UpdatedAt, IsDeleted) @@ -1929,7 +1929,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); (lower(hex(randomblob(16))), 'alias.nickname', 'Item', 'Text', 'Nickname', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.gender', 'Item', 'Text', 'Gender', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0), (lower(hex(randomblob(16))), 'alias.birthdate', 'Item', 'Date', 'Birth Date', 0, 'Visible', 0, 0, '["Login"]', datetime('now'), datetime('now'), 0); - + INSERT INTO Items (Id, Name, ItemType, LogoId, FolderId, CreatedAt, UpdatedAt, IsDeleted) @@ -1944,7 +1944,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); c.IsDeleted FROM Credentials c LEFT JOIN Services s ON s.Id = c.ServiceId; - + INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -1960,7 +1960,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Services s WHERE s.Logo IS NOT NULL AND s.Url IS NOT NULL AND s.Url != '' GROUP BY s.Url; - + UPDATE Items @@ -1976,7 +1976,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); INNER JOIN Services s ON s.Id = c.ServiceId WHERE c.Id = Items.Id AND s.Logo IS NOT NULL ); - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -1992,7 +1992,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Services s ON s.Id = c.ServiceId WHERE s.Url IS NOT NULL AND s.Url != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2007,7 +2007,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Username IS NOT NULL AND c.Username != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2022,7 +2022,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); 0 AS IsDeleted FROM Credentials c WHERE c.Notes IS NOT NULL AND c.Notes != ''; - + INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, Value, ValueIndex, CreatedAt, UpdatedAt, IsDeleted) @@ -2041,7 +2041,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Passwords GROUP BY CredentialId ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated; - + INSERT INTO FieldHistories (Id, ItemId, FieldDefinitionId, ValueSnapshot, ChangedAt, CreatedAt, UpdatedAt, IsDeleted) @@ -2063,7 +2063,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); GROUP BY CredentialId ) pm ON p2.CredentialId = pm.CredentialId AND p2.UpdatedAt = pm.MaxUpdated ); - + -- Migrate Alias.Email @@ -2155,7 +2155,7 @@ CREATE UNIQUE INDEX "IX_Logos_Source" ON "Logos" ("Source"); FROM Credentials c INNER JOIN Aliases a ON a.Id = c.AliasId WHERE a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate != '0001-01-01 00:00:00.000'; - + DROP TABLE "Passwords";