export class API { // query resolves into the JSON data produced by the application, or an exception with 'type' and 'error' properties. static async query(method, path, request) { return new Promise((resolve, reject) => { const body = JSON.stringify(request) const headers = {} // Authentication is done with a bearer token. // Here provided to the backend if set. const token = localStorage.getItem('token') if (token) { headers.Authorization = `Bearer ${token}` } fetch(path, { method, headers, body }) .then(response => { // An HTTP communication level error occured. if (!response.ok || response.status != 200) return reject({ type: 'http', error: response, }) return response.json() }) .then(json => { // Application level response are handled here. if (!json.OK) return reject({ type: 'application', error: json.Error, application: json, }) resolve(json) }) .catch(err => // Catch any other errors from fetch. reject({ type: 'http', error: err, })) }) } static hasAuthenticationToken() {//{{{ const token = localStorage.getItem('token') return token !== null && token !== '' }//}}} static authenticate(username, password) {//{{{ return new Promise((resolve, reject) => { const req = { username, password } API.query('POST', '/user/authenticate', req) .then(response => { localStorage.setItem('token', response.Token) localStorage.setItem('user', JSON.stringify(response.User)) resolve(response.User) }) .catch(e => { console.log(e.type, e.error) reject(e.error) }) }) }//}}} static logout() {//{{{ localStorage.removeItem('token') location.href = '/' }//}}} }