Skip to content

Commit 6047ad3

Browse files
committed
More pleasant flow when auth expires, dev buttons to test
1 parent 105b6fd commit 6047ad3

4 files changed

Lines changed: 116 additions & 20 deletions

File tree

apps/desktop/src-tauri/src/commands.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ pub fn open_overlay_devtools(window: WebviewWindow) {
5050
}
5151
}
5252

53+
#[tauri::command]
54+
pub fn simulate_error_screen(window: WebviewWindow) {
55+
let app = window.app_handle();
56+
57+
if let Some(main_window) = app.get_webview_window(MAIN_WINDOW_NAME) {
58+
let _ = main_window.eval("window.location.hash = '#/error';");
59+
let _ = main_window.show();
60+
let _ = main_window.set_focus();
61+
}
62+
63+
if let Some(settings_window) = app.get_webview_window(SETTINGS_WINDOW_NAME) {
64+
let _ = settings_window.hide();
65+
}
66+
}
67+
5368
#[tauri::command]
5469
pub fn toggle_pin(
5570
window: WebviewWindow,

apps/desktop/src-tauri/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ fn main() {
168168
set_pin,
169169
open_devtools,
170170
open_overlay_devtools,
171+
simulate_error_screen,
171172
close_settings,
172173
open_settings,
173174
set_hide_taskbar_when_pinned,

apps/desktop/src/rpc/manager.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ class UserdataStore {
5252
this.store.removeItem(this.keys.accessToken);
5353
this.store.removeItem(this.keys.accessTokenExpiry);
5454
}
55+
56+
removeUserdata() {
57+
this.store.removeItem(this.keys.userData);
58+
}
59+
60+
clearAuth() {
61+
this.removeAccessToken();
62+
this.removeUserdata();
63+
}
5564
}
5665

5766
/**
@@ -337,14 +346,23 @@ class SocketManager {
337346
// console.log(payload);
338347
// we are ready to do things cause we are fully authed
339348
if (payload.cmd === RPCCommand.AUTHENTICATE && payload.evt === RPCEvent.ERROR) {
340-
// they have a token from the old client id
341-
if (payload.data.code === RPCErrors.INVALID_CLIENTID) {
342-
this.userdataStore.removeAccessToken();
343-
}
344-
345-
// they have an invalid token
346-
if (payload.data.code === RPCErrors.INVALID_TOKEN) {
347-
this.userdataStore.removeAccessToken();
349+
// These are recoverable auth issues (e.g. expired/revoked token),
350+
// so clear auth state and send the user back to the reauth screen.
351+
const shouldReauth = [
352+
RPCErrors.INVALID_CLIENTID,
353+
RPCErrors.INVALID_TOKEN,
354+
RPCErrors.INVALID_USER,
355+
RPCErrors.OAUTH2_ERROR,
356+
].includes(payload.data.code);
357+
358+
if (shouldReauth) {
359+
this.userdataStore.clearAuth();
360+
this.store.setMe(null);
361+
this.store.setCurrentChannel(null);
362+
this.store.clearUsers();
363+
this.navigate("/");
364+
track(Metric.DiscordAuthed, 0);
365+
return;
348366
}
349367

350368
this.store.pushError(payload.data.message);

apps/desktop/src/views/settings/account.tsx

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,53 @@ import * as shell from "@tauri-apps/plugin-shell";
2626

2727
export const Developer = () => {
2828
const platformInfo = usePlatformInfo();
29+
const DEV_TOKEN_BACKUP_KEY = "overlayed:dev:token-backup";
30+
const DEV_TOKEN_EXPIRY_BACKUP_KEY = "overlayed:dev:token-expiry-backup";
31+
const DEV_USER_DATA_BACKUP_KEY = "overlayed:dev:user-data-backup";
32+
33+
const simulateTokenExpiryForTesting = async () => {
34+
const currentToken = localStorage.getItem("discord_access_token");
35+
const currentTokenExpiry = localStorage.getItem("discord_access_token_expiry");
36+
const currentUserData = localStorage.getItem("user_data");
37+
38+
if (currentToken) {
39+
localStorage.setItem(DEV_TOKEN_BACKUP_KEY, currentToken);
40+
}
41+
if (currentTokenExpiry) {
42+
localStorage.setItem(DEV_TOKEN_EXPIRY_BACKUP_KEY, currentTokenExpiry);
43+
}
44+
if (currentUserData) {
45+
localStorage.setItem(DEV_USER_DATA_BACKUP_KEY, currentUserData);
46+
}
47+
48+
// Clear auth keys so the app immediately routes back to the re-auth screen.
49+
localStorage.removeItem("discord_access_token");
50+
localStorage.removeItem("discord_access_token_expiry");
51+
localStorage.removeItem("user_data");
52+
53+
// Bring focus back to the main window where the auth screen is shown.
54+
await invoke("close_settings");
55+
};
56+
57+
const restoreTokenAfterTesting = () => {
58+
const tokenBackup = localStorage.getItem(DEV_TOKEN_BACKUP_KEY);
59+
const tokenExpiryBackup = localStorage.getItem(DEV_TOKEN_EXPIRY_BACKUP_KEY);
60+
const userDataBackup = localStorage.getItem(DEV_USER_DATA_BACKUP_KEY);
61+
62+
if (tokenBackup) {
63+
localStorage.setItem("discord_access_token", tokenBackup);
64+
localStorage.removeItem(DEV_TOKEN_BACKUP_KEY);
65+
}
66+
if (tokenExpiryBackup) {
67+
localStorage.setItem("discord_access_token_expiry", tokenExpiryBackup);
68+
localStorage.removeItem(DEV_TOKEN_EXPIRY_BACKUP_KEY);
69+
}
70+
if (userDataBackup) {
71+
localStorage.setItem("user_data", userDataBackup);
72+
localStorage.removeItem(DEV_USER_DATA_BACKUP_KEY);
73+
}
74+
};
75+
2976
return (
3077
<>
3178
<div className="flex flex-col gap-2">
@@ -35,18 +82,10 @@ export const Developer = () => {
3582
variant="outline"
3683
onClick={async () => {
3784
await invoke("open_devtools");
38-
}}
39-
>
40-
Open Devtools
41-
</Button>
42-
<Button
43-
size="sm"
44-
variant="outline"
45-
onClick={async () => {
4685
await invoke("open_overlay_devtools");
4786
}}
4887
>
49-
Open Overlay Devtools
88+
Open Devtools
5089
</Button>
5190
<Button
5291
size="sm"
@@ -57,7 +96,9 @@ export const Developer = () => {
5796
>
5897
Open Config Dir
5998
</Button>
60-
{import.meta.env.DEV && (
99+
</div>
100+
{import.meta.env.DEV && (
101+
<div className="flex gap-4 pb-2">
61102
<Button
62103
size="sm"
63104
variant="outline"
@@ -67,8 +108,29 @@ export const Developer = () => {
67108
>
68109
Reset FTUE tip
69110
</Button>
70-
)}
71-
</div>
111+
<Button
112+
size="sm"
113+
variant="outline"
114+
onClick={() => {
115+
void simulateTokenExpiryForTesting();
116+
}}
117+
>
118+
Expire Auth
119+
</Button>
120+
<Button size="sm" variant="outline" onClick={restoreTokenAfterTesting}>
121+
Restore Auth
122+
</Button>
123+
<Button
124+
size="sm"
125+
variant="outline"
126+
onClick={async () => {
127+
await invoke("simulate_error_screen");
128+
}}
129+
>
130+
Simulate Error Screen
131+
</Button>
132+
</div>
133+
)}
72134
</div>
73135
</>
74136
);

0 commit comments

Comments
 (0)