Loading portal/static/js/account.mjs 0 → 100644 +61 −0 Changes for portal/static/js/account.mjs: 61 added lines, 0 removed lines. Original line number Diff line number Diff line import { Base64 } from "/static/lib/base64-3.7.5/base64.mjs" export function getKey() { return JSON.parse(localStorage.getItem("key")) } export function isExpired(key) { const now = new Date() return now > new Date(key.expiresAt) } export function isLoggedIn() { return getKey() !== null && !isExpired(getKey()) } export async function login(username, password) { // We use a library to Base64 encode username and password to conform to RFC7671 // (https://datatracker.ietf.org/doc/html/rfc7617#section-2.1) because the built-in // JavaScript function btoa cannot deal with Unicode characters properly. const encodedUsernamePassword = Base64.encode(`${username}:${password}`) const key = await m.request({ method: "POST", url: "/api/v0/keys", headers: { Authorization: `Basic ${encodedUsernamePassword}`, }, }) localStorage.setItem("key", JSON.stringify(key)) } export async function logout() { const key = getKey() // Remove the key from local storage. This way, the logout button will always reset the local session in the browser, // even if something weird happens immediately afterwards. localStorage.removeItem("key") if (!key) { throw new Error(`Tried to logout, but the key was falsy: key = ${key}`) } try { await m.request({ method: "DELETE", url: `/api/v0/keys/${key.uuid}`, headers: { Authorization: `Bearer ${key.secret}`, }, }) } catch (e) { if (e.code === 401 && isExpired(key)) { // Expired keys are deleted automatically and are not authorized to do anything anymore, // so this error is expected. We do nothing in this case, but could show an info message. } else { // This should not happen, rethrow throw e } } } Loading
portal/static/js/account.mjs 0 → 100644 +61 −0 Changes for portal/static/js/account.mjs: 61 added lines, 0 removed lines. Original line number Diff line number Diff line import { Base64 } from "/static/lib/base64-3.7.5/base64.mjs" export function getKey() { return JSON.parse(localStorage.getItem("key")) } export function isExpired(key) { const now = new Date() return now > new Date(key.expiresAt) } export function isLoggedIn() { return getKey() !== null && !isExpired(getKey()) } export async function login(username, password) { // We use a library to Base64 encode username and password to conform to RFC7671 // (https://datatracker.ietf.org/doc/html/rfc7617#section-2.1) because the built-in // JavaScript function btoa cannot deal with Unicode characters properly. const encodedUsernamePassword = Base64.encode(`${username}:${password}`) const key = await m.request({ method: "POST", url: "/api/v0/keys", headers: { Authorization: `Basic ${encodedUsernamePassword}`, }, }) localStorage.setItem("key", JSON.stringify(key)) } export async function logout() { const key = getKey() // Remove the key from local storage. This way, the logout button will always reset the local session in the browser, // even if something weird happens immediately afterwards. localStorage.removeItem("key") if (!key) { throw new Error(`Tried to logout, but the key was falsy: key = ${key}`) } try { await m.request({ method: "DELETE", url: `/api/v0/keys/${key.uuid}`, headers: { Authorization: `Bearer ${key.secret}`, }, }) } catch (e) { if (e.code === 401 && isExpired(key)) { // Expired keys are deleted automatically and are not authorized to do anything anymore, // so this error is expected. We do nothing in this case, but could show an info message. } else { // This should not happen, rethrow throw e } } }