feat: line up sessions management with latest SNJS

This commit is contained in:
Baptiste Grob
2021-01-05 12:18:44 +01:00
parent 79b190b47b
commit 7261c2f119
3 changed files with 42 additions and 22 deletions

View File

@@ -1,6 +1,11 @@
import { AppState } from '@/ui_models/app_state'; import { AppState } from '@/ui_models/app_state';
import { PureViewCtrl } from '@/views'; import { PureViewCtrl } from '@/views';
import { SNApplication, RemoteSession, UuidString } from '@standardnotes/snjs'; import {
SNApplication,
RemoteSession,
SessionStrings,
UuidString,
} from '@standardnotes/snjs';
import { autorun, IAutorunOptions, IReactionPublic } from 'mobx'; import { autorun, IAutorunOptions, IReactionPublic } from 'mobx';
import { render, FunctionComponent } from 'preact'; import { render, FunctionComponent } from 'preact';
import { useState, useEffect, useRef } from 'preact/hooks'; import { useState, useEffect, useRef } from 'preact/hooks';
@@ -16,16 +21,20 @@ function useAutorun(view: (r: IReactionPublic) => any, opts?: IAutorunOptions) {
useEffect(() => autorun(view, opts), []); useEffect(() => autorun(view, opts), []);
} }
type Session = RemoteSession & {
revoking?: true;
};
function useSessions( function useSessions(
application: SNApplication application: SNApplication
): [ ): [
RemoteSession[], Session[],
() => void, () => void,
boolean, boolean,
(uuid: UuidString) => Promise<void>, (uuid: UuidString) => Promise<void>,
string string
] { ] {
const [sessions, setSessions] = useState<RemoteSession[]>([]); const [sessions, setSessions] = useState<Session[]>([]);
const [lastRefreshDate, setLastRefreshDate] = useState(Date.now()); const [lastRefreshDate, setLastRefreshDate] = useState(Date.now());
const [refreshing, setRefreshing] = useState(true); const [refreshing, setRefreshing] = useState(true);
const [errorMessage, setErrorMessage] = useState(''); const [errorMessage, setErrorMessage] = useState('');
@@ -41,7 +50,7 @@ function useSessions(
setErrorMessage('An unknown error occured while loading sessions.'); setErrorMessage('An unknown error occured while loading sessions.');
} }
} else { } else {
const sessions = response as RemoteSession[]; const sessions = response as Session[];
setSessions(sessions); setSessions(sessions);
setErrorMessage(''); setErrorMessage('');
} }
@@ -54,9 +63,21 @@ function useSessions(
} }
async function revokeSession(uuid: UuidString) { async function revokeSession(uuid: UuidString) {
const responsePromise = application.revokeSession(uuid);
let sessionsBeforeRevoke = sessions; let sessionsBeforeRevoke = sessions;
setSessions(sessions.filter((session) => session.uuid !== uuid));
const response = await application.revokeSession(uuid); const sessionsDuringRevoke = sessions.slice();
const toRemoveIndex = sessions.findIndex(
(session) => session.uuid === uuid
);
sessionsDuringRevoke[toRemoveIndex] = {
...sessionsDuringRevoke[toRemoveIndex],
revoking: true,
};
setSessions(sessionsDuringRevoke);
const response = await responsePromise;
if ('error' in response) { if ('error' in response) {
if (response.error?.message) { if (response.error?.message) {
setErrorMessage(response.error?.message); setErrorMessage(response.error?.message);
@@ -64,6 +85,8 @@ function useSessions(
setErrorMessage('An unknown error occured while revoking the session.'); setErrorMessage('An unknown error occured while revoking the session.');
} }
setSessions(sessionsBeforeRevoke); setSessions(sessionsBeforeRevoke);
} else {
setSessions(sessions.filter((session) => session.uuid !== uuid));
} }
} }
@@ -84,7 +107,7 @@ const SessionsModal: FunctionComponent<{
errorMessage, errorMessage,
] = useSessions(application); ] = useSessions(application);
const [revokingSessionUuid, setRevokingSessionUuid] = useState(''); const [confirmRevokingSessionUuid, setRevokingSessionUuid] = useState('');
const closeRevokeSessionAlert = () => setRevokingSessionUuid(''); const closeRevokeSessionAlert = () => setRevokingSessionUuid('');
const cancelRevokeRef = useRef<HTMLButtonElement>(); const cancelRevokeRef = useRef<HTMLButtonElement>();
@@ -146,6 +169,7 @@ const SessionsModal: FunctionComponent<{
</p> </p>
<button <button
className="sk-button danger sk-label" className="sk-button danger sk-label"
disabled={session.revoking}
onClick={() => onClick={() =>
setRevokingSessionUuid(session.uuid) setRevokingSessionUuid(session.uuid)
} }
@@ -165,7 +189,7 @@ const SessionsModal: FunctionComponent<{
</div> </div>
</div> </div>
</Dialog> </Dialog>
{revokingSessionUuid && ( {confirmRevokingSessionUuid && (
<AlertDialog leastDestructiveRef={cancelRevokeRef}> <AlertDialog leastDestructiveRef={cancelRevokeRef}>
<div className="sk-modal-content"> <div className="sk-modal-content">
<div className="sn-component"> <div className="sn-component">
@@ -173,14 +197,10 @@ const SessionsModal: FunctionComponent<{
<div className="sk-panel-content"> <div className="sk-panel-content">
<div className="sk-panel-section"> <div className="sk-panel-section">
<AlertDialogLabel className="sk-h3 sk-panel-section-title"> <AlertDialogLabel className="sk-h3 sk-panel-section-title">
Revoke this session? {SessionStrings.RevokeTitle}
</AlertDialogLabel> </AlertDialogLabel>
<AlertDialogDescription className="sk-panel-row"> <AlertDialogDescription className="sk-panel-row">
<p> <p>{SessionStrings.RevokeText}</p>
The associated app will be signed out and all data
removed from the device when it is next launched. You
can sign back in on that device at any time.
</p>
</AlertDialogDescription> </AlertDialogDescription>
<div className="sk-panel-row"> <div className="sk-panel-row">
<div className="sk-button-group"> <div className="sk-button-group">
@@ -189,16 +209,16 @@ const SessionsModal: FunctionComponent<{
ref={cancelRevokeRef} ref={cancelRevokeRef}
onClick={closeRevokeSessionAlert} onClick={closeRevokeSessionAlert}
> >
<span>Cancel</span> <span>{SessionStrings.RevokeCancelButton}</span>
</button> </button>
<button <button
className="sk-button danger sk-label" className="sk-button danger sk-label"
onClick={() => { onClick={() => {
closeRevokeSessionAlert(); closeRevokeSessionAlert();
revokeSession(revokingSessionUuid); revokeSession(confirmRevokingSessionUuid);
}} }}
> >
<span>Revoke</span> <span>{SessionStrings.RevokeConfirmButton}</span>
</button> </button>
</div> </div>
</div> </div>

View File

@@ -71,7 +71,7 @@
"@reach/alert-dialog": "^0.12.1", "@reach/alert-dialog": "^0.12.1",
"@reach/dialog": "^0.12.1", "@reach/dialog": "^0.12.1",
"@standardnotes/sncrypto-web": "^1.2.9", "@standardnotes/sncrypto-web": "^1.2.9",
"@standardnotes/snjs": "^2.0.32", "@standardnotes/snjs": "^2.0.35",
"babel-loader": "^8.2.2", "babel-loader": "^8.2.2",
"mobx": "^6.0.4", "mobx": "^6.0.4",
"preact": "^10.5.7" "preact": "^10.5.7"

View File

@@ -1045,10 +1045,10 @@
"@standardnotes/sncrypto-common" "^1.2.7" "@standardnotes/sncrypto-common" "^1.2.7"
libsodium-wrappers "^0.7.8" libsodium-wrappers "^0.7.8"
"@standardnotes/snjs@^2.0.32": "@standardnotes/snjs@^2.0.35":
version "2.0.32" version "2.0.35"
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.32.tgz#7742e3cb08ee560b5b7cf06e526ebc19ff2a81ba" resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.35.tgz#9e9c3058ebbfc9af7a5fc3ae18497f02a9b1e71b"
integrity sha512-SnbOqGwx5H59HjFSzBKT/1Wh2zAAcx+QSQeYDyKjZKNYN0g8JvirzL0FpoLTxa15BRTl2mG073eIyFsEtx8LFA== integrity sha512-uA4HXorgiV8yFGN1dtO52istUudnc3ZzEQiFLgf0bkKvA0wH3Xt+R9bBviYAdIBkTBKHCyGsBdsCiKr1QS/X9g==
dependencies: dependencies:
"@standardnotes/sncrypto-common" "^1.2.9" "@standardnotes/sncrypto-common" "^1.2.9"