feat: line up sessions management with latest SNJS
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user