mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 06:29:29 +01:00
mobile: fix vault unlock with biometrics
This commit is contained in:
@@ -24,7 +24,7 @@ import {
|
|||||||
setAppLockVerificationCipher,
|
setAppLockVerificationCipher,
|
||||||
validateAppLockPassword
|
validateAppLockPassword
|
||||||
} from "../../../common/database/encryption";
|
} from "../../../common/database/encryption";
|
||||||
import BiometicService from "../../../services/biometrics";
|
import BiometricService from "../../../services/biometrics";
|
||||||
import { DDS } from "../../../services/device-detection";
|
import { DDS } from "../../../services/device-detection";
|
||||||
import {
|
import {
|
||||||
ToastManager,
|
ToastManager,
|
||||||
@@ -323,7 +323,7 @@ export const AppLockPassword = () => {
|
|||||||
SettingsService.setProperty("appLockHasPasswordSecurity", false);
|
SettingsService.setProperty("appLockHasPasswordSecurity", false);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!(await BiometicService.isBiometryAvailable()) ||
|
!(await BiometricService.isBiometryAvailable()) ||
|
||||||
SettingsService.getProperty("biometricsAuthEnabled") === false
|
SettingsService.getProperty("biometricsAuthEnabled") === false
|
||||||
) {
|
) {
|
||||||
SettingsService.setProperty("appLockEnabled", false);
|
SettingsService.setProperty("appLockEnabled", false);
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export class VaultDialog extends Component {
|
|||||||
: this.state.copyNote
|
: this.state.copyNote
|
||||||
? "Unlock note to copy it. If biometrics are not working, you can enter device pin to unlock vault."
|
? "Unlock note to copy it. If biometrics are not working, you can enter device pin to unlock vault."
|
||||||
: this.state.goToEditor
|
: this.state.goToEditor
|
||||||
? "Unlock note to open it in editor. If biometrics are not working, you can enter device pin to unlock vault."
|
? "Unlock note to open it in editor."
|
||||||
: "Enter vault password to unlock note. If biometrics are not working, you can enter device pin to unlock vault."
|
: "Enter vault password to unlock note. If biometrics are not working, you can enter device pin to unlock vault."
|
||||||
: "Enter vault password to lock note. If biometrics are not working, you can enter device pin to lock note.");
|
: "Enter vault password to lock note. If biometrics are not working, you can enter device pin to lock note.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ import { SyncStatus, useUserStore } from "../stores/use-user-store";
|
|||||||
import { updateStatusBarColor } from "../utils/colors";
|
import { updateStatusBarColor } from "../utils/colors";
|
||||||
import { BETA } from "../utils/constants";
|
import { BETA } from "../utils/constants";
|
||||||
import {
|
import {
|
||||||
eClearEditor,
|
|
||||||
eCloseSheet,
|
eCloseSheet,
|
||||||
eLoginSessionExpired,
|
eLoginSessionExpired,
|
||||||
eOnLoadNote,
|
eOnLoadNote,
|
||||||
@@ -532,12 +531,6 @@ export const useAppEvents = () => {
|
|||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
globalThis["IS_SHARE_EXTENSION"] = false;
|
globalThis["IS_SHARE_EXTENSION"] = false;
|
||||||
} else {
|
} else {
|
||||||
const id = useTabStore.getState().getCurrentNoteId();
|
|
||||||
const note = id ? await db.notes.note(id) : undefined;
|
|
||||||
const locked = note && (await db.vaults.itemExists(note));
|
|
||||||
if (locked && SettingsService.canLockAppInBackground()) {
|
|
||||||
eSendEvent(eClearEditor);
|
|
||||||
}
|
|
||||||
await saveEditorState();
|
await saveEditorState();
|
||||||
if (
|
if (
|
||||||
SettingsService.canLockAppInBackground() &&
|
SettingsService.canLockAppInBackground() &&
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback, useEffect } from "react";
|
import React, { useCallback, useEffect } from "react";
|
||||||
import BiometicService from "../services/biometrics";
|
import BiometricService from "../services/biometrics";
|
||||||
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
|
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
|
||||||
import { db } from "../common/database";
|
import { db } from "../common/database";
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ export const useVaultStatus = () => {
|
|||||||
|
|
||||||
const checkVaultStatus = useCallback(() => {
|
const checkVaultStatus = useCallback(() => {
|
||||||
db.vault?.exists().then(async (exists) => {
|
db.vault?.exists().then(async (exists) => {
|
||||||
const available = await BiometicService.isBiometryAvailable();
|
const available = await BiometricService.isBiometryAvailable();
|
||||||
const fingerprint = await BiometicService.hasInternetCredentials();
|
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||||
if (
|
if (
|
||||||
VaultStatusCache.exists === exists &&
|
VaultStatusCache.exists === exists &&
|
||||||
VaultStatusCache.biometryEnrolled === fingerprint &&
|
VaultStatusCache.biometryEnrolled === fingerprint &&
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import WebView from "react-native-webview";
|
|||||||
import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
|
import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
|
||||||
import { notesnook } from "../../../e2e/test.ids";
|
import { notesnook } from "../../../e2e/test.ids";
|
||||||
import { db } from "../../common/database";
|
import { db } from "../../common/database";
|
||||||
import BiometicService from "../../services/biometrics";
|
import BiometricService from "../../services/biometrics";
|
||||||
import {
|
import {
|
||||||
ToastManager,
|
ToastManager,
|
||||||
eSendEvent,
|
eSendEvent,
|
||||||
@@ -208,8 +208,8 @@ const useLockedNoteHandler = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const biometry = await BiometicService.isBiometryAvailable();
|
const biometry = await BiometricService.isBiometryAvailable();
|
||||||
const fingerprint = await BiometicService.hasInternetCredentials();
|
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||||
useTabStore.setState({
|
useTabStore.setState({
|
||||||
biometryAvailable: !!biometry,
|
biometryAvailable: !!biometry,
|
||||||
biometryEnrolled: !!fingerprint
|
biometryEnrolled: !!fingerprint
|
||||||
@@ -223,9 +223,9 @@ const useLockedNoteHandler = () => {
|
|||||||
try {
|
try {
|
||||||
if (!tabRef.current?.noteLocked || !tabRef.current) return;
|
if (!tabRef.current?.noteLocked || !tabRef.current) return;
|
||||||
console.log("Trying to unlock with biometrics...");
|
console.log("Trying to unlock with biometrics...");
|
||||||
const credentials = await BiometicService.getCredentials(
|
const credentials = await BiometricService.getCredentials(
|
||||||
"Unlock note",
|
"Unlock note",
|
||||||
"Unlock note to open it in editor. If biometrics are not working, you can enter device pin to unlock vault."
|
"Unlock note to open it in editor."
|
||||||
);
|
);
|
||||||
|
|
||||||
if (credentials && credentials?.password && tabRef.current.noteId) {
|
if (credentials && credentials?.password && tabRef.current.noteId) {
|
||||||
@@ -233,6 +233,7 @@ const useLockedNoteHandler = () => {
|
|||||||
tabRef.current.noteId,
|
tabRef.current.noteId,
|
||||||
credentials?.password
|
credentials?.password
|
||||||
);
|
);
|
||||||
|
|
||||||
eSendEvent(eOnLoadNote, {
|
eSendEvent(eOnLoadNote, {
|
||||||
item: note
|
item: note
|
||||||
});
|
});
|
||||||
@@ -269,7 +270,7 @@ const useLockedNoteHandler = () => {
|
|||||||
try {
|
try {
|
||||||
const unlocked = await db.vault.unlock(password);
|
const unlocked = await db.vault.unlock(password);
|
||||||
if (!unlocked) throw new Error("Incorrect vault password");
|
if (!unlocked) throw new Error("Incorrect vault password");
|
||||||
await BiometicService.storeCredentials(password);
|
await BiometricService.storeCredentials(password);
|
||||||
eSendEvent("vaultUpdated");
|
eSendEvent("vaultUpdated");
|
||||||
ToastManager.show({
|
ToastManager.show({
|
||||||
heading: "Biometric unlocking enabled!",
|
heading: "Biometric unlocking enabled!",
|
||||||
@@ -278,8 +279,8 @@ const useLockedNoteHandler = () => {
|
|||||||
context: "global"
|
context: "global"
|
||||||
});
|
});
|
||||||
|
|
||||||
const biometry = await BiometicService.isBiometryAvailable();
|
const biometry = await BiometricService.isBiometryAvailable();
|
||||||
const fingerprint = await BiometicService.hasInternetCredentials();
|
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||||
useTabStore.setState({
|
useTabStore.setState({
|
||||||
biometryAvailable: !!biometry,
|
biometryAvailable: !!biometry,
|
||||||
biometryEnrolled: !!fingerprint
|
biometryEnrolled: !!fingerprint
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import { Pressable } from "../../components/ui/pressable";
|
|||||||
import Seperator from "../../components/ui/seperator";
|
import Seperator from "../../components/ui/seperator";
|
||||||
import Heading from "../../components/ui/typography/heading";
|
import Heading from "../../components/ui/typography/heading";
|
||||||
import Paragraph from "../../components/ui/typography/paragraph";
|
import Paragraph from "../../components/ui/typography/paragraph";
|
||||||
import BiometicService from "../../services/biometrics";
|
import BiometricService from "../../services/biometrics";
|
||||||
import { ToastManager, presentSheet } from "../../services/event-manager";
|
import { ToastManager, presentSheet } from "../../services/event-manager";
|
||||||
import SettingsService from "../../services/settings";
|
import SettingsService from "../../services/settings";
|
||||||
import { useSettingStore } from "../../stores/use-setting-store";
|
import { useSettingStore } from "../../stores/use-setting-store";
|
||||||
@@ -119,7 +119,7 @@ const AppLock = () => {
|
|||||||
type={appLockMode === item.value ? "secondary" : "transparent"}
|
type={appLockMode === item.value ? "secondary" : "transparent"}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
if (
|
if (
|
||||||
!(await BiometicService.isBiometryAvailable()) &&
|
!(await BiometricService.isBiometryAvailable()) &&
|
||||||
!useUserStore.getState().user &&
|
!useUserStore.getState().user &&
|
||||||
item.value !== modes[0].value &&
|
item.value !== modes[0].value &&
|
||||||
!SettingsService.getProperty("appLockHasPasswordSecurity")
|
!SettingsService.getProperty("appLockHasPasswordSecurity")
|
||||||
@@ -139,7 +139,7 @@ const AppLock = () => {
|
|||||||
) &&
|
) &&
|
||||||
item.value !== modes[0].value
|
item.value !== modes[0].value
|
||||||
) {
|
) {
|
||||||
const verified = await BiometicService.validateUser(
|
const verified = await BiometricService.validateUser(
|
||||||
"Verify it's you"
|
"Verify it's you"
|
||||||
);
|
);
|
||||||
if (verified) {
|
if (verified) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
import { db } from "../../common/database";
|
import { db } from "../../common/database";
|
||||||
import { validateAppLockPassword } from "../../common/database/encryption";
|
import { validateAppLockPassword } from "../../common/database/encryption";
|
||||||
import { presentDialog } from "../../components/dialog/functions";
|
import { presentDialog } from "../../components/dialog/functions";
|
||||||
import BiometicService from "../../services/biometrics";
|
import BiometricService from "../../services/biometrics";
|
||||||
import { ToastManager } from "../../services/event-manager";
|
import { ToastManager } from "../../services/event-manager";
|
||||||
import SettingsService from "../../services/settings";
|
import SettingsService from "../../services/settings";
|
||||||
import { useUserStore } from "../../stores/use-user-store";
|
import { useUserStore } from "../../stores/use-user-store";
|
||||||
@@ -100,9 +100,9 @@ export async function verifyUserWithApplock() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
BiometicService.isBiometryAvailable().then((available) => {
|
BiometricService.isBiometryAvailable().then((available) => {
|
||||||
if (available) {
|
if (available) {
|
||||||
BiometicService.validateUser("Verify it's you").then((verified) => {
|
BiometricService.validateUser("Verify it's you").then((verified) => {
|
||||||
resolve(verified);
|
resolve(verified);
|
||||||
});
|
});
|
||||||
} else if (useUserStore.getState().user) {
|
} else if (useUserStore.getState().user) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import { Update } from "../../components/sheets/update";
|
|||||||
import { VaultStatusType, useVaultStatus } from "../../hooks/use-vault-status";
|
import { VaultStatusType, useVaultStatus } from "../../hooks/use-vault-status";
|
||||||
import { BackgroundSync } from "../../services/background-sync";
|
import { BackgroundSync } from "../../services/background-sync";
|
||||||
import BackupService from "../../services/backup";
|
import BackupService from "../../services/backup";
|
||||||
import BiometicService from "../../services/biometrics";
|
import BiometricService from "../../services/biometrics";
|
||||||
import {
|
import {
|
||||||
ToastManager,
|
ToastManager,
|
||||||
eSendEvent,
|
eSendEvent,
|
||||||
@@ -349,7 +349,7 @@ export const settingsGroups: SettingSection[] = [
|
|||||||
await db.user?.logout();
|
await db.user?.logout();
|
||||||
setLoginMessage();
|
setLoginMessage();
|
||||||
await PremiumService.setPremiumStatus();
|
await PremiumService.setPremiumStatus();
|
||||||
await BiometicService.resetCredentials();
|
await BiometricService.resetCredentials();
|
||||||
MMKV.clearStore();
|
MMKV.clearStore();
|
||||||
clearAllStores();
|
clearAllStores();
|
||||||
refreshAllStores();
|
refreshAllStores();
|
||||||
@@ -394,7 +394,7 @@ export const settingsGroups: SettingSection[] = [
|
|||||||
if (verified) {
|
if (verified) {
|
||||||
eSendEvent("settings-loading", true);
|
eSendEvent("settings-loading", true);
|
||||||
await db.user?.deleteUser(value);
|
await db.user?.deleteUser(value);
|
||||||
await BiometicService.resetCredentials();
|
await BiometricService.resetCredentials();
|
||||||
SettingsService.set({
|
SettingsService.set({
|
||||||
introCompleted: true
|
introCompleted: true
|
||||||
});
|
});
|
||||||
@@ -789,7 +789,7 @@ export const settingsGroups: SettingSection[] = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "biometic-unlock",
|
id: "biometric-unlock",
|
||||||
type: "switch",
|
type: "switch",
|
||||||
name: "Biometric unlocking",
|
name: "Biometric unlocking",
|
||||||
icon: "fingerprint",
|
icon: "fingerprint",
|
||||||
@@ -859,13 +859,13 @@ export const settingsGroups: SettingSection[] = [
|
|||||||
if (!SettingsService.getProperty("appLockEnabled")) {
|
if (!SettingsService.getProperty("appLockEnabled")) {
|
||||||
if (
|
if (
|
||||||
!SettingsService.getProperty("appLockHasPasswordSecurity") &&
|
!SettingsService.getProperty("appLockHasPasswordSecurity") &&
|
||||||
(await BiometicService.isBiometryAvailable())
|
(await BiometricService.isBiometryAvailable())
|
||||||
) {
|
) {
|
||||||
SettingsService.setProperty("biometricsAuthEnabled", true);
|
SettingsService.setProperty("biometricsAuthEnabled", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!(await BiometicService.isBiometryAvailable()) &&
|
!(await BiometricService.isBiometryAvailable()) &&
|
||||||
!SettingsService.getProperty("appLockHasPasswordSecurity")
|
!SettingsService.getProperty("appLockHasPasswordSecurity")
|
||||||
) {
|
) {
|
||||||
ToastManager.show({
|
ToastManager.show({
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ async function validateUser(title: string, description?: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BiometicService = {
|
const BiometricService = {
|
||||||
isBiometryAvailable,
|
isBiometryAvailable,
|
||||||
enableFingerprintAuth,
|
enableFingerprintAuth,
|
||||||
isFingerprintAuthEnabled,
|
isFingerprintAuthEnabled,
|
||||||
@@ -190,4 +190,4 @@ const BiometicService = {
|
|||||||
validateUser
|
validateUser
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BiometicService;
|
export default BiometricService;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import { basename, dirname, join } from "pathe";
|
|||||||
import downloadAttachment from "../common/filesystem/download-attachment";
|
import downloadAttachment from "../common/filesystem/download-attachment";
|
||||||
import { presentDialog } from "../components/dialog/functions";
|
import { presentDialog } from "../components/dialog/functions";
|
||||||
import { useSettingStore } from "../stores/use-setting-store";
|
import { useSettingStore } from "../stores/use-setting-store";
|
||||||
import BiometicService from "./biometrics";
|
import BiometricService from "./biometrics";
|
||||||
import { ToastManager } from "./event-manager";
|
import { ToastManager } from "./event-manager";
|
||||||
import { cacheDir } from "../common/filesystem/utils";
|
import { cacheDir } from "../common/filesystem/utils";
|
||||||
|
|
||||||
@@ -186,10 +186,10 @@ async function exportAs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function unlockVault() {
|
async function unlockVault() {
|
||||||
const biometry = await BiometicService.isBiometryAvailable();
|
const biometry = await BiometricService.isBiometryAvailable();
|
||||||
const fingerprint = await BiometicService.hasInternetCredentials();
|
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||||
if (biometry && fingerprint) {
|
if (biometry && fingerprint) {
|
||||||
const credentials = await BiometicService.getCredentials(
|
const credentials = await BiometricService.getCredentials(
|
||||||
"Unlock vault",
|
"Unlock vault",
|
||||||
"Unlock vault to export locked notes"
|
"Unlock vault to export locked notes"
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user