import { WebApplication } from '@/UIModels/Application' import { FunctionalComponent } from 'preact' import { useCallback, useState, useEffect } from 'preact/hooks' import { ApplicationEvent } from '@standardnotes/snjs' import { isSameDay } from '@/Utils' import { PreferencesGroup, PreferencesSegment, Title, Text, } from '@/Components/Preferences/PreferencesComponents' import { Button } from '@/Components/Button/Button' type Props = { application: WebApplication } export const Protections: FunctionalComponent = ({ application }) => { const enableProtections = () => { application.clearProtectionSession().catch(console.error) } const [hasProtections, setHasProtections] = useState(() => application.hasProtectionSources()) const getProtectionsDisabledUntil = useCallback((): string | null => { const protectionExpiry = application.getProtectionSessionExpiryDate() const now = new Date() if (protectionExpiry > now) { let f: Intl.DateTimeFormat if (isSameDay(protectionExpiry, now)) { f = new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: 'numeric', }) } else { f = new Intl.DateTimeFormat(undefined, { weekday: 'long', day: 'numeric', month: 'short', hour: 'numeric', minute: 'numeric', }) } return f.format(protectionExpiry) } return null }, [application]) const [protectionsDisabledUntil, setProtectionsDisabledUntil] = useState( getProtectionsDisabledUntil(), ) useEffect(() => { const removeUnprotectedSessionBeginObserver = application.addEventObserver(async () => { setProtectionsDisabledUntil(getProtectionsDisabledUntil()) }, ApplicationEvent.UnprotectedSessionBegan) const removeUnprotectedSessionEndObserver = application.addEventObserver(async () => { setProtectionsDisabledUntil(getProtectionsDisabledUntil()) }, ApplicationEvent.UnprotectedSessionExpired) const removeKeyStatusChangedObserver = application.addEventObserver(async () => { setHasProtections(application.hasProtectionSources()) }, ApplicationEvent.KeyStatusChanged) return () => { removeUnprotectedSessionBeginObserver() removeUnprotectedSessionEndObserver() removeKeyStatusChangedObserver() } }, [application, getProtectionsDisabledUntil]) if (!hasProtections) { return null } return ( Protections {protectionsDisabledUntil ? ( Unprotected access expires at {protectionsDisabledUntil}. ) : ( Protections are enabled. )} Actions like viewing or searching protected notes, exporting decrypted backups, or revoking an active session require additional authentication such as entering your account password or application passcode. {protectionsDisabledUntil && (