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) => { 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> => { 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 = async () => { await axios .get(config.get('url') + 'client') .then((resp: AxiosResponse) => { resp.data.filter((client) => client.token === this.tokenCache).forEach((client) => { return axios.delete(config.get('url') + 'client/' + client.id); }); }) .catch(() => Promise.resolve()); 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')); }; }