aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/services
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-07-05 22:47:38 +0800
committercrupest <crupest@outlook.com>2021-07-05 22:47:38 +0800
commit6612510d2baa31f6bb946b412351b7992b2ffbe1 (patch)
tree943582be3f5940161d0666fd5a2e4a504466bf9a /FrontEnd/src/services
parent5c3f254c6a7ff14981616968b020ed38ca3edf00 (diff)
downloadtimeline-6612510d2baa31f6bb946b412351b7992b2ffbe1.tar.gz
timeline-6612510d2baa31f6bb946b412351b7992b2ffbe1.tar.bz2
timeline-6612510d2baa31f6bb946b412351b7992b2ffbe1.zip
feat: Fix #623, fix #621.
Diffstat (limited to 'FrontEnd/src/services')
-rw-r--r--FrontEnd/src/services/user.ts123
1 files changed, 43 insertions, 80 deletions
diff --git a/FrontEnd/src/services/user.ts b/FrontEnd/src/services/user.ts
index 9a8e5687..2f42dd59 100644
--- a/FrontEnd/src/services/user.ts
+++ b/FrontEnd/src/services/user.ts
@@ -3,7 +3,7 @@ import { BehaviorSubject, Observable } from "rxjs";
import { UiLogicError } from "@/common";
-import { HttpNetworkError, setHttpToken } from "@/http/common";
+import { HttpNetworkError, setHttpToken, axios } from "@/http/common";
import {
getHttpTokenClient,
HttpCreateTokenBadCredentialError,
@@ -11,6 +11,7 @@ import {
import { getHttpUserClient, HttpUser, UserPermission } from "@/http/user";
import { pushAlert } from "./alert";
+import { AxiosError } from "axios";
interface IAuthUser extends HttpUser {
token: string;
@@ -58,24 +59,16 @@ export class UserService {
this.userSubject.subscribe((u) => {
setHttpToken(u?.token ?? null);
});
- }
-
- private userSubject = new BehaviorSubject<AuthUser | null | undefined>(
- undefined
- );
-
- get user$(): Observable<AuthUser | null | undefined> {
- return this.userSubject;
- }
-
- get currentUser(): AuthUser | null | undefined {
- return this.userSubject.value;
- }
- async checkLoginState(): Promise<AuthUser | null> {
- if (this.currentUser !== undefined) {
- console.warn("Already checked user. Can't check twice.");
- }
+ axios.interceptors.response.use(undefined, (e: AxiosError) => {
+ if (e.isAxiosError && e.response && e.response.status === 401) {
+ this.userSubject.next(null);
+ pushAlert({
+ type: "danger",
+ message: "user.tokenInvalid",
+ });
+ }
+ });
const savedUserString = localStorage.getItem(USER_STORAGE_KEY);
@@ -89,41 +82,39 @@ export class UserService {
? null
: new AuthUser(savedAuthUserData, savedAuthUserData.token);
- if (savedUser == null) {
- this.userSubject.next(null);
- return null;
+ if (savedUser != null) {
+ this.userSubject.next(savedUser);
+
+ getHttpTokenClient()
+ .verify({ token: savedUser.token })
+ .then(
+ (res) => {
+ const user = new AuthUser(res.user, savedUser.token);
+ localStorage.setItem(USER_STORAGE_KEY, JSON.stringify(user));
+ this.userSubject.next(user);
+ },
+ (error) => {
+ if (!(error instanceof HttpNetworkError)) {
+ localStorage.removeItem(USER_STORAGE_KEY);
+ this.userSubject.next(null);
+ pushAlert({
+ type: "danger",
+ message: "user.tokenInvalid",
+ });
+ }
+ }
+ );
}
+ }
- this.userSubject.next(savedUser);
+ private userSubject = new BehaviorSubject<AuthUser | null>(null);
- const savedToken = savedUser.token;
- try {
- const res = await getHttpTokenClient().verify({ token: savedToken });
- const user = new AuthUser(res.user, savedToken);
- localStorage.setItem(USER_STORAGE_KEY, JSON.stringify(user));
- this.userSubject.next(user);
- pushAlert({
- type: "success",
- message: "user.welcomeBack",
- });
- return user;
- } catch (error) {
- if (error instanceof HttpNetworkError) {
- pushAlert({
- type: "danger",
- message: "user.verifyTokenFailedNetwork",
- });
- return savedUser;
- } else {
- localStorage.removeItem(USER_STORAGE_KEY);
- this.userSubject.next(null);
- pushAlert({
- type: "danger",
- message: "user.verifyTokenFailed",
- });
- return null;
- }
- }
+ get user$(): Observable<AuthUser | null> {
+ return this.userSubject;
+ }
+
+ get currentUser(): AuthUser | null {
+ return this.userSubject.value;
}
async login(
@@ -180,38 +171,10 @@ export class UserService {
export const userService = new UserService();
-export function useRawUser(): AuthUser | null | undefined {
- const [user, setUser] = useState<AuthUser | null | undefined>(
- userService.currentUser
- );
- useEffect(() => {
- const subscription = userService.user$.subscribe((u) => setUser(u));
- return () => {
- subscription.unsubscribe();
- };
- });
- return user;
-}
-
export function useUser(): AuthUser | null {
- const [user, setUser] = useState<AuthUser | null>(() => {
- const initUser = userService.currentUser;
- if (initUser === undefined) {
- throw new UiLogicError(
- "This is a logic error in user module. Current user can't be undefined in useUser."
- );
- }
- return initUser;
- });
+ const [user, setUser] = useState<AuthUser | null>(userService.currentUser);
useEffect(() => {
- const sub = userService.user$.subscribe((u) => {
- if (u === undefined) {
- throw new UiLogicError(
- "This is a logic error in user module. User emitted can't be undefined later."
- );
- }
- setUser(u);
- });
+ const sub = userService.user$.subscribe((u) => setUser(u));
return () => {
sub.unsubscribe();
};