mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 19:49:54 +02:00
Merge pull request #9931 from kashaf-ansari-dev/fix-vault-dialog-form-input
mobile: replace Input with FormInput in VaultDialog for inline field …
This commit is contained in:
@@ -51,7 +51,10 @@ import DialogButtons from "../../dialog/dialog-buttons";
|
||||
import DialogHeader from "../../dialog/dialog-header";
|
||||
import { Toast } from "../../toast";
|
||||
import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
import FormInput, {
|
||||
createFormRef,
|
||||
validators
|
||||
} from "../../ui/input/form-input";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
@@ -70,8 +73,6 @@ export const VaultDialog: React.FC = () => {
|
||||
// UI State
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [wrongPassword, setWrongPassword] = useState(false);
|
||||
const [passwordsDontMatch, setPasswordsDontMatch] = useState(false);
|
||||
const [deleteAll, setDeleteAll] = useState(false);
|
||||
const [biometricUnlock, setBiometricUnlock] = useState(false);
|
||||
const [isBiometryAvailable, setIsBiometryAvailable] = useState(false);
|
||||
@@ -100,15 +101,19 @@ export const VaultDialog: React.FC = () => {
|
||||
| undefined
|
||||
>(undefined);
|
||||
|
||||
// Form ref
|
||||
const formRef = useRef(
|
||||
createFormRef({
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
newPassword: ""
|
||||
})
|
||||
);
|
||||
|
||||
// Input refs
|
||||
const passInputRef = useRef<TextInput>(null);
|
||||
const confirmPassRef = useRef<TextInput>(null);
|
||||
const changePassInputRef = useRef<TextInput>(null);
|
||||
|
||||
// Password refs
|
||||
const passwordRef = useRef<string | null>(null);
|
||||
const confirmPasswordRef = useRef<string | null>(null);
|
||||
const newPasswordRef = useRef<string | null>(null);
|
||||
const newPassInputRef = useRef<TextInput>(null);
|
||||
|
||||
const close = useCallback(() => {
|
||||
if (loading) {
|
||||
@@ -123,10 +128,11 @@ export const VaultDialog: React.FC = () => {
|
||||
|
||||
Navigation.queueRoutesForUpdate();
|
||||
|
||||
// Reset password refs
|
||||
passwordRef.current = null;
|
||||
confirmPasswordRef.current = null;
|
||||
newPasswordRef.current = null;
|
||||
// Reset form values and errors
|
||||
formRef.current.setValue("password", "");
|
||||
formRef.current.setValue("confirmPassword", "");
|
||||
formRef.current.setValue("newPassword", "");
|
||||
formRef.current.clearErrors();
|
||||
|
||||
// Reset refs
|
||||
requestTypeRef.current = null;
|
||||
@@ -144,8 +150,6 @@ export const VaultDialog: React.FC = () => {
|
||||
// Reset UI state
|
||||
setVisible(false);
|
||||
setLoading(false);
|
||||
setWrongPassword(false);
|
||||
setPasswordsDontMatch(false);
|
||||
setDeleteAll(false);
|
||||
setBiometricUnlock(false);
|
||||
setIsBiometryAvailable(false);
|
||||
@@ -155,9 +159,10 @@ export const VaultDialog: React.FC = () => {
|
||||
const deleteVault = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const { password } = formRef.current.getValues();
|
||||
let verified = true;
|
||||
if (await db.user.getUser()) {
|
||||
verified = await db.user.verifyPassword(passwordRef.current || "");
|
||||
verified = await db.user.verifyPassword(password);
|
||||
}
|
||||
if (verified) {
|
||||
let noteIds: string[] = [];
|
||||
@@ -175,6 +180,7 @@ export const VaultDialog: React.FC = () => {
|
||||
noteIds = relations.map((item) => item.toId);
|
||||
}
|
||||
await db.vault.delete(deleteAll);
|
||||
await BiometricService.resetCredentials();
|
||||
|
||||
if (deleteAll) {
|
||||
noteIds.forEach((id) => {
|
||||
@@ -195,11 +201,7 @@ export const VaultDialog: React.FC = () => {
|
||||
}, 100);
|
||||
} else {
|
||||
setLoading(false);
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -209,11 +211,12 @@ export const VaultDialog: React.FC = () => {
|
||||
const clearVault = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const { password } = formRef.current.getValues();
|
||||
const vault = await db.vaults.default();
|
||||
const relations = await db.relations.from(vault!, "note").get();
|
||||
const noteIds = relations.map((item) => item.toId);
|
||||
|
||||
await db.vault.clear(passwordRef.current || "");
|
||||
await db.vault.clear(password);
|
||||
|
||||
noteIds.forEach((id) => {
|
||||
eSendEvent(
|
||||
@@ -233,11 +236,7 @@ export const VaultDialog: React.FC = () => {
|
||||
type: "success"
|
||||
});
|
||||
} catch (e) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
}
|
||||
setLoading(false);
|
||||
}, [close]);
|
||||
@@ -257,12 +256,7 @@ export const VaultDialog: React.FC = () => {
|
||||
});
|
||||
close();
|
||||
} catch (e) {
|
||||
close();
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
@@ -270,24 +264,14 @@ export const VaultDialog: React.FC = () => {
|
||||
);
|
||||
|
||||
const takeErrorAction = useCallback(() => {
|
||||
setWrongPassword(true);
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
setVisible(true);
|
||||
setTimeout(() => {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
}, 500);
|
||||
}, []);
|
||||
|
||||
const lockNote = useCallback(async () => {
|
||||
if (!passwordRef.current || passwordRef.current.trim() === "") {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
const { password } = formRef.current.getValues();
|
||||
if (!password || password.trim() === "") {
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
return;
|
||||
} else {
|
||||
await db.vault.add(noteRef.current!.id);
|
||||
@@ -305,8 +289,9 @@ export const VaultDialog: React.FC = () => {
|
||||
}, [close]);
|
||||
|
||||
const permanantUnlock = useCallback(() => {
|
||||
const { password } = formRef.current.getValues();
|
||||
db.vault
|
||||
.remove(noteRef.current!.id, passwordRef.current || "")
|
||||
.remove(noteRef.current!.id, password)
|
||||
.then(async () => {
|
||||
ToastManager.show({
|
||||
heading: strings.noteUnlocked(),
|
||||
@@ -315,7 +300,7 @@ export const VaultDialog: React.FC = () => {
|
||||
});
|
||||
eSendEvent(eUpdateNoteInEditor, noteRef.current, true);
|
||||
if (biometricUnlock && !isBiometryEnrolled) {
|
||||
await enrollFingerprint(passwordRef.current || "");
|
||||
await enrollFingerprint(password);
|
||||
}
|
||||
close();
|
||||
})
|
||||
@@ -375,8 +360,9 @@ export const VaultDialog: React.FC = () => {
|
||||
);
|
||||
|
||||
const deleteNote = useCallback(async () => {
|
||||
const { password } = formRef.current.getValues();
|
||||
try {
|
||||
await db.vault.remove(noteRef.current!.id, passwordRef.current || "");
|
||||
await db.vault.remove(noteRef.current!.id, password);
|
||||
await deleteItems("note", [noteRef.current!.id]);
|
||||
close();
|
||||
} catch (e) {
|
||||
@@ -385,16 +371,14 @@ export const VaultDialog: React.FC = () => {
|
||||
}, [close, takeErrorAction]);
|
||||
|
||||
const openNote = useCallback(async () => {
|
||||
const { password } = formRef.current.getValues();
|
||||
try {
|
||||
if (!passwordRef.current) throw new Error("Invalid password");
|
||||
if (!password) throw new Error("Invalid password");
|
||||
|
||||
const note = await db.vault.open(
|
||||
noteRef.current!.id,
|
||||
passwordRef.current
|
||||
);
|
||||
const note = await db.vault.open(noteRef.current!.id, password);
|
||||
if (!note) throw new Error("Failed to unlock note.");
|
||||
if (biometricUnlock && !isBiometryEnrolled) {
|
||||
await enrollFingerprint(passwordRef.current || "");
|
||||
await enrollFingerprint(password);
|
||||
}
|
||||
|
||||
const requestType = requestTypeRef.current;
|
||||
@@ -411,7 +395,6 @@ export const VaultDialog: React.FC = () => {
|
||||
requestType === VaultRequestType.CustomAction &&
|
||||
onUnlockRef.current
|
||||
) {
|
||||
const password = passwordRef.current;
|
||||
const unlock = onUnlockRef.current;
|
||||
close();
|
||||
await sleep(500);
|
||||
@@ -433,12 +416,9 @@ export const VaultDialog: React.FC = () => {
|
||||
]);
|
||||
|
||||
const unlockNote = useCallback(async () => {
|
||||
if (!passwordRef.current || passwordRef.current.trim() === "") {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
const { password } = formRef.current.getValues();
|
||||
if (!password || password.trim() === "") {
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
return;
|
||||
}
|
||||
if (requestTypeRef.current === VaultRequestType.PermanentUnlock) {
|
||||
@@ -449,10 +429,11 @@ export const VaultDialog: React.FC = () => {
|
||||
}, [permanantUnlock, openNote]);
|
||||
|
||||
const createVault = useCallback(async () => {
|
||||
await db.vault.create(passwordRef.current || "");
|
||||
const { password } = formRef.current.getValues();
|
||||
await db.vault.create(password);
|
||||
|
||||
if (biometricUnlock) {
|
||||
await enrollFingerprint(passwordRef.current || "");
|
||||
await enrollFingerprint(password);
|
||||
}
|
||||
if (noteRef.current?.id) {
|
||||
await db.vault.add(noteRef.current.id);
|
||||
@@ -504,36 +485,23 @@ export const VaultDialog: React.FC = () => {
|
||||
|
||||
if (loading) return;
|
||||
|
||||
if (!passwordRef.current) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordNotEntered(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!formRef.current.validate()) return;
|
||||
|
||||
const { password, newPassword } = formRef.current.getValues();
|
||||
|
||||
if (requestType === VaultRequestType.CreateVault) {
|
||||
if (passwordRef.current !== confirmPasswordRef.current) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordNotMatched(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
setPasswordsDontMatch(true);
|
||||
return;
|
||||
}
|
||||
|
||||
createVault();
|
||||
} else if (requestType === VaultRequestType.ChangePassword) {
|
||||
setLoading(true);
|
||||
|
||||
db.vault
|
||||
.changePassword(passwordRef.current, newPasswordRef.current || "")
|
||||
.then(() => {
|
||||
.changePassword(password, newPassword)
|
||||
.then(async () => {
|
||||
setLoading(false);
|
||||
if (biometricUnlock) {
|
||||
enrollFingerprint(newPasswordRef.current || "");
|
||||
enrollFingerprint(newPassword);
|
||||
} else {
|
||||
await BiometricService.resetCredentials();
|
||||
}
|
||||
ToastManager.show({
|
||||
heading: strings.passwordUpdated(),
|
||||
@@ -545,37 +513,23 @@ export const VaultDialog: React.FC = () => {
|
||||
.catch((e) => {
|
||||
setLoading(false);
|
||||
if (e.message === VAULT_ERRORS.wrongPassword) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
} else {
|
||||
ToastManager.error(e);
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
} else if (requestType === VaultRequestType.LockNote) {
|
||||
if (!passwordRef.current || passwordRef.current.trim() === "") {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
setWrongPassword(true);
|
||||
return;
|
||||
}
|
||||
db.vault
|
||||
.unlock(passwordRef.current)
|
||||
.unlock(password)
|
||||
.then(async (unlocked) => {
|
||||
if (unlocked) {
|
||||
setWrongPassword(false);
|
||||
await lockNote();
|
||||
} else {
|
||||
takeErrorAction();
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
takeErrorAction();
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
});
|
||||
} else if (
|
||||
requestType === VaultRequestType.UnlockNote ||
|
||||
@@ -586,22 +540,13 @@ export const VaultDialog: React.FC = () => {
|
||||
requestType === VaultRequestType.DeleteNote ||
|
||||
requestType === VaultRequestType.CustomAction
|
||||
) {
|
||||
if (!passwordRef.current || passwordRef.current.trim() === "") {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
setWrongPassword(true);
|
||||
return;
|
||||
}
|
||||
if (noteLockedRef.current) {
|
||||
await unlockNote();
|
||||
} else {
|
||||
console.log("Error: Note should be locked for this operation");
|
||||
}
|
||||
} else if (requestType === VaultRequestType.EnableFingerprint) {
|
||||
enrollFingerprint(passwordRef.current);
|
||||
enrollFingerprint(password);
|
||||
} else if (requestType === VaultRequestType.ClearVault) {
|
||||
await clearVault();
|
||||
} else if (requestType === VaultRequestType.DeleteVault) {
|
||||
@@ -616,7 +561,6 @@ export const VaultDialog: React.FC = () => {
|
||||
enrollFingerprint,
|
||||
unlockNote,
|
||||
lockNote,
|
||||
takeErrorAction,
|
||||
clearVault,
|
||||
deleteVault
|
||||
]);
|
||||
@@ -632,7 +576,7 @@ export const VaultDialog: React.FC = () => {
|
||||
if (!credentials) throw new Error("Failed to get user credentials");
|
||||
|
||||
if (credentials?.password) {
|
||||
passwordRef.current = credentials.password;
|
||||
formRef.current.setValue("password", credentials.password);
|
||||
onPress();
|
||||
} else {
|
||||
eSendEvent(eCloseActionSheet);
|
||||
@@ -679,8 +623,6 @@ export const VaultDialog: React.FC = () => {
|
||||
setIsBiometryAvailable(available);
|
||||
setIsBiometryEnrolled(fingerprint);
|
||||
setBiometricUnlock(fingerprint);
|
||||
setWrongPassword(false);
|
||||
setPasswordsDontMatch(false);
|
||||
setDeleteAll(false);
|
||||
setLoading(false);
|
||||
|
||||
@@ -772,14 +714,14 @@ export const VaultDialog: React.FC = () => {
|
||||
isCustomAction) &&
|
||||
!isRevokeFingerprint ? (
|
||||
<>
|
||||
<Input
|
||||
<FormInput
|
||||
name="password"
|
||||
formRef={formRef}
|
||||
fwdRef={passInputRef}
|
||||
editable={!loading}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwd}
|
||||
onChangeText={(value) => {
|
||||
passwordRef.current = value;
|
||||
}}
|
||||
autoComplete="password"
|
||||
marginBottom={
|
||||
!biometricUnlock ||
|
||||
!isBiometryEnrolled ||
|
||||
@@ -789,14 +731,13 @@ export const VaultDialog: React.FC = () => {
|
||||
? 0
|
||||
: 10
|
||||
}
|
||||
onSubmit={() => {
|
||||
onSubmitEditing={() => {
|
||||
if (isChangePassword) {
|
||||
confirmPassRef.current?.focus();
|
||||
newPassInputRef.current?.focus();
|
||||
} else {
|
||||
onPress();
|
||||
}
|
||||
}}
|
||||
autoComplete="password"
|
||||
returnKeyLabel={
|
||||
isChangePassword ? strings.next() : titleRef.current
|
||||
}
|
||||
@@ -807,6 +748,7 @@ export const VaultDialog: React.FC = () => {
|
||||
? strings.currentPassword()
|
||||
: strings.password()
|
||||
}
|
||||
validators={[validators.required(strings.passwordRequired())]}
|
||||
/>
|
||||
|
||||
{!biometricUnlock ||
|
||||
@@ -849,70 +791,67 @@ export const VaultDialog: React.FC = () => {
|
||||
{isChangePassword ? (
|
||||
<>
|
||||
<Seperator half />
|
||||
<Input
|
||||
fwdRef={confirmPassRef}
|
||||
<FormInput
|
||||
name="newPassword"
|
||||
formRef={formRef}
|
||||
fwdRef={newPassInputRef}
|
||||
editable={!loading}
|
||||
testID={notesnook.ids.dialogs.vault.changePwd}
|
||||
autoCapitalize="none"
|
||||
onChangeText={(value) => {
|
||||
newPasswordRef.current = value;
|
||||
}}
|
||||
autoComplete="password"
|
||||
onSubmit={() => {
|
||||
onSubmitEditing={() => {
|
||||
onPress();
|
||||
}}
|
||||
returnKeyLabel="Change"
|
||||
returnKeyType="done"
|
||||
secureTextEntry
|
||||
placeholder={strings.newPassword()}
|
||||
validators={[validators.required(strings.passwordRequired())]}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{isCreateVault ? (
|
||||
<View>
|
||||
<Input
|
||||
<FormInput
|
||||
name="password"
|
||||
formRef={formRef}
|
||||
fwdRef={passInputRef}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwd}
|
||||
onChangeText={(value) => {
|
||||
passwordRef.current = value;
|
||||
}}
|
||||
autoComplete="password"
|
||||
returnKeyLabel={strings.next()}
|
||||
returnKeyType="next"
|
||||
secureTextEntry
|
||||
onSubmit={() => {
|
||||
onSubmitEditing={() => {
|
||||
confirmPassRef.current?.focus();
|
||||
}}
|
||||
placeholder={strings.password()}
|
||||
validators={[validators.required(strings.passwordRequired())]}
|
||||
/>
|
||||
|
||||
<Input
|
||||
<FormInput
|
||||
name="confirmPassword"
|
||||
formRef={formRef}
|
||||
fwdRef={confirmPassRef}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwdAlt}
|
||||
secureTextEntry
|
||||
validationType="confirmPassword"
|
||||
customValidator={() => passwordRef.current || ""}
|
||||
errorMessage="Passwords do not match."
|
||||
onErrorCheck={() => null}
|
||||
marginBottom={0}
|
||||
autoComplete="password"
|
||||
returnKeyLabel="Create"
|
||||
returnKeyType="done"
|
||||
onChangeText={(value) => {
|
||||
confirmPasswordRef.current = value;
|
||||
if (value !== passwordRef.current) {
|
||||
setPasswordsDontMatch(true);
|
||||
} else {
|
||||
setPasswordsDontMatch(false);
|
||||
}
|
||||
}}
|
||||
onSubmit={() => {
|
||||
marginBottom={0}
|
||||
onSubmitEditing={() => {
|
||||
onPress();
|
||||
}}
|
||||
placeholder={strings.confirmPassword()}
|
||||
validators={[
|
||||
validators.required(strings.confirmPasswordRequired()),
|
||||
validators.matchField(
|
||||
"password",
|
||||
strings.passwordNotMatched()
|
||||
)
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -64,6 +64,7 @@ import { strings } from "@notesnook/intl";
|
||||
import { i18n } from "@lingui/core";
|
||||
import { useVaultStatus } from "../../hooks/use-vault-status";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
import { NativeEvents } from "@notesnook/editor-mobile/src/utils/native-events";
|
||||
|
||||
const style: ViewStyle = {
|
||||
height: "100%",
|
||||
@@ -268,17 +269,22 @@ const useLockedNoteHandler = () => {
|
||||
|
||||
const onSubmit = async ({
|
||||
password,
|
||||
biometrics: enrollBiometrics
|
||||
biometrics: enrollBiometrics,
|
||||
resolverId
|
||||
}: {
|
||||
password: string;
|
||||
biometrics?: boolean;
|
||||
resolverId?: string;
|
||||
}) => {
|
||||
if (!tabRef.current?.session?.noteId || !tabRef.current) return;
|
||||
|
||||
if (!password || password.trim().length === 0) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordNotEntered(),
|
||||
type: "error"
|
||||
});
|
||||
if (resolverId) {
|
||||
editorController.current?.postMessage(NativeEvents.resolve, {
|
||||
resolverId,
|
||||
data: { success: false, error: strings.passwordNotEntered() }
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -287,6 +293,7 @@ const useLockedNoteHandler = () => {
|
||||
tabRef.current?.session?.noteId,
|
||||
password
|
||||
);
|
||||
|
||||
if (enrollBiometrics && note) {
|
||||
try {
|
||||
const unlocked = await db.vault.unlock(password);
|
||||
@@ -298,7 +305,6 @@ const useLockedNoteHandler = () => {
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
|
||||
const biometry = await BiometricService.isBiometryAvailable();
|
||||
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||
useTabStore.setState({
|
||||
@@ -306,22 +312,24 @@ const useLockedNoteHandler = () => {
|
||||
biometryEnrolled: !!fingerprint
|
||||
});
|
||||
syncTabs();
|
||||
} catch (e) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
eSendEvent(eOnLoadNote, {
|
||||
item: note,
|
||||
refresh: true
|
||||
});
|
||||
|
||||
if (resolverId) {
|
||||
editorController.current?.postMessage(NativeEvents.resolve, {
|
||||
resolverId,
|
||||
data: { success: true }
|
||||
});
|
||||
}
|
||||
|
||||
eSendEvent(eOnLoadNote, { item: note, refresh: true });
|
||||
} catch (e) {
|
||||
ToastManager.show({
|
||||
heading: strings.passwordIncorrect(),
|
||||
type: "error"
|
||||
});
|
||||
if (resolverId) {
|
||||
editorController.current?.postMessage(NativeEvents.resolve, {
|
||||
resolverId,
|
||||
data: { success: false, error: strings.passwordIncorrect() }
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -721,7 +721,10 @@ export const useEditorEvents = (
|
||||
}
|
||||
|
||||
case EditorEvents.unlock: {
|
||||
eSendEvent(eUnlockWithPassword, editorMessage.value);
|
||||
eSendEvent(eUnlockWithPassword, {
|
||||
...editorMessage.value,
|
||||
resolverId: editorMessage.resolverId
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ export default class Vault {
|
||||
async remove(noteId: string, password: string) {
|
||||
await this.unlockNote(noteId, password, true);
|
||||
|
||||
if (!(await this.exists())) await this.create(password);
|
||||
await this.db.relations.to({ id: noteId, type: "note" }, "vault").unlink();
|
||||
}
|
||||
|
||||
@@ -203,9 +202,11 @@ export default class Vault {
|
||||
);
|
||||
|
||||
if (password) {
|
||||
this.password = password;
|
||||
if (!(await this.exists())) await this.create(password);
|
||||
try {
|
||||
await this.unlock(password);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return { ...note, content };
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ const Tiptap = ({
|
||||
const tab = useTabContext();
|
||||
const isFocused = useTabStore((state) => state.currentTab === tab?.id);
|
||||
const [tick, setTick] = useState(0);
|
||||
const [passwordError, setPasswordError] = useState<string | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const noteStateUpdateTimer = useRef<NodeJS.Timeout>();
|
||||
const tabRef = useRef<TabItem>(tab);
|
||||
@@ -84,6 +85,9 @@ const Tiptap = ({
|
||||
undo,
|
||||
redo
|
||||
};
|
||||
useEffect(() => {
|
||||
setPasswordError(null);
|
||||
}, [tab.session?.noteId]);
|
||||
|
||||
logger("info", tabRef.current.id, "rendering");
|
||||
|
||||
@@ -660,15 +664,31 @@ const Tiptap = ({
|
||||
</p>
|
||||
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
const data = new FormData(e.currentTarget);
|
||||
const password = data.get("password");
|
||||
if (!password) {
|
||||
setPasswordError(strings.enterPassword());
|
||||
return;
|
||||
}
|
||||
|
||||
setPasswordError(null);
|
||||
const biometrics = data.get("enrollBiometrics");
|
||||
post("editor-events:unlock", {
|
||||
password,
|
||||
biometrics: biometrics === "on" ? true : false
|
||||
});
|
||||
|
||||
const result = await postAsyncWithTimeout(
|
||||
EditorEvents.unlock,
|
||||
{
|
||||
password,
|
||||
biometrics: biometrics === "on"
|
||||
}
|
||||
);
|
||||
|
||||
if (result && !result.success) {
|
||||
setPasswordError(
|
||||
result.error || strings.passwordIncorrect()
|
||||
);
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
display: "flex",
|
||||
@@ -683,7 +703,9 @@ const Tiptap = ({
|
||||
ref={controller.passwordInputRef}
|
||||
name="password"
|
||||
type="password"
|
||||
required
|
||||
onChange={() => {
|
||||
if (passwordError) setPasswordError(null);
|
||||
}}
|
||||
style={{
|
||||
boxSizing: "border-box",
|
||||
width: 300,
|
||||
@@ -698,6 +720,19 @@ const Tiptap = ({
|
||||
color: colors.primary.paragraph
|
||||
}}
|
||||
/>
|
||||
{passwordError ? (
|
||||
<p
|
||||
style={{
|
||||
color: colors.error.paragraph,
|
||||
fontSize: "0.8rem",
|
||||
margin: 0,
|
||||
width: 300,
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
{passwordError}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
<button
|
||||
className="unlock-note"
|
||||
|
||||
Reference in New Issue
Block a user