handle logout
Seto Elkahfi committed
Aug 1, 2024 at 12:58 UTC
fcf585913a468528376471e77337afaba2176fce
6 files changed
+99
-40
frontend/splitfire-desktop/app/_src/lib/tauriHandler.ts
+1
@@ -14,6 +14,7 @@ export const TAURI_PLAYER_RECORDING_LENGTH = 'player_recording_length' // in se
14
15
// Account
16
export const TAURI_ACCOUNT_LOGIN = 'account_login'
17
+export const TAURI_ACCOUNT_LOGOUT = 'account_logout'
18
export const TAURI_ACCOUNT_REGISTER = 'account_register'
19
20
export enum TauriResponse {
frontend/splitfire-desktop/app/_ui/global-nav.tsx
+2
@@ -9,7 +9,9 @@ import { useContext, useState } from 'react';
9
import Image from 'next/image';
10
import { UserContext } from '../_src/lib/CurrentUserContext';
11
12
+
13
export function GlobalNav() {
14
+
15
const [isOpen, setIsOpen] = useState(false);
16
const close = () => setIsOpen(false);
17
const user = useContext(UserContext);
frontend/splitfire-desktop/app/logout/page.tsx
+37
-12
@@ -1,20 +1,45 @@
1
-export async function generateStaticParams() {
2
- const posts = [
3
- { slug: "post-1" },
4
- { slug: "post-2" },
5
- { slug: "post-3" },
6
- ];
7
-
8
- return posts.map((post) => ({
9
- slug: post.slug,
10
- }))
1
+"use client";
2
+
3
+import { useContext, useEffect, useState } from "react";
4
+import { UserContext } from "../_src/lib/CurrentUserContext";
5
+import { useLogger } from "../_src/lib/logger";
6
+import { db } from "../_src/lib/db";
7
+import { invoke } from "@tauri-apps/api/tauri";
8
+import { TAURI_ACCOUNT_LOGOUT } from "../_src/lib/tauriHandler";
9
+import { useRouter } from "next/navigation";
10
+
11
+enum State {
12
+ LOADING,
13
+ LOADED,
14
+ ERROR,
15
}
16
17
export default function Page() {
18
+ const [state, setState] = useState(State.LOADING);
19
+ const log = useLogger("Logout/Page");
20
+ const currentUser = useContext(UserContext);
21
+ const router = useRouter();
22
+
23
+ useEffect(() => {
24
+ async function logout() {
25
+ log.debug(currentUser);
26
+ db.currentUser.clear();
27
+ if (currentUser.user?.accessToken) {
28
+ const res = await invoke(TAURI_ACCOUNT_LOGOUT, {
29
+ accessToken: currentUser.user?.accessToken,
30
+ });
31
+ log.debug(res);
32
+ }
33
+ setState(State.LOADED);
34
+ router.push("/");
35
+ }
36
+ logout();
37
+ // eslint-disable-next-line react-hooks/exhaustive-deps
38
+ }, [state]);
39
+ const text = state === State.LOADING ? "Logging out..." : "Logged out";
40
return (
41
<div className="prose prose-sm prose-invert max-w-none">
16
- <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
17
- </div>
42
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">{text}</div>
43
</div>
44
);
45
}
frontend/splitfire-desktop/src-tauri/src/main.rs
+9
-2
@@ -18,8 +18,14 @@ use app::{
18
player_unmount::{__cmd__player_unmount, player_unmount},
19
},
20
rest::{
21
- account::{__cmd__account_login, __cmd__account_register, account_login, account_register},
22
- content::{__cmd__content_carousel, __cmd__content_ready_to_play, content_carousel, content_ready_to_play},
21
+ account::{
22
+ __cmd__account_login, __cmd__account_logout, __cmd__account_register, account_login,
23
+ account_logout, account_register,
24
+ },
25
+ content::{
26
+ __cmd__content_carousel, __cmd__content_ready_to_play, content_carousel,
27
+ content_ready_to_play,
28
+ },
29
},
30
sfai_home_dir_path,
31
};
@@ -55,6 +61,7 @@ fn main() {
61
})
62
.invoke_handler(tauri::generate_handler![
63
account_login,
64
+ account_logout,
65
account_register,
66
open_lyrics_editor,
67
open_player,
frontend/splitfire-desktop/src-tauri/src/models/player.rs
+1
-1
@@ -24,7 +24,7 @@ impl Display for ResultFile {
24
25
#[derive(Serialize, Deserialize)]
26
#[derive(Debug)]
27
-enum Status {
27
+pub enum Status {
28
#[serde(rename = "downloading")]
29
Downloading,
30
#[serde(rename = "splitting")]
frontend/splitfire-desktop/src-tauri/src/rest/account.rs
+49
-25
@@ -1,19 +1,30 @@
1
+use crate::{
2
+ command::constants::{
3
+ base_url_builder, PATH_ACCOUNT_LOGIN, PATH_ACCOUNT_LOGOUT, PATH_ACCOUNT_REGISTER,
4
+ },
5
+ models::{
6
+ account::{AccountLoginResponse, LoginResponse},
7
+ player::TauriResponse,
8
+ },
9
+};
10
use log::debug;
11
use reqwest::Client;
12
use serde_json::json;
13
use tauri;
5
-use crate::{command::constants::{base_url_builder, PATH_ACCOUNT_LOGIN, PATH_ACCOUNT_REGISTER}, models::{account::{AccountLoginResponse, LoginResponse}, player::TauriResponse}};
14
15
#[tauri::command]
16
pub async fn account_login(username: String, password: String) -> AccountLoginResponse {
9
- debug!("Logging in with username {}, password {}", username, password);
17
+ debug!(
18
+ "Logging in with username {}, password {}",
19
+ username, password
20
+ );
21
// Login
22
let body = json!( {
23
"username": username,
24
"password": password
25
});
26
let response = Client::new()
16
- .post(login_url_builder())
27
+ .post(account_url_builder(PATH_ACCOUNT_LOGIN))
28
.json(&body)
29
.send()
30
.await;
@@ -24,42 +35,38 @@ pub async fn account_login(username: String, password: String) -> AccountLoginRe
35
Some(token) => {
36
// Trim Bearer prefix
37
let token = match token.to_str() {
27
- Ok(token) => {
28
- token.trim_start_matches("Bearer ")
29
- },
38
+ Ok(token) => token.trim_start_matches("Bearer "),
39
Err(e) => {
40
println!("Failed to get token: {:?}", e);
41
return AccountLoginResponse {
42
status: TauriResponse::Error,
43
message: "Failed to get token".to_string(),
44
access_token: None,
36
- user: None
45
+ user: None,
46
};
47
}
48
};
49
Some(token.to_string())
41
- },
50
+ }
51
None => {
52
println!("Failed to get token");
53
return AccountLoginResponse {
54
status: TauriResponse::Error,
55
message: "Failed to get token".to_string(),
56
access_token: None,
48
- user: None
57
+ user: None,
58
};
59
}
60
};
61
let res: LoginResponse = match response.json().await {
53
- Ok(json) => {
54
- json
55
- },
62
+ Ok(json) => json,
63
Err(e) => {
64
println!("Failed to parse response: {:?}", e);
65
return AccountLoginResponse {
66
status: TauriResponse::Error,
67
message: "Failed to parse response".to_string(),
68
access_token: None,
62
- user: None
69
+ user: None,
70
};
71
}
72
};
@@ -69,7 +76,7 @@ pub async fn account_login(username: String, password: String) -> AccountLoginRe
76
status: TauriResponse::Success,
77
message: res.message,
78
access_token: token,
72
- user: res.user
79
+ user: res.user,
80
}
81
}
82
Err(e) => {
@@ -78,15 +85,38 @@ pub async fn account_login(username: String, password: String) -> AccountLoginRe
85
status: TauriResponse::Error,
86
message: "Failed to get response".to_string(),
87
access_token: None,
81
- user: None
88
+ user: None,
89
}
90
}
91
}
92
}
93
94
+#[tauri::command]
95
+pub async fn account_logout(access_token: String) {
96
+ debug!("Logging out with access token {}", access_token);
97
+ // Logout
98
+ let response = Client::new()
99
+ .post(account_url_builder(PATH_ACCOUNT_LOGOUT))
100
+ .header("Authorization", format!("Bearer {}", access_token))
101
+ .send()
102
+ .await;
103
+
104
+ match response {
105
+ Ok(response) => {
106
+ debug!("Got response: {:?}", response);
107
+ }
108
+ Err(e) => {
109
+ println!("Failed to get response: {:?}", e);
110
+ }
111
+ }
112
+}
113
+
114
#[tauri::command]
115
pub async fn account_register(username: String, email: String, password: String) {
89
- debug!("Registering with username {} and email {}.", username, email);
116
+ debug!(
117
+ "Registering with username {} and email {}.",
118
+ username, email
119
+ );
120
// Register
121
let body = json!( {
122
"username": username,
@@ -94,7 +124,7 @@ pub async fn account_register(username: String, email: String, password: String)
124
"password": password
125
});
126
let response = Client::new()
97
- .post(register_url_builder())
127
+ .post(account_url_builder(PATH_ACCOUNT_REGISTER))
128
.json(&body)
129
.send()
130
.await;
@@ -117,14 +147,8 @@ pub async fn account_register(username: String, email: String, password: String)
147
}
148
}
149
120
-fn login_url_builder() -> String {
150
+fn account_url_builder(path: &str) -> String {
151
let mut base_url = base_url_builder();
122
- base_url.add_route(PATH_ACCOUNT_LOGIN);
152
+ base_url.add_route(path);
153
base_url.build()
154
}
125
-
126
-fn register_url_builder() -> String {
127
- let mut base_url = base_url_builder();
128
- base_url.add_route(PATH_ACCOUNT_REGISTER);
129
- base_url.build()
130
-}
\ No newline at end of file