sharded-gotify/ui/src/CurrentUser.ts

104 lines
3.2 KiB
TypeScript

import axios, {AxiosResponse} from 'axios';
import * as config from './config';
import {detect} from 'detect-browser';
import {SnackReporter} from './snack/SnackManager';
import {observable} from 'mobx';
const tokenKey = 'gotify-login-key';
export class CurrentUser {
private tokenCache: string | null = null;
@observable
public loggedIn = false;
@observable
public authenticating = false;
@observable
public user: IUser = {name: 'unknown', admin: false, id: -1};
public constructor(private readonly snack: SnackReporter) {}
public token = (): string => {
if (this.tokenCache !== null) {
return this.tokenCache;
}
const localStorageToken = window.localStorage.getItem(tokenKey);
if (localStorageToken) {
this.tokenCache = localStorageToken;
return localStorageToken;
}
return '';
};
private setToken = (token: string) => {
this.tokenCache = token;
window.localStorage.setItem(tokenKey, token);
};
public login = async (username: string, password: string) => {
this.loggedIn = false;
this.authenticating = true;
const browser = detect();
const name = (browser && browser.name + ' ' + browser.version) || 'unknown browser';
axios
.create()
.request({
url: config.get('url') + 'client',
method: 'POST',
data: {name},
auth: {username, password},
})
.then((resp: AxiosResponse<IClient>) => {
this.snack(`A client named '${name}' was created for your session.`);
this.setToken(resp.data.token);
this.tryAuthenticate()
.then(() => {
this.authenticating = false;
this.loggedIn = true;
})
.catch(() => {
this.authenticating = false;
console.log(
'create client succeeded, but authenticated with given token failed'
);
});
})
.catch(() => {
this.authenticating = false;
return this.snack('Login failed');
});
};
public tryAuthenticate = async (): Promise<AxiosResponse<IUser>> => {
if (this.token() === '') {
return Promise.reject();
}
return axios
.create()
.get(config.get('url') + 'current/user', {headers: {'X-Gotify-Key': this.token()}})
.then((passThrough) => {
this.user = passThrough.data;
this.loggedIn = true;
return passThrough;
})
.catch((error) => {
this.logout();
return Promise.reject(error);
});
};
public logout = () => {
window.localStorage.removeItem(tokenKey);
this.tokenCache = null;
this.loggedIn = false;
};
public changePassword = (pass: string) => {
axios
.post(config.get('url') + 'current/user/password', {pass})
.then(() => this.snack('Password changed'));
};
}