From 351bb09332a9e279c62d2e1ddc13a580bcaff1ee Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Wed, 17 Dec 2025 22:48:51 +0100 Subject: [PATCH] Refactor Credential to Item based structure in AliasVault.Client (#1404) --- .../Details/AttachmentUploader.tsx | 2 +- .../utils/db/repositories/FolderRepository.ts | 2 +- .../utils/dist/core/models/vault/index.d.ts | 70 -- .../src/utils/dist/core/models/vault/index.js | 72 +- .../src/utils/dist/core/vault/index.d.mts | 2 +- .../src/utils/dist/core/vault/index.d.ts | 2 +- .../src/utils/dist/core/vault/index.js | 124 ++- .../src/utils/dist/core/vault/index.mjs | 124 ++- .../app/vaultstore/models/FieldKey.kt | 72 +- .../mobile-app/ios/VaultModels/FieldKey.swift | 44 +- .../utils/dist/core/models/vault/index.d.ts | 70 -- .../utils/dist/core/models/vault/index.js | 72 +- .../utils/dist/core/vault/index.d.mts | 2 +- .../utils/dist/core/vault/index.d.ts | 2 +- .../mobile-app/utils/dist/core/vault/index.js | 124 ++- .../utils/dist/core/vault/index.mjs | 124 ++- .../Credentials/CredentialCard.razor | 2 +- .../Credentials/CredentialsTable.razor | 6 +- .../Forms/EditPasswordFormRow.razor | 4 +- .../Settings/PasswordSettingsPopup.razor | 4 +- .../Widgets/CreateNewIdentityWidget.razor | 37 +- .../Components/Widgets/SearchWidget.razor | 60 +- .../Main/Models/CredentialEdit.cs | 177 ---- .../AliasVault.Client/Main/Models/ItemEdit.cs | 222 +++++ ...redentialListEntry.cs => ItemListEntry.cs} | 34 +- .../Main/Pages/Credentials/AddEdit.razor | 150 ++-- .../Main/Pages/Credentials/Delete.razor | 11 +- .../Main/Pages/Credentials/Home.razor | 24 +- .../Main/Pages/Credentials/View.razor | 113 +-- .../Main/Pages/Emails/Home.razor | 17 +- .../Components/ImportServiceAliasVault.razor | 6 +- .../Components/ImportServiceCard.razor | 50 +- .../Settings/ImportExport/ImportExport.razor | 6 +- .../Settings/ImportExport/ResetVault.razor | 6 +- .../Main/Pages/Test/Test3.razor | 2 +- apps/server/AliasVault.Client/Program.cs | 2 +- .../Services/CredentialService.cs | 607 -------------- .../Services/Database/DbService.cs | 33 +- .../AliasVault.Client/Services/ItemService.cs | 781 ++++++++++++++++++ .../wwwroot/js/dist/core/vault/index.d.mts | 2 +- .../wwwroot/js/dist/core/vault/index.d.ts | 2 +- .../wwwroot/js/dist/core/vault/index.js | 124 ++- .../wwwroot/js/dist/core/vault/index.mjs | 124 ++- ...3111207_1.7.0-FieldBasedDataModelUpdate.cs | 70 +- .../AliasClientDb/Models}/FieldKey.cs | 72 +- .../Scripts/MigrationSql/000_FullSchema.sql | 62 +- ...111207_1.7.0-FieldBasedDataModelUpdate.sql | 62 +- .../CredentialCsvService.cs | 145 ---- .../Importers/BaseImporter.cs | 118 ++- .../AliasVault.ImportExport/ItemCsvService.cs | 240 ++++++ core/models/scripts/generate-field-keys.cjs | 8 +- core/vault/src/sql/SqlConstants.ts | 124 ++- 52 files changed, 2532 insertions(+), 1883 deletions(-) delete mode 100644 apps/server/AliasVault.Client/Main/Models/CredentialEdit.cs create mode 100644 apps/server/AliasVault.Client/Main/Models/ItemEdit.cs rename apps/server/AliasVault.Client/Main/Models/{CredentialListEntry.cs => ItemListEntry.cs} (51%) delete mode 100644 apps/server/AliasVault.Client/Services/CredentialService.cs create mode 100644 apps/server/AliasVault.Client/Services/ItemService.cs rename apps/server/{AliasVault.Client/Main/Models/Vault => Databases/AliasClientDb/Models}/FieldKey.cs (53%) delete mode 100644 apps/server/Utilities/AliasVault.ImportExport/CredentialCsvService.cs create mode 100644 apps/server/Utilities/AliasVault.ImportExport/ItemCsvService.cs diff --git a/apps/browser-extension/src/entrypoints/popup/components/Credentials/Details/AttachmentUploader.tsx b/apps/browser-extension/src/entrypoints/popup/components/Credentials/Details/AttachmentUploader.tsx index 79aed3e77..b0ab5ca71 100644 --- a/apps/browser-extension/src/entrypoints/popup/components/Credentials/Details/AttachmentUploader.tsx +++ b/apps/browser-extension/src/entrypoints/popup/components/Credentials/Details/AttachmentUploader.tsx @@ -37,7 +37,7 @@ const AttachmentUploader: React.FC = ({ const byteArray = new Uint8Array(arrayBuffer); const attachment: Attachment = { - Id: crypto.randomUUID(), + Id: crypto.randomUUID().toUpperCase(), Filename: file.name, Blob: byteArray, ItemId: '', // Will be set when saving item diff --git a/apps/browser-extension/src/utils/db/repositories/FolderRepository.ts b/apps/browser-extension/src/utils/db/repositories/FolderRepository.ts index 0b93578b0..f968fc462 100644 --- a/apps/browser-extension/src/utils/db/repositories/FolderRepository.ts +++ b/apps/browser-extension/src/utils/db/repositories/FolderRepository.ts @@ -97,7 +97,7 @@ export class FolderRepository extends BaseRepository { */ public async create(name: string, parentFolderId?: string | null): Promise { return this.withTransaction(async () => { - const folderId = crypto.randomUUID(); + const folderId = crypto.randomUUID().toUpperCase(); const currentDateTime = this.now(); this.client.executeUpdate(FolderQueries.INSERT, [ diff --git a/apps/browser-extension/src/utils/dist/core/models/vault/index.d.ts b/apps/browser-extension/src/utils/dist/core/models/vault/index.d.ts index 98f6fd3ca..546d5615a 100644 --- a/apps/browser-extension/src/utils/dist/core/models/vault/index.d.ts +++ b/apps/browser-extension/src/utils/dist/core/models/vault/index.d.ts @@ -160,11 +160,6 @@ declare const FieldKey: { * Type: Password */ readonly LoginPassword: "login.password"; - /** - * Login notes field - * Type: Text - */ - readonly LoginNotes: "login.notes"; /** * Login email field * Type: Email @@ -175,11 +170,6 @@ declare const FieldKey: { * Type: URL */ readonly LoginUrl: "login.url"; - /** - * Login recovery codes field (multi-value) - * Type: Text - */ - readonly LoginRecoveryCodes: "login.recovery_codes"; /** * Credit card number field * Type: Text @@ -210,66 +200,6 @@ declare const FieldKey: { * Type: Password */ readonly CardPin: "card.pin"; - /** - * Identity title field (e.g., Mr., Mrs., Dr.) - * Type: Text - */ - readonly IdentityTitle: "identity.title"; - /** - * Identity first name field - * Type: Text - */ - readonly IdentityFirstName: "identity.first_name"; - /** - * Identity middle name field - * Type: Text - */ - readonly IdentityMiddleName: "identity.middle_name"; - /** - * Identity last name field - * Type: Text - */ - readonly IdentityLastName: "identity.last_name"; - /** - * Identity email field - * Type: Email - */ - readonly IdentityEmail: "identity.email"; - /** - * Identity phone number field (multi-value) - * Type: Text - */ - readonly IdentityPhoneNumbers: "identity.phone_numbers"; - /** - * Identity address line 1 field - * Type: Text - */ - readonly IdentityAddressLine1: "identity.address_line1"; - /** - * Identity address line 2 field - * Type: Text - */ - readonly IdentityAddressLine2: "identity.address_line2"; - /** - * Identity city field - * Type: Text - */ - readonly IdentityCity: "identity.city"; - /** - * Identity state/province field - * Type: Text - */ - readonly IdentityState: "identity.state"; - /** - * Identity postal code field - * Type: Text - */ - readonly IdentityPostalCode: "identity.postal_code"; - /** - * Identity country field - * Type: Text - */ - readonly IdentityCountry: "identity.country"; /** * Alias first name field * Type: Text diff --git a/apps/browser-extension/src/utils/dist/core/models/vault/index.js b/apps/browser-extension/src/utils/dist/core/models/vault/index.js index 5005cd11d..e55e3203c 100644 --- a/apps/browser-extension/src/utils/dist/core/models/vault/index.js +++ b/apps/browser-extension/src/utils/dist/core/models/vault/index.js @@ -14,11 +14,6 @@ var FieldKey = { * Type: Password */ LoginPassword: "login.password", - /** - * Login notes field - * Type: Text - */ - LoginNotes: "login.notes", /** * Login email field * Type: Email @@ -29,11 +24,6 @@ var FieldKey = { * Type: URL */ LoginUrl: "login.url", - /** - * Login recovery codes field (multi-value) - * Type: Text - */ - LoginRecoveryCodes: "login.recovery_codes", /** * Credit card number field * Type: Text @@ -64,66 +54,6 @@ var FieldKey = { * Type: Password */ CardPin: "card.pin", - /** - * Identity title field (e.g., Mr., Mrs., Dr.) - * Type: Text - */ - IdentityTitle: "identity.title", - /** - * Identity first name field - * Type: Text - */ - IdentityFirstName: "identity.first_name", - /** - * Identity middle name field - * Type: Text - */ - IdentityMiddleName: "identity.middle_name", - /** - * Identity last name field - * Type: Text - */ - IdentityLastName: "identity.last_name", - /** - * Identity email field - * Type: Email - */ - IdentityEmail: "identity.email", - /** - * Identity phone number field (multi-value) - * Type: Text - */ - IdentityPhoneNumbers: "identity.phone_numbers", - /** - * Identity address line 1 field - * Type: Text - */ - IdentityAddressLine1: "identity.address_line1", - /** - * Identity address line 2 field - * Type: Text - */ - IdentityAddressLine2: "identity.address_line2", - /** - * Identity city field - * Type: Text - */ - IdentityCity: "identity.city", - /** - * Identity state/province field - * Type: Text - */ - IdentityState: "identity.state", - /** - * Identity postal code field - * Type: Text - */ - IdentityPostalCode: "identity.postal_code", - /** - * Identity country field - * Type: Text - */ - IdentityCountry: "identity.country", /** * Alias first name field * Type: Text @@ -402,7 +332,7 @@ function getAllSystemFieldKeys() { return Object.keys(SystemFieldRegistry); } function isSystemFieldPrefix(fieldKey) { - return fieldKey.startsWith("login.") || fieldKey.startsWith("alias.") || fieldKey.startsWith("card.") || fieldKey.startsWith("identity.") || fieldKey.startsWith("api.") || fieldKey.startsWith("notes.") || fieldKey.startsWith("metadata."); + return fieldKey.startsWith("login.") || fieldKey.startsWith("alias.") || fieldKey.startsWith("card.") || fieldKey.startsWith("notes."); } // src/vault/ItemMethods.ts diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.d.mts b/apps/browser-extension/src/utils/dist/core/vault/index.d.mts index 86322b145..033a999f0 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.d.mts +++ b/apps/browser-extension/src/utils/dist/core/vault/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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\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 -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n a.BirthDate AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.d.ts b/apps/browser-extension/src/utils/dist/core/vault/index.d.ts index 86322b145..033a999f0 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.d.ts +++ b/apps/browser-extension/src/utils/dist/core/vault/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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\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 -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n a.BirthDate AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.js b/apps/browser-extension/src/utils/dist/core/vault/index.js index 5fed8f803..e0802c5be 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.js +++ b/apps/browser-extension/src/utils/dist/core/vault/index.js @@ -882,7 +882,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -1011,7 +1015,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -1028,7 +1036,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -1044,7 +1056,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -1060,7 +1076,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -1082,7 +1102,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -1099,7 +1123,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -1116,7 +1144,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -1133,7 +1165,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -1150,11 +1186,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, @@ -2039,7 +2079,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -2168,7 +2212,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -2185,7 +2233,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -2201,7 +2253,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -2217,7 +2273,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -2239,7 +2299,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -2256,7 +2320,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -2273,7 +2341,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -2290,7 +2362,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -2307,11 +2383,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, diff --git a/apps/browser-extension/src/utils/dist/core/vault/index.mjs b/apps/browser-extension/src/utils/dist/core/vault/index.mjs index 40d72bd7b..8c4d5fa37 100644 --- a/apps/browser-extension/src/utils/dist/core/vault/index.mjs +++ b/apps/browser-extension/src/utils/dist/core/vault/index.mjs @@ -850,7 +850,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -979,7 +983,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -996,7 +1004,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -1012,7 +1024,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -1028,7 +1044,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -1050,7 +1070,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -1067,7 +1091,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -1084,7 +1112,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -1101,7 +1133,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -1118,11 +1154,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, @@ -2007,7 +2047,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -2136,7 +2180,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -2153,7 +2201,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -2169,7 +2221,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -2185,7 +2241,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -2207,7 +2267,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -2224,7 +2288,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -2241,7 +2309,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -2258,7 +2330,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -2275,11 +2351,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, diff --git a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/FieldKey.kt b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/FieldKey.kt index d73dd82c4..6fa59e737 100644 --- a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/FieldKey.kt +++ b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/FieldKey.kt @@ -1,5 +1,5 @@ // -// This file is auto-generated from shared/models/src/vault/FieldKey.ts +// This file is auto-generated from core/models/src/vault/FieldKey.ts // Do not edit this file directly. Run 'npm run generate:models' to regenerate. package net.aliasvault.app.vaultstore.models @@ -19,11 +19,6 @@ object FieldKey { */ const val LOGIN_PASSWORD = "login.password" - /** - * Type: Text. - */ - const val LOGIN_NOTES = "login.notes" - /** * Type: Email. */ @@ -34,11 +29,6 @@ object FieldKey { */ const val LOGIN_URL = "login.url" - /** - * Type: Text. - */ - const val LOGIN_RECOVERY_CODES = "login.recovery_codes" - /** * Type: Text. */ @@ -69,66 +59,6 @@ object FieldKey { */ const val CARD_PIN = "card.pin" - /** - * Type: Text. - */ - const val IDENTITY_TITLE = "identity.title" - - /** - * Type: Text. - */ - const val IDENTITY_FIRST_NAME = "identity.first_name" - - /** - * Type: Text. - */ - const val IDENTITY_MIDDLE_NAME = "identity.middle_name" - - /** - * Type: Text. - */ - const val IDENTITY_LAST_NAME = "identity.last_name" - - /** - * Type: Email. - */ - const val IDENTITY_EMAIL = "identity.email" - - /** - * Type: Text. - */ - const val IDENTITY_PHONE_NUMBERS = "identity.phone_numbers" - - /** - * Type: Text. - */ - const val IDENTITY_ADDRESS_LINE1 = "identity.address_line1" - - /** - * Type: Text. - */ - const val IDENTITY_ADDRESS_LINE2 = "identity.address_line2" - - /** - * Type: Text. - */ - const val IDENTITY_CITY = "identity.city" - - /** - * Type: Text. - */ - const val IDENTITY_STATE = "identity.state" - - /** - * Type: Text. - */ - const val IDENTITY_POSTAL_CODE = "identity.postal_code" - - /** - * Type: Text. - */ - const val IDENTITY_COUNTRY = "identity.country" - /** * Type: Text. */ diff --git a/apps/mobile-app/ios/VaultModels/FieldKey.swift b/apps/mobile-app/ios/VaultModels/FieldKey.swift index 2a5b2f649..8177df729 100644 --- a/apps/mobile-app/ios/VaultModels/FieldKey.swift +++ b/apps/mobile-app/ios/VaultModels/FieldKey.swift @@ -1,5 +1,5 @@ // -// This file is auto-generated from shared/models/src/vault/FieldKey.ts +// This file is auto-generated from core/models/src/vault/FieldKey.ts // Do not edit this file directly. Run 'npm run generate:models' to regenerate. import Foundation @@ -13,18 +13,12 @@ public struct FieldKey { /// Type: Password public static let loginPassword = "login.password" - /// Type: Text - public static let loginNotes = "login.notes" - /// Type: Email public static let loginEmail = "login.email" /// Type: URL public static let loginUrl = "login.url" - /// Type: Text - public static let loginRecoveryCodes = "login.recovery_codes" - /// Type: Text public static let cardNumber = "card.number" @@ -43,42 +37,6 @@ public struct FieldKey { /// Type: Password public static let cardPin = "card.pin" - /// Type: Text - public static let identityTitle = "identity.title" - - /// Type: Text - public static let identityFirstName = "identity.first_name" - - /// Type: Text - public static let identityMiddleName = "identity.middle_name" - - /// Type: Text - public static let identityLastName = "identity.last_name" - - /// Type: Email - public static let identityEmail = "identity.email" - - /// Type: Text - public static let identityPhoneNumbers = "identity.phone_numbers" - - /// Type: Text - public static let identityAddressLine1 = "identity.address_line1" - - /// Type: Text - public static let identityAddressLine2 = "identity.address_line2" - - /// Type: Text - public static let identityCity = "identity.city" - - /// Type: Text - public static let identityState = "identity.state" - - /// Type: Text - public static let identityPostalCode = "identity.postal_code" - - /// Type: Text - public static let identityCountry = "identity.country" - /// Type: Text public static let aliasFirstName = "alias.first_name" diff --git a/apps/mobile-app/utils/dist/core/models/vault/index.d.ts b/apps/mobile-app/utils/dist/core/models/vault/index.d.ts index 98f6fd3ca..546d5615a 100644 --- a/apps/mobile-app/utils/dist/core/models/vault/index.d.ts +++ b/apps/mobile-app/utils/dist/core/models/vault/index.d.ts @@ -160,11 +160,6 @@ declare const FieldKey: { * Type: Password */ readonly LoginPassword: "login.password"; - /** - * Login notes field - * Type: Text - */ - readonly LoginNotes: "login.notes"; /** * Login email field * Type: Email @@ -175,11 +170,6 @@ declare const FieldKey: { * Type: URL */ readonly LoginUrl: "login.url"; - /** - * Login recovery codes field (multi-value) - * Type: Text - */ - readonly LoginRecoveryCodes: "login.recovery_codes"; /** * Credit card number field * Type: Text @@ -210,66 +200,6 @@ declare const FieldKey: { * Type: Password */ readonly CardPin: "card.pin"; - /** - * Identity title field (e.g., Mr., Mrs., Dr.) - * Type: Text - */ - readonly IdentityTitle: "identity.title"; - /** - * Identity first name field - * Type: Text - */ - readonly IdentityFirstName: "identity.first_name"; - /** - * Identity middle name field - * Type: Text - */ - readonly IdentityMiddleName: "identity.middle_name"; - /** - * Identity last name field - * Type: Text - */ - readonly IdentityLastName: "identity.last_name"; - /** - * Identity email field - * Type: Email - */ - readonly IdentityEmail: "identity.email"; - /** - * Identity phone number field (multi-value) - * Type: Text - */ - readonly IdentityPhoneNumbers: "identity.phone_numbers"; - /** - * Identity address line 1 field - * Type: Text - */ - readonly IdentityAddressLine1: "identity.address_line1"; - /** - * Identity address line 2 field - * Type: Text - */ - readonly IdentityAddressLine2: "identity.address_line2"; - /** - * Identity city field - * Type: Text - */ - readonly IdentityCity: "identity.city"; - /** - * Identity state/province field - * Type: Text - */ - readonly IdentityState: "identity.state"; - /** - * Identity postal code field - * Type: Text - */ - readonly IdentityPostalCode: "identity.postal_code"; - /** - * Identity country field - * Type: Text - */ - readonly IdentityCountry: "identity.country"; /** * Alias first name field * Type: Text diff --git a/apps/mobile-app/utils/dist/core/models/vault/index.js b/apps/mobile-app/utils/dist/core/models/vault/index.js index 5005cd11d..e55e3203c 100644 --- a/apps/mobile-app/utils/dist/core/models/vault/index.js +++ b/apps/mobile-app/utils/dist/core/models/vault/index.js @@ -14,11 +14,6 @@ var FieldKey = { * Type: Password */ LoginPassword: "login.password", - /** - * Login notes field - * Type: Text - */ - LoginNotes: "login.notes", /** * Login email field * Type: Email @@ -29,11 +24,6 @@ var FieldKey = { * Type: URL */ LoginUrl: "login.url", - /** - * Login recovery codes field (multi-value) - * Type: Text - */ - LoginRecoveryCodes: "login.recovery_codes", /** * Credit card number field * Type: Text @@ -64,66 +54,6 @@ var FieldKey = { * Type: Password */ CardPin: "card.pin", - /** - * Identity title field (e.g., Mr., Mrs., Dr.) - * Type: Text - */ - IdentityTitle: "identity.title", - /** - * Identity first name field - * Type: Text - */ - IdentityFirstName: "identity.first_name", - /** - * Identity middle name field - * Type: Text - */ - IdentityMiddleName: "identity.middle_name", - /** - * Identity last name field - * Type: Text - */ - IdentityLastName: "identity.last_name", - /** - * Identity email field - * Type: Email - */ - IdentityEmail: "identity.email", - /** - * Identity phone number field (multi-value) - * Type: Text - */ - IdentityPhoneNumbers: "identity.phone_numbers", - /** - * Identity address line 1 field - * Type: Text - */ - IdentityAddressLine1: "identity.address_line1", - /** - * Identity address line 2 field - * Type: Text - */ - IdentityAddressLine2: "identity.address_line2", - /** - * Identity city field - * Type: Text - */ - IdentityCity: "identity.city", - /** - * Identity state/province field - * Type: Text - */ - IdentityState: "identity.state", - /** - * Identity postal code field - * Type: Text - */ - IdentityPostalCode: "identity.postal_code", - /** - * Identity country field - * Type: Text - */ - IdentityCountry: "identity.country", /** * Alias first name field * Type: Text @@ -402,7 +332,7 @@ function getAllSystemFieldKeys() { return Object.keys(SystemFieldRegistry); } function isSystemFieldPrefix(fieldKey) { - return fieldKey.startsWith("login.") || fieldKey.startsWith("alias.") || fieldKey.startsWith("card.") || fieldKey.startsWith("identity.") || fieldKey.startsWith("api.") || fieldKey.startsWith("notes.") || fieldKey.startsWith("metadata."); + return fieldKey.startsWith("login.") || fieldKey.startsWith("alias.") || fieldKey.startsWith("card.") || fieldKey.startsWith("notes."); } // src/vault/ItemMethods.ts diff --git a/apps/mobile-app/utils/dist/core/vault/index.d.mts b/apps/mobile-app/utils/dist/core/vault/index.d.mts index 86322b145..033a999f0 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.d.mts +++ b/apps/mobile-app/utils/dist/core/vault/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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\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 -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n a.BirthDate AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/mobile-app/utils/dist/core/vault/index.d.ts b/apps/mobile-app/utils/dist/core/vault/index.d.ts index 86322b145..033a999f0 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.d.ts +++ b/apps/mobile-app/utils/dist/core/vault/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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\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 -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n lower(hex(randomblob(16))) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n a.BirthDate AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '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 \"FieldType\" TEXT NOT NULL,\n \"Label\" TEXT NOT NULL,\n \"IsMultiValue\" INTEGER NOT NULL,\n \"IsHidden\" INTEGER NOT NULL,\n \"EnableHistory\" INTEGER NOT NULL,\n \"Weight\" 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 \"Weight\" 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 \"Tags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_Tags\" PRIMARY KEY,\n \"Name\" TEXT NOT NULL,\n \"Color\" TEXT NULL,\n \"DisplayOrder\" INTEGER NOT 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 \"DeletedAt\" 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 NULL,\n \"FieldKey\" TEXT 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 NULL,\n \"FieldKey\" TEXT NULL,\n \"Value\" TEXT NULL,\n \"Weight\" 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 TABLE \"ItemTags\" (\n \"Id\" TEXT NOT NULL CONSTRAINT \"PK_ItemTags\" PRIMARY KEY,\n \"ItemId\" TEXT NOT NULL,\n \"TagId\" TEXT NOT NULL,\n \"CreatedAt\" TEXT NOT NULL,\n \"UpdatedAt\" TEXT NOT NULL,\n \"IsDeleted\" INTEGER NOT NULL,\n CONSTRAINT \"FK_ItemTags_Items_ItemId\" FOREIGN KEY (\"ItemId\") REFERENCES \"Items\" (\"Id\") ON DELETE CASCADE,\n CONSTRAINT \"FK_ItemTags_Tags_TagId\" FOREIGN KEY (\"TagId\") REFERENCES \"Tags\" (\"Id\") ON DELETE CASCADE\n);\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_FieldKey\" ON \"FieldValues\" (\"FieldKey\");\n\nCREATE INDEX \"IX_FieldValues_ItemId\" ON \"FieldValues\" (\"ItemId\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldDefinitionId_Weight\" ON \"FieldValues\" (\"ItemId\", \"FieldDefinitionId\", \"Weight\");\n\nCREATE INDEX \"IX_FieldValues_ItemId_FieldKey\" ON \"FieldValues\" (\"ItemId\", \"FieldKey\");\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 INDEX \"IX_ItemTags_ItemId\" ON \"ItemTags\" (\"ItemId\");\n\nCREATE UNIQUE INDEX \"IX_ItemTags_ItemId_TagId\" ON \"ItemTags\" (\"ItemId\", \"TagId\");\n\nCREATE INDEX \"IX_ItemTags_TagId\" ON \"ItemTags\" (\"TagId\");\n\nCREATE UNIQUE INDEX \"IX_Logos_Source\" ON \"Logos\" (\"Source\");\n\nCREATE INDEX \"IX_Tags_Name\" ON \"Tags\" (\"Name\");\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 CASE\n WHEN a.Id IS NOT NULL AND (\n (a.FirstName IS NOT NULL AND a.FirstName != '') OR\n (a.LastName IS NOT NULL AND a.LastName != '') OR\n (a.Gender IS NOT NULL AND a.Gender != '') OR\n (a.BirthDate IS NOT NULL AND a.BirthDate != '' AND a.BirthDate NOT LIKE '0001-%')\n ) THEN 'Alias'\n ELSE 'Login'\n END 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 LEFT JOIN Aliases a ON a.Id = c.AliasId;\n \n\n\n INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix\n REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) 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 REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n );\n \n\n\n UPDATE Items\n SET LogoId = (\n SELECT l.Id FROM Logos l\n INNER JOIN Services s ON REPLACE(\n LOWER(\n SUBSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END,\n 1,\n CASE\n WHEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') > 0\n THEN INSTR(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END, '/') - 1\n ELSE LENGTH(\n CASE\n WHEN s.Url LIKE 'https://%' THEN SUBSTR(s.Url, 9)\n WHEN s.Url LIKE 'http://%' THEN SUBSTR(s.Url, 8)\n ELSE s.Url\n END)\n END\n )\n ),\n 'www.', ''\n ) = 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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.url' AS FieldKey,\n s.Url AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.username' AS FieldKey,\n c.Username AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.notes' AS FieldKey,\n c.Notes AS Value,\n 0 AS Weight,\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, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n p.CredentialId AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.password' AS FieldKey,\n p.Value AS Value,\n 0 AS Weight,\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, MAX(Id) AS MaxId\n FROM Passwords\n WHERE IsDeleted = 0\n GROUP BY CredentialId\n ) pm ON p.CredentialId = pm.CredentialId AND p.UpdatedAt = pm.MaxUpdated AND p.Id = pm.MaxId\n WHERE p.IsDeleted = 0;\n \n\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'login.email' AS FieldKey,\n a.Email AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.first_name' AS FieldKey,\n a.FirstName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.last_name' AS FieldKey,\n a.LastName AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.gender' AS FieldKey,\n a.Gender AS Value,\n 0 AS Weight,\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\n\n INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted)\n SELECT\n UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(2)), 1, 4) || '-' ||\n SUBSTR(hex(randomblob(6)), 1, 12)) AS Id,\n c.Id AS ItemId,\n NULL AS FieldDefinitionId,\n 'alias.birthdate' AS FieldKey,\n SUBSTR(a.BirthDate, 1, 10) AS Value,\n 0 AS Weight,\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 NOT LIKE '0001-%';\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 ('20251213111207_1.7.0-FieldBasedDataModelUpdate', '9.0.4');\n"; /** * Individual migration SQL scripts * Auto-generated from EF Core migrations diff --git a/apps/mobile-app/utils/dist/core/vault/index.js b/apps/mobile-app/utils/dist/core/vault/index.js index 5fed8f803..e0802c5be 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.js +++ b/apps/mobile-app/utils/dist/core/vault/index.js @@ -882,7 +882,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -1011,7 +1015,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -1028,7 +1036,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -1044,7 +1056,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -1060,7 +1076,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -1082,7 +1102,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -1099,7 +1123,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -1116,7 +1144,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -1133,7 +1165,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -1150,11 +1186,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, @@ -2039,7 +2079,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -2168,7 +2212,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -2185,7 +2233,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -2201,7 +2253,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -2217,7 +2273,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -2239,7 +2299,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -2256,7 +2320,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -2273,7 +2341,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -2290,7 +2362,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -2307,11 +2383,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, diff --git a/apps/mobile-app/utils/dist/core/vault/index.mjs b/apps/mobile-app/utils/dist/core/vault/index.mjs index 40d72bd7b..8c4d5fa37 100644 --- a/apps/mobile-app/utils/dist/core/vault/index.mjs +++ b/apps/mobile-app/utils/dist/core/vault/index.mjs @@ -850,7 +850,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -979,7 +983,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -996,7 +1004,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -1012,7 +1024,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -1028,7 +1044,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -1050,7 +1070,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -1067,7 +1091,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -1084,7 +1112,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -1101,7 +1133,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -1118,11 +1154,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, @@ -2007,7 +2047,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO Logos (Id, Source, FileData, MimeType, FetchedAt, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, -- Extract and normalize hostname: remove protocol, path, lowercase, and www. prefix REPLACE( LOWER( @@ -2136,7 +2180,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.url' AS FieldKey, @@ -2153,7 +2201,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.username' AS FieldKey, @@ -2169,7 +2221,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.notes' AS FieldKey, @@ -2185,7 +2241,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, p.CredentialId AS ItemId, NULL AS FieldDefinitionId, 'login.password' AS FieldKey, @@ -2207,7 +2267,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'login.email' AS FieldKey, @@ -2224,7 +2288,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.first_name' AS FieldKey, @@ -2241,7 +2309,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.last_name' AS FieldKey, @@ -2258,7 +2330,11 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.gender' AS FieldKey, @@ -2275,11 +2351,15 @@ CREATE INDEX "IX_Tags_Name" ON "Tags" ("Name"); INSERT INTO FieldValues (Id, ItemId, FieldDefinitionId, FieldKey, Value, Weight, CreatedAt, UpdatedAt, IsDeleted) SELECT - lower(hex(randomblob(16))) AS Id, + UPPER(SUBSTR(hex(randomblob(4)), 1, 8) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(2)), 1, 4) || '-' || + SUBSTR(hex(randomblob(6)), 1, 12)) AS Id, c.Id AS ItemId, NULL AS FieldDefinitionId, 'alias.birthdate' AS FieldKey, - a.BirthDate AS Value, + SUBSTR(a.BirthDate, 1, 10) AS Value, 0 AS Weight, a.UpdatedAt AS CreatedAt, a.UpdatedAt AS UpdatedAt, diff --git a/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialCard.razor b/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialCard.razor index be9e6799a..9f709f1f5 100644 --- a/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialCard.razor +++ b/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialCard.razor @@ -28,7 +28,7 @@ /// Gets or sets the credentials object to show. /// [Parameter] - public required CredentialListEntry Obj { get; set; } + public required ItemListEntry Obj { get; set; } /// /// Gets the display text for the credential, showing username by default, diff --git a/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialsTable.razor b/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialsTable.razor index 6c80705fe..67259b811 100644 --- a/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialsTable.razor +++ b/apps/server/AliasVault.Client/Main/Components/Credentials/CredentialsTable.razor @@ -24,7 +24,7 @@ /// Gets or sets the list of credentials to show. /// [Parameter] - public List Credentials { get; set; } = []; + public List Credentials { get; set; } = []; /// /// Gets or sets the sort order for the credentials (used to determine initial table state). @@ -60,7 +60,7 @@ /// /// Gets the credentials to display, with optional column-based sorting applied. /// - private IEnumerable DisplayedCredentials + private IEnumerable DisplayedCredentials { get { @@ -135,7 +135,7 @@ /// The list of credentials to sort. /// The column to sort by. /// The direction to sort by. - private static IEnumerable SortList(List credentials, string sortColumn, SortDirection sortDirection) + private static IEnumerable SortList(List credentials, string sortColumn, SortDirection sortDirection) { return sortColumn switch { diff --git a/apps/server/AliasVault.Client/Main/Components/Forms/EditPasswordFormRow.razor b/apps/server/AliasVault.Client/Main/Components/Forms/EditPasswordFormRow.razor index 20338c76f..28a0dd368 100644 --- a/apps/server/AliasVault.Client/Main/Components/Forms/EditPasswordFormRow.razor +++ b/apps/server/AliasVault.Client/Main/Components/Forms/EditPasswordFormRow.razor @@ -1,5 +1,5 @@ @inject DbService DbService -@inject CredentialService CredentialService +@inject ItemService ItemService
@@ -169,7 +169,7 @@ ///
private async Task GeneratePassword() { - string newPassword = await CredentialService.GenerateRandomPasswordAsync(_internalPasswordSettings); + string newPassword = await ItemService.GenerateRandomPasswordAsync(_internalPasswordSettings); // Update the local value. Value = newPassword; diff --git a/apps/server/AliasVault.Client/Main/Components/Settings/PasswordSettingsPopup.razor b/apps/server/AliasVault.Client/Main/Components/Settings/PasswordSettingsPopup.razor index 2de8d6601..ee866b52b 100644 --- a/apps/server/AliasVault.Client/Main/Components/Settings/PasswordSettingsPopup.razor +++ b/apps/server/AliasVault.Client/Main/Components/Settings/PasswordSettingsPopup.razor @@ -2,7 +2,7 @@ @inject DbService DbService @inject GlobalLoadingService GlobalLoadingService @inject GlobalNotificationService GlobalNotificationService -@inject CredentialService CredentialService +@inject ItemService ItemService @inject IStringLocalizerFactory LocalizerFactory @using Microsoft.Extensions.Localization @@ -143,7 +143,7 @@ { try { - _previewPassword = await CredentialService.GenerateRandomPasswordAsync(_workingSettings); + _previewPassword = await ItemService.GenerateRandomPasswordAsync(_workingSettings); } catch { diff --git a/apps/server/AliasVault.Client/Main/Components/Widgets/CreateNewIdentityWidget.razor b/apps/server/AliasVault.Client/Main/Components/Widgets/CreateNewIdentityWidget.razor index 5a2808a94..3cff5445d 100644 --- a/apps/server/AliasVault.Client/Main/Components/Widgets/CreateNewIdentityWidget.razor +++ b/apps/server/AliasVault.Client/Main/Components/Widgets/CreateNewIdentityWidget.razor @@ -3,10 +3,12 @@ @using AliasVault.Client.Resources @inherits AliasVault.Client.Main.Pages.MainBase @inject IJSRuntime JSRuntime -@inject CredentialService CredentialService +@inject ItemService ItemService @inject AliasVault.Client.Services.QuickCreateStateService QuickCreateStateService @inject LanguageService LanguageService @implements IAsyncDisposable +@using AliasClientDb +@using AliasClientDb.Models