diff --git a/apps/mobile/app/components/dialogs/vault/index.tsx b/apps/mobile/app/components/dialogs/vault/index.tsx index 57266e2d3..10619cfec 100644 --- a/apps/mobile/app/components/dialogs/vault/index.tsx +++ b/apps/mobile/app/components/dialogs/vault/index.tsx @@ -66,12 +66,17 @@ import { VAULT_ERRORS } from "@notesnook/core"; import { useThemeColors } from "@notesnook/theme"; +import { useUserStore } from "../../../stores/use-user-store"; +import { AppFontSize } from "../../../utils/size"; +import { Pressable } from "../../ui/pressable"; +import AppIcon from "../../ui/AppIcon"; export const VaultDialog: React.FC = () => { const { colors } = useThemeColors(); // UI State const [visible, setVisible] = useState(false); + const isUserLoggedIn = useUserStore((state) => !!state.user); const [loading, setLoading] = useState(false); const [deleteAll, setDeleteAll] = useState(false); const [biometricUnlock, setBiometricUnlock] = useState(false); @@ -196,9 +201,12 @@ export const VaultDialog: React.FC = () => { } eSendEvent("vaultUpdated"); setLoading(false); - setTimeout(() => { - close(); - }, 100); + close(); + ToastManager.show({ + message: strings.vaultDeleted(), + type: "success", + context: "global" + }); } else { setLoading(false); formRef.current.setError("password", strings.passwordIncorrect()); @@ -489,6 +497,13 @@ export const VaultDialog: React.FC = () => { const { password, newPassword } = formRef.current.getValues(); + if (requestType === VaultRequestType.DeleteVault && !isUserLoggedIn) { + setLoading(true); + await deleteVault(); + setLoading(false); + return; + } + if (requestType === VaultRequestType.CreateVault) { createVault(); } else if (requestType === VaultRequestType.ChangePassword) { @@ -629,16 +644,22 @@ export const VaultDialog: React.FC = () => { // Auto-unlock with fingerprint if applicable const canAutoUnlock = fingerprint && + available && data.requestType !== VaultRequestType.EnableFingerprint && data.requestType !== VaultRequestType.RevokeFingerprint && data.requestType !== VaultRequestType.ChangePassword && data.requestType !== VaultRequestType.ClearVault && data.requestType !== VaultRequestType.DeleteVault && data.requestType !== VaultRequestType.CustomAction && - data.requestType !== VaultRequestType.PermanentUnlock; + data.requestType !== VaultRequestType.PermanentUnlock && + data.requestType !== VaultRequestType.CreateVault; - if (canAutoUnlock) { - await onPressFingerprintAuth(data.title, data.description); + if (canAutoUnlock && available) { + try { + await onPressFingerprintAuth(data.title, data.description); + } catch (e) { + setVisible(true); + } } else { setVisible(true); } @@ -700,7 +721,6 @@ export const VaultDialog: React.FC = () => { icon="shield" padding={12} /> - { > {(isChangePassword || isClearVault || - !isCreateVault || - isDeleteVault || + (isDeleteVault && isUserLoggedIn) || isCustomAction) && !isRevokeFingerprint ? ( <> @@ -772,20 +791,32 @@ export const VaultDialog: React.FC = () => { ) : null} {isDeleteVault && ( - diff --git a/apps/web/src/common/vault.ts b/apps/web/src/common/vault.ts index 39ef84cd5..b5f2bc862 100644 --- a/apps/web/src/common/vault.ts +++ b/apps/web/src/common/vault.ts @@ -23,6 +23,7 @@ import { showToast } from "../utils/toast"; import { VAULT_ERRORS } from "@notesnook/core"; import { strings } from "@notesnook/intl"; import { useStore as useAppStore } from "../stores/app-store"; +import { useStore as useUserStore } from "../stores/user-store"; class Vault { static async createVault() { @@ -63,29 +64,47 @@ class Vault { static async deleteVault() { if (!(await db.vault.exists())) return false; - const result = await showPasswordDialog({ - title: strings.deleteVault(), - subtitle: strings.deleteVaultDesc(), - inputs: { - password: { - label: strings.accountPassword(), - autoComplete: "current-password" - } - }, - checks: { - deleteAllLockedNotes: { - text: strings.deleteAllNotes(), - default: false - } - }, - validate: ({ password }) => { - return db.user.verifyPassword(password); - } - }); + + const result = await (useUserStore.getState().isLoggedIn + ? showPasswordDialog({ + title: strings.deleteVault(), + subtitle: strings.deleteVaultDesc(), + inputs: { + password: { + label: strings.accountPassword(), + autoComplete: "current-password" + } + }, + checks: { + deleteAllLockedNotes: { + text: strings.deleteAllNotes(), + default: false + } + }, + validate: ({ password }) => { + return db.user.verifyPassword(password); + } + }) + : showPasswordDialog({ + title: strings.deleteVault(), + subtitle: strings.deleteVaultDesc(), + inputs: {}, + checks: { + deleteAllLockedNotes: { + text: strings.deleteAllNotes(), + default: false + } + }, + validate: () => { + return Promise.resolve(true); + } + })); + if (result) { await db.vault.delete(result.deleteAllLockedNotes); return true; } + return false; } diff --git a/packages/core/src/database/migrations.ts b/packages/core/src/database/migrations.ts index 6fa22a5c5..5290963e1 100644 --- a/packages/core/src/database/migrations.ts +++ b/packages/core/src/database/migrations.ts @@ -38,6 +38,7 @@ export class NNMigrationProvider implements MigrationProvider { async up(db) { await db.schema .createTable("kv") + .ifNotExists() .modifyEnd(sql`without rowid`) .addColumn("key", "text", (c) => c.primaryKey().unique().notNull()) .addColumn("value", "text") @@ -46,6 +47,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("notes") + .ifNotExists() // .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .$call(addTrashColumns) @@ -68,6 +70,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("content") + .ifNotExists() // .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("noteId", "text") @@ -88,6 +91,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("notehistory") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("noteId", "text") @@ -98,6 +102,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("sessioncontent") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("data", "text") @@ -109,6 +114,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("notebooks") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .$call(addTrashColumns) @@ -120,6 +126,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("tags") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("title", "text", COLLATE_NOCASE) @@ -127,6 +134,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("colors") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("title", "text", COLLATE_NOCASE) @@ -135,6 +143,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("vaults") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("title", "text", COLLATE_NOCASE) @@ -143,6 +152,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("relations") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("fromType", "text") @@ -153,6 +163,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("shortcuts") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("sortIndex", "integer") @@ -162,6 +173,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("reminders") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("title", "text", COLLATE_NOCASE) @@ -178,6 +190,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("attachments") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("iv", "text") @@ -197,6 +210,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createTable("settings") + .ifNotExists() .modifyEnd(sql`without rowid`) .$call(addBaseColumns) .addColumn("key", "text", (c) => c.unique()) @@ -205,12 +219,14 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createIndex("notehistory_noteid") + .ifNotExists() .on("notehistory") .column("noteId") .execute(); await db.schema .createIndex("relation_from_general") + .ifNotExists() .on("relations") .columns(["fromType", "toType", "fromId"]) .where("toType", "!=", "note") @@ -219,6 +235,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createIndex("relation_to_general") + .ifNotExists() .on("relations") .columns(["fromType", "toType", "toId"]) .where("fromType", "!=", "note") @@ -227,6 +244,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createIndex("relation_from_note_notebook") + .ifNotExists() .on("relations") .columns(["fromType", "toType", "fromId", "toId"]) .where((eb) => @@ -239,6 +257,7 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createIndex("relation_to_note_notebook") + .ifNotExists() .on("relations") .columns(["fromType", "toType", "toId", "fromId"]) .where((eb) => @@ -251,36 +270,42 @@ export class NNMigrationProvider implements MigrationProvider { await db.schema .createIndex("note_type") + .ifNotExists() .on("notes") .columns(["type"]) .execute(); await db.schema .createIndex("note_deleted") + .ifNotExists() .on("notes") .columns(["deleted"]) .execute(); await db.schema .createIndex("note_date_deleted") + .ifNotExists() .on("notes") .columns(["dateDeleted"]) .execute(); await db.schema .createIndex("notebook_type") + .ifNotExists() .on("notebooks") .columns(["type"]) .execute(); await db.schema .createIndex("attachment_hash") + .ifNotExists() .on("attachments") .column("hash") .execute(); await db.schema .createIndex("content_noteId") + .ifNotExists() .on("content") .columns(["noteId"]) .execute(); @@ -316,6 +341,7 @@ export class NNMigrationProvider implements MigrationProvider { async up(db) { await db.schema .createTable("config") + .ifNotExists() .modifyEnd(sql`without rowid`) .addColumn("name", "text", (c) => c.primaryKey().unique().notNull()) .addColumn("value", "text") @@ -397,6 +423,7 @@ export class NNMigrationProvider implements MigrationProvider { async up(db) { await db.schema .createTable("monographs") + .ifNotExists() .$call(addBaseColumns) .addColumn("datePublished", "integer") .addColumn("title", "text", COLLATE_NOCASE) @@ -413,6 +440,7 @@ export class NNMigrationProvider implements MigrationProvider { .execute(); await db.schema .createIndex("note_expiry_date") + .ifNotExists() .on("notes") .expression(sql`expiryDate ->> '$.value'`) .execute(); @@ -514,7 +542,9 @@ function createFTS5Table( sql.join(_options.map((o) => sql.raw(o))) ]); - return sql`CREATE VIRTUAL TABLE ${sql.raw(name)} USING fts5(${args})`; + return sql`CREATE VIRTUAL TABLE IF NOT EXISTS ${sql.raw( + name + )} USING fts5(${args})`; } async function runFTSTablesMigrations(db: Kysely) { diff --git a/packages/intl/locale/en.po b/packages/intl/locale/en.po index 7fc988b35..ded5131af 100644 --- a/packages/intl/locale/en.po +++ b/packages/intl/locale/en.po @@ -2310,8 +2310,8 @@ msgid "Delete mode" msgstr "Delete mode" #: src/strings.ts:562 -msgid "Delete notes in this vault" -msgstr "Delete notes in this vault" +msgid "Delete notes in this vault permanently" +msgstr "Delete notes in this vault permanently" #: src/strings.ts:569 msgid "Delete permanently" diff --git a/packages/intl/locale/pseudo-LOCALE.po b/packages/intl/locale/pseudo-LOCALE.po index 63531b09c..9122bc479 100644 --- a/packages/intl/locale/pseudo-LOCALE.po +++ b/packages/intl/locale/pseudo-LOCALE.po @@ -2299,7 +2299,7 @@ msgid "Delete mode" msgstr "" #: src/strings.ts:562 -msgid "Delete notes in this vault" +msgid "Delete notes in this vault permanently" msgstr "" #: src/strings.ts:569 diff --git a/packages/intl/src/strings.ts b/packages/intl/src/strings.ts index 24d5d749a..cba2d595f 100644 --- a/packages/intl/src/strings.ts +++ b/packages/intl/src/strings.ts @@ -559,7 +559,7 @@ $day$: Current day (eg. Monday)`, couldNotUnlock: () => t`Could not unlock`, unlockNoteDesc: () => t`Your note will be unencrypted and removed from the vault.`, - deleteAllNotes: () => t`Delete notes in this vault`, + deleteAllNotes: () => t`Delete notes in this vault permanently`, getStarted: () => t`Get started`, saveACopy: () => t`Save a copy`, discard: () => t`Discard`,