import { observable } from "mobx"; import HttpApi, { ApiError } from "@app/state/HttpApi"; import { Token } from "@app/state/Token"; import { TokenGrantPasswordRequest, TokenGrantRefreshRequest, TokenGrantResponse } from "@common/httpApi"; import logger from "@common/logger"; const log = logger.child({ source: "TokenStore"}); const LOCAL_STORAGE_KEY = "TokenStore"; export class TokenStore { @observable accessToken: Token = new Token(); @observable refreshToken: Token = new Token(); private api: HttpApi; constructor(api: HttpApi) { this.api = api; } clear() { this.accessToken.token = null; this.refreshToken.token = null; this.saveLocalStorage(); } saveLocalStorage() { window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.toJSON())); } loadLocalStorage() { const data = window.localStorage.getItem(LOCAL_STORAGE_KEY); if (data) { const data2 = JSON.parse(data); this.updateFromJson(data2); } } async grantPassword(username: string, password: string) { const request: TokenGrantPasswordRequest = { grant_type: "password", username, password, }; const response: TokenGrantResponse = await this.api.makeRequest("/token/grant", { method: "POST", }, request); this.accessToken.token = response.access_token; this.refreshToken.token = response.refresh_token; this.saveLocalStorage(); log.debug({ aud: this.accessToken.claims!.aud }, "got password grant tokens"); } async grantRefresh() { if (!this.refreshToken.isValid) { throw new ApiError("can not grant refresh with invalid refresh_token"); } const request: TokenGrantRefreshRequest = { grant_type: "refresh", refresh_token: this.refreshToken.token!, }; const response: TokenGrantResponse = await this.api.makeRequest("/token/grant", { method: "POST", }, request); this.accessToken.token = response.access_token; this.refreshToken.token = response.refresh_token; this.saveLocalStorage(); log.debug({ aud: this.accessToken.claims!.aud }, "got refresh grant tokens"); } toJSON() { return { accessToken: this.accessToken.toJSON(), refreshToken: this.refreshToken.toJSON() }; } updateFromJson(json: any) { this.accessToken.token = json.accessToken; this.refreshToken.token = json.refreshToken; } }