Notes2/static/js/api.mjs
2026-06-18 09:21:23 +02:00

56 lines
1.7 KiB
JavaScript

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) {
try {
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}`
}
const res = await fetch(path, { method, headers, body })
// An HTTP communication level error occured.
if (!res.ok || res.status != 200)
throw new Error('HTTP error', { cause: { type: 'http', error: res, }})
// Application level response are handled here.
const json = await res.json()
if (!json.OK)
throw new Error(json.Error, { cause: { type: 'application', application: json, }})
return json
} catch (err) {
// Catch any other errors from fetch.
throw new Error(err.message, { cause: { 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 = '/'
}//}}}
}