aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/profile-page.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/profile-page.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/profile-page.js26
1 files changed, 26 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/profile-page.js b/packages/meshbay-hub/src/meshbay_hub/static/profile-page.js
index 7e355e7..4d452e1 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/profile-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/profile-page.js
@@ -42,6 +42,23 @@ export function ProfilePage({ user, onLogout }) {
const [delPass, setDelPass] = useState('');
const [delError, setDelError] = useState('');
const [deleting, setDeleting] = useState(false);
+ const [revoking, setRevoking] = useState(false);
+ const [revokeError, setRevokeError] = useState('');
+
+ // Every session of this account stops renewing, this one included — the
+ // case it exists for is a browser left signed in somewhere else.
+ const signOutEverywhere = useCallback(async () => {
+ if (!confirm(t('settings.sign_out_everywhere_confirm'))) return;
+ setRevoking(true);
+ setRevokeError('');
+ try {
+ await hubFetch('/v1/users/me/sessions/revoke', { method: 'POST', token: user.token });
+ onLogout();
+ } catch (err) {
+ setRevokeError(err.message);
+ setRevoking(false);
+ }
+ }, [user, onLogout]);
const deleteAccount = useCallback(async (e) => {
e.preventDefault();
@@ -485,6 +502,15 @@ export function ProfilePage({ user, onLogout }) {
</div>
<div class="settings-section">
+ <h3 class="settings-heading">${t('settings.sessions_heading')}</h3>
+ <p class="settings-hint">${t('settings.sign_out_everywhere_hint')}</p>
+ ${revokeError && html`<p class="error-msg">${revokeError}</p>`}
+ <button class="btn-secondary" disabled=${revoking} onClick=${signOutEverywhere}>
+ ${revoking ? '…' : t('settings.sign_out_everywhere')}
+ </button>
+ </div>
+
+ <div class="settings-section">
<h3 class="settings-heading">${t('settings.danger')}</h3>
<p class="settings-hint">${t('settings.delete_hint')}</p>
${delError && html`<p class="error-msg">${delError}</p>`}