feat: handle unprotected session expiration (#747)
* feat: hide note contents if the protection expires when the protected note is open and wasn't edited for a while * feat: handle session expiration for opened protected note for both plain advanced editors * fix: if after canceling session expiry modal only one unprotected note stays selected, show its contents in the editor * refactor: handle session expiration for opened protected note (move the logic to web client) * feat: handle the case of selecting "Don't remember" option in session expiry dialog * test (WIP): add unit tests for protecting opened note after the session has expired * test: add remaining unit tests * refactor: move the opened note protection logic to "editor_view" * refactor: reviewer comments - don't rely on user signed-in/out status to require authentication for protected note - remove unnecessary async/awaits - better wording on ui * refactor: reviewer's comments: - use snjs method to check if "Don't remember" option is selected in authentication modal - move the constant to snjs - fix eslint error * refactor: avoid `any` type for `appEvent` payload * test: add unit tests * chore: update function name * refactor: use simpler protection session event types * refactor: protected access terminology * refactor: start counting idle timer after every edit (instead of counting by interval in spite of edits) * test: unit tests * style: don't give extra brightness to the "View Note"/"Authenticate" button on hover/focus * chore: bump snjs version Co-authored-by: Mo Bitar <me@bitar.io>
This commit is contained in:
@@ -1,27 +1,41 @@
|
||||
import { AppState } from '@/ui_models/app_state';
|
||||
import { toDirective } from './utils';
|
||||
|
||||
type Props = { appState: AppState; onViewNote: () => void };
|
||||
type Props = {
|
||||
appState: AppState;
|
||||
onViewNote: () => void;
|
||||
requireAuthenticationForProtectedNote: boolean;
|
||||
};
|
||||
|
||||
function NoProtectionsNoteWarning({
|
||||
appState,
|
||||
onViewNote,
|
||||
requireAuthenticationForProtectedNote,
|
||||
}: Props) {
|
||||
const instructionText = requireAuthenticationForProtectedNote
|
||||
? 'Authenticate to view this note.'
|
||||
: 'Add a passcode or create an account to require authentication to view this note.';
|
||||
|
||||
function NoProtectionsNoteWarning({ appState, onViewNote }: Props) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center text-center max-w-md">
|
||||
<h1 className="text-2xl m-0 w-full">This note is protected</h1>
|
||||
<p className="text-lg mt-2 w-full">
|
||||
Add a passcode or create an account to require authentication to view
|
||||
this note.
|
||||
</p>
|
||||
<p className="text-lg mt-2 w-full">{instructionText}</p>
|
||||
<div className="mt-4 flex gap-3">
|
||||
{!requireAuthenticationForProtectedNote && (
|
||||
<button
|
||||
className="sn-button small info"
|
||||
onClick={() => {
|
||||
appState.accountMenu.setShow(true);
|
||||
}}
|
||||
>
|
||||
Open account menu
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
className="sn-button small info"
|
||||
onClick={() => {
|
||||
appState.accountMenu.setShow(true);
|
||||
}}
|
||||
className="sn-button small outlined normal-focus-brightness"
|
||||
onClick={onViewNote}
|
||||
>
|
||||
Open account menu
|
||||
</button>
|
||||
<button className="sn-button small outlined" onClick={onViewNote}>
|
||||
View note
|
||||
{requireAuthenticationForProtectedNote ? 'Authenticate' : 'View Note'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -32,5 +46,6 @@ export const NoProtectionsdNoteWarningDirective = toDirective<Props>(
|
||||
NoProtectionsNoteWarning,
|
||||
{
|
||||
onViewNote: '&',
|
||||
requireAuthenticationForProtectedNote: '=',
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user