Add js web stuff to landing page + documentation

This commit is contained in:
2026-07-14 10:33:12 -04:00
parent fec8ef4a3e
commit 02a6dc6c48
435 changed files with 69567 additions and 1522 deletions

View File

@@ -0,0 +1,106 @@
import { apiFetch } from "./checkBundleVersion.js";
const TOKEN_KEY = "session_key";
const TOKEN_EXPIRY_KEY = "session_key_expiry";
export function getToken() {
return localStorage.getItem(TOKEN_KEY);
}
export function setToken(token, expiresAt) {
localStorage.setItem(TOKEN_KEY, token);
if (expiresAt) {
localStorage.setItem(TOKEN_EXPIRY_KEY, expiresAt.toString());
}
}
export function clearToken() {
localStorage.removeItem(TOKEN_KEY);
localStorage.removeItem(TOKEN_EXPIRY_KEY);
}
export function isTokenExpired() {
const expiry = localStorage.getItem(TOKEN_EXPIRY_KEY);
if (!expiry) return true;
return Date.now() >= parseInt(expiry, 10) * 1000;
}
export function useAuthFetch(options = {}) {
const { onUnauthorized } = options;
return async (url, fetchOptions = {}) => {
const fullUrl = url.startsWith("http") ? url : url;
const token = getToken();
const headers = {
"Content-Type": "application/json",
...fetchOptions.headers,
};
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
const response = await apiFetch(fullUrl, {
...fetchOptions,
headers,
});
if (response.status === 401) {
clearToken();
if (onUnauthorized) {
onUnauthorized();
} else {
const returnUrl = encodeURIComponent(window.location.pathname + window.location.search);
window.location.href = `/login?redirect=${returnUrl}`;
}
throw new AuthError("Unauthorized", 401);
}
if (response.status === 403) {
throw new AuthError("Forbidden: insufficient permissions", 403);
}
return response;
};
}
export async function authFetch(url, options = {}) {
const fullUrl = url.startsWith("http") ? url : url;
const token = getToken();
const headers = {
"Content-Type": "application/json",
...options.headers,
};
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
const response = await fetch(fullUrl, {
...options,
headers,
});
if (response.status === 401) {
clearToken();
const returnUrl = encodeURIComponent(window.location.pathname + window.location.search);
window.location.href = `/login?redirect=${returnUrl}`;
throw new AuthError("Unauthorized", 401);
}
if (response.status === 403) {
throw new AuthError("Forbidden: insufficient permissions", 403);
}
return response;
}
export class AuthError extends Error {
constructor(message, status) {
super(message);
this.name = "AuthError";
this.status = status;
}
}