diff options
author | crupest <crupest@outlook.com> | 2020-08-07 00:01:45 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-08-07 00:01:45 +0800 |
commit | 978c9071613177aea8b3d773827c87fa329522cd (patch) | |
tree | 0a1e792c183435ddae9ce76172170e38f567863f | |
parent | 1087499e6cbbee1a506fcd7c762703b90526a7ab (diff) | |
download | timeline-978c9071613177aea8b3d773827c87fa329522cd.tar.gz timeline-978c9071613177aea8b3d773827c87fa329522cd.tar.bz2 timeline-978c9071613177aea8b3d773827c87fa329522cd.zip |
Use cache login user if offline.
-rw-r--r-- | Timeline/ClientApp/src/app/data/user.ts | 131 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/user/Login.tsx | 4 |
2 files changed, 65 insertions, 70 deletions
diff --git a/Timeline/ClientApp/src/app/data/user.ts b/Timeline/ClientApp/src/app/data/user.ts index 14f4e943..defcb4e4 100644 --- a/Timeline/ClientApp/src/app/data/user.ts +++ b/Timeline/ClientApp/src/app/data/user.ts @@ -1,6 +1,5 @@ import React, { useState, useEffect } from 'react';
-import { BehaviorSubject, Observable, of, from } from 'rxjs';
-import { map } from 'rxjs/operators';
+import { BehaviorSubject, Observable, from } from 'rxjs';
import { UiLogicError } from '../common';
import { convertError } from '../utilities/rxjs';
@@ -41,7 +40,7 @@ export class BadCredentialError { message = 'login.badCredential';
}
-const TOKEN_STORAGE_KEY = 'token';
+const USER_STORAGE_KEY = 'currentuser';
export class UserService {
private userSubject = new BehaviorSubject<UserWithToken | null | undefined>(
@@ -56,96 +55,92 @@ export class UserService { return this.userSubject.value;
}
- checkLoginState(): Observable<UserWithToken | null> {
+ async checkLoginState(): Promise<UserWithToken | null> {
if (this.currentUser !== undefined) {
console.warn("Already checked user. Can't check twice.");
}
- const savedToken = window.localStorage.getItem(TOKEN_STORAGE_KEY);
- if (savedToken) {
- const u$ = from(getHttpTokenClient().verify({ token: savedToken })).pipe(
- map(
- (res) =>
- ({
- ...res.user,
- token: savedToken,
- } as UserWithToken)
- )
- );
- u$.subscribe(
- (user) => {
- if (user != null) {
- pushAlert({
- type: 'success',
- message: {
- type: 'i18n',
- key: 'user.welcomeBack',
- },
- });
- }
- this.userSubject.next(user);
+ const savedUser = await dataStorage.getItem<UserWithToken | null>(
+ USER_STORAGE_KEY
+ );
+
+ if (savedUser == null) {
+ this.userSubject.next(null);
+ return null;
+ }
+
+ this.userSubject.next(savedUser);
+
+ const savedToken = savedUser.token;
+ try {
+ const res = await getHttpTokenClient().verify({ token: savedToken });
+ const user: UserWithToken = { ...res.user, token: savedToken };
+ await dataStorage.setItem<UserWithToken>(USER_STORAGE_KEY, user);
+ this.userSubject.next(user);
+ pushAlert({
+ type: 'success',
+ message: {
+ type: 'i18n',
+ key: 'user.welcomeBack',
},
- (error) => {
- if (error instanceof HttpNetworkError) {
- pushAlert({
- type: 'danger',
- message: { type: 'i18n', key: 'user.verifyTokenFailedNetwork' },
- });
- } else {
- window.localStorage.removeItem(TOKEN_STORAGE_KEY);
- pushAlert({
- type: 'danger',
- message: { type: 'i18n', key: 'user.verifyTokenFailed' },
- });
- }
- this.userSubject.next(null);
- }
- );
- return u$;
+ });
+ return user;
+ } catch (error) {
+ if (error instanceof HttpNetworkError) {
+ pushAlert({
+ type: 'danger',
+ message: { type: 'i18n', key: 'user.verifyTokenFailedNetwork' },
+ });
+ return savedUser;
+ } else {
+ await dataStorage.removeItem(USER_STORAGE_KEY);
+ this.userSubject.next(null);
+ pushAlert({
+ type: 'danger',
+ message: { type: 'i18n', key: 'user.verifyTokenFailed' },
+ });
+ return null;
+ }
}
- this.userSubject.next(null);
- return of(null);
}
- login(
+ async login(
credentials: LoginCredentials,
rememberMe: boolean
- ): Observable<UserWithToken> {
+ ): Promise<void> {
if (this.currentUser) {
throw new UiLogicError('Already login.');
}
- const u$ = from(
- getHttpTokenClient().create({
+ try {
+ const res = await getHttpTokenClient().create({
...credentials,
expire: 30,
- })
- ).pipe(
- map(
- (res) =>
- ({
- ...res.user,
- token: res.token,
- } as UserWithToken)
- ),
- convertError(HttpCreateTokenBadCredentialError, BadCredentialError)
- );
- u$.subscribe((user) => {
+ });
+ const user: UserWithToken = {
+ ...res.user,
+ token: res.token,
+ };
if (rememberMe) {
- window.localStorage.setItem(TOKEN_STORAGE_KEY, user.token);
+ await dataStorage.setItem<UserWithToken>(USER_STORAGE_KEY, user);
}
this.userSubject.next(user);
- });
- return u$;
+ } catch (e) {
+ if (e instanceof HttpCreateTokenBadCredentialError) {
+ throw new BadCredentialError();
+ } else {
+ throw e;
+ }
+ }
}
- logout(): void {
+ async logout(): Promise<void> {
if (this.currentUser === undefined) {
throw new UiLogicError('Please check user first.');
}
if (this.currentUser === null) {
throw new UiLogicError('No login.');
}
- window.localStorage.removeItem(TOKEN_STORAGE_KEY);
+ await dataStorage.removeItem(USER_STORAGE_KEY);
this.userSubject.next(null);
}
@@ -166,7 +161,7 @@ export class UserService { )
);
$.subscribe(() => {
- this.logout();
+ void this.logout();
});
return $;
}
diff --git a/Timeline/ClientApp/src/app/user/Login.tsx b/Timeline/ClientApp/src/app/user/Login.tsx index a615d8ed..2f2a3188 100644 --- a/Timeline/ClientApp/src/app/user/Login.tsx +++ b/Timeline/ClientApp/src/app/user/Login.tsx @@ -62,8 +62,8 @@ const Login: React.FC = (_) => { },
rememberMe
)
- .subscribe(
- (_) => {
+ .then(
+ () => {
if (history.length === 0) {
history.push('/');
} else {
|