aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/app/data/user.ts
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/ClientApp/src/app/data/user.ts')
-rw-r--r--Timeline/ClientApp/src/app/data/user.ts224
1 files changed, 0 insertions, 224 deletions
diff --git a/Timeline/ClientApp/src/app/data/user.ts b/Timeline/ClientApp/src/app/data/user.ts
deleted file mode 100644
index 8f787478..00000000
--- a/Timeline/ClientApp/src/app/data/user.ts
+++ /dev/null
@@ -1,224 +0,0 @@
-import axios, { AxiosError } from 'axios';
-import { useState, useEffect } from 'react';
-import { BehaviorSubject, Observable } from 'rxjs';
-
-import { apiBaseUrl } from '../config';
-import { extractErrorCode } from './common';
-import { pushAlert } from '../common/alert-service';
-import { i18nPromise } from '../i18n';
-import { UiLogicError } from '../common';
-
-export interface UserAuthInfo {
- username: string;
- administrator: boolean;
-}
-
-export interface User {
- username: string;
- administrator: boolean;
- nickname: string;
- _links: {
- avatar: string;
- timeline: string;
- };
-}
-
-export interface UserWithToken extends User {
- token: string;
-}
-
-interface CreateTokenRequest {
- username: string;
- password: string;
-}
-
-interface CreateTokenResponse {
- token: string;
- user: User;
-}
-
-interface VerifyTokenRequest {
- token: string;
-}
-
-interface VerifyTokenResponse {
- user: User;
-}
-
-export type LoginCredentials = CreateTokenRequest;
-
-const userSubject = new BehaviorSubject<UserWithToken | null | undefined>(
- undefined
-);
-
-export const user$: Observable<UserWithToken | null | undefined> = userSubject;
-
-export function getCurrentUser(): UserWithToken | null | undefined {
- return userSubject.value;
-}
-
-const kCreateTokenUrl = '/token/create';
-const kVerifyTokenUrl = '/token/verify';
-const createTokenUrl = apiBaseUrl + kCreateTokenUrl;
-const verifyTokenUrl = apiBaseUrl + kVerifyTokenUrl;
-
-function verifyToken(token: string): Promise<User> {
- return axios
- .post<VerifyTokenResponse>(verifyTokenUrl, {
- token: token,
- } as VerifyTokenRequest)
- .then((res) => res.data.user);
-}
-
-const TOKEN_STORAGE_KEY = 'token';
-
-export function checkUserLoginState(): Promise<UserWithToken | null> {
- if (getCurrentUser() !== undefined)
- throw new UiLogicError("Already checked user. Can't check twice.");
-
- const savedToken = window.localStorage.getItem(TOKEN_STORAGE_KEY);
- if (savedToken) {
- return verifyToken(savedToken)
- .then(
- (u) => {
- const user: UserWithToken = {
- ...u,
- token: savedToken,
- };
- void i18nPromise.then((t) => {
- pushAlert({
- type: 'success',
- message: t('user.welcomeBack'),
- });
- });
- return user;
- },
- (e: AxiosError) => {
- if (e.response != null) {
- window.localStorage.removeItem(TOKEN_STORAGE_KEY);
- void i18nPromise.then((t) => {
- pushAlert({
- type: 'danger',
- message: t('user.verifyTokenFailed'),
- });
- });
- } else {
- void i18nPromise.then((t) => {
- pushAlert({
- type: 'danger',
- message: t('user.verifyTokenFailedNetwork'),
- });
- });
- }
-
- return null;
- }
- )
- .then((u) => {
- userSubject.next(u);
- return u;
- });
- }
- userSubject.next(null);
- return Promise.resolve(null);
-}
-
-export class BadCredentialError {
- constructor(public innerError: Error) {}
-
- message = 'login.badCredential';
-}
-
-export function userLogin(
- credentials: LoginCredentials,
- rememberMe: boolean
-): Promise<UserWithToken> {
- if (getCurrentUser()) {
- throw new UiLogicError('Already login.');
- }
- return axios
- .post<CreateTokenResponse>(createTokenUrl, { ...credentials, expire: 30 })
- .catch((e: AxiosError) => {
- if (extractErrorCode(e) === 11010101) {
- throw new BadCredentialError(e);
- }
- throw e;
- })
- .then((res) => {
- const body = res.data;
- const token = body.token;
- if (rememberMe) {
- window.localStorage.setItem(TOKEN_STORAGE_KEY, token);
- }
- const user = {
- ...body.user,
- token,
- };
- userSubject.next(user);
- return user;
- });
-}
-
-export function userLogout(): void {
- if (getCurrentUser() === undefined) {
- throw new UiLogicError('Please check user first.');
- }
- if (getCurrentUser() === null) {
- throw new UiLogicError('No login.');
- }
- window.localStorage.removeItem(TOKEN_STORAGE_KEY);
- userSubject.next(null);
-}
-
-export function useOptionalUser(): UserWithToken | null | undefined {
- const [user, setUser] = useState<UserWithToken | null | undefined>(
- userSubject.value
- );
- useEffect(() => {
- const sub = user$.subscribe((u) => setUser(u));
- return () => {
- sub.unsubscribe();
- };
- });
- return user;
-}
-
-export function useUser(): UserWithToken | null {
- const [user, setUser] = useState<UserWithToken | null>(() => {
- const initUser = userSubject.value;
- if (initUser === undefined) {
- throw new UiLogicError(
- "This is a logic error in user module. Current user can't be undefined in useUser."
- );
- }
- return initUser;
- });
- useEffect(() => {
- const sub = 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);
- });
- return () => {
- sub.unsubscribe();
- };
- });
- return user;
-}
-
-export function useUserLoggedIn(): UserWithToken {
- const user = useUser();
- if (user == null) {
- throw new UiLogicError('You assert user has logged in but actually not.');
- }
- return user;
-}
-
-export function fetchUser(username: string): Promise<User> {
- return axios
- .get<User>(`${apiBaseUrl}/users/${username}`)
- .then((res) => res.data);
-}