garm/webapp/assets/_app/immutable/chunks/duD3WMbl.js
Gabriel Adrian Samfira eec158b32c Add SPA UI for GARM
This change adds a single page application front-end to GARM. It uses
a generated REST client, built from the swagger definitions, the websocket
interface for live updates of entities and eager loading of everything
except runners, as users may have many runners and we don't want to load
hundreds of runners in memory.

Proper pagination should be implemented in the API, in future commits,
to avoid loading lots of elements for no reason.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 09:09:13 +00:00

1 line
2.7 KiB
JavaScript

import{I as w}from"./D8EpLgQ1.js";import{g as r}from"./CiE1LlKV.js";const m=!0,z=m,I=()=>window.location.port==="5173",b={isAuthenticated:!1,user:null,loading:!0,needsInitialization:!1},n=w(b);function f(t,a,e=7){const i=new Date;i.setTime(i.getTime()+e*24*60*60*1e3),document.cookie=`${t}=${a};expires=${i.toUTCString()};path=/;SameSite=Lax`}function d(t){const a=t+"=",e=document.cookie.split(";");for(let i=0;i<e.length;i++){let o=e[i];for(;o.charAt(0)===" ";)o=o.substring(1,o.length);if(o.indexOf(a)===0)return o.substring(a.length,o.length)}return null}function g(t){document.cookie=`${t}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/`}const c={async login(t,a){try{n.update(i=>({...i,loading:!0}));const e=await r.login({username:t,password:a});z&&(f("garm_token",e.token),f("garm_user",t)),r.setToken(e.token),n.set({isAuthenticated:!0,user:t,loading:!1,needsInitialization:!1})}catch(e){throw n.update(i=>({...i,loading:!1})),e}},logout(){g("garm_token"),g("garm_user"),n.set({isAuthenticated:!1,user:null,loading:!1,needsInitialization:!1})},async init(){try{n.update(e=>({...e,loading:!0})),await c.checkInitializationStatus();const t=d("garm_token"),a=d("garm_user");if(t&&a&&(r.setToken(t),await c.checkAuth())){n.set({isAuthenticated:!0,user:a,loading:!1,needsInitialization:!1});return}n.update(e=>({...e,loading:!1,needsInitialization:!1}))}catch{n.update(a=>({...a,loading:!1}))}},async checkInitializationStatus(){try{const t={Accept:"application/json"},a=d("garm_token"),e=I();e&&a&&(t.Authorization=`Bearer ${a}`);const i=await fetch("/api/v1/login",{method:"GET",headers:t,credentials:e?"omit":"include"});if(!i.ok){if(i.status===409&&(await i.json()).error==="init_required")throw n.update(s=>({...s,needsInitialization:!0,loading:!1})),new Error("Initialization required");return}return}catch(t){if(t instanceof Error&&t.message==="Initialization required")throw t;return}},async checkAuth(){try{return await c.checkInitializationStatus(),await r.getControllerInfo(),!0}catch(t){return t instanceof Error&&t.message==="Initialization required"?!1:t?.response?.status===409&&t?.response?.data?.error==="init_required"?(n.update(a=>({...a,needsInitialization:!0,loading:!1})),!1):(c.logout(),!1)}},async initialize(t,a,e,i,o){try{n.update(u=>({...u,loading:!0}));const s=await r.firstRun({username:t,email:a,password:e,full_name:i||t});await c.login(t,e);const l=window.location.origin,h=o?.metadataUrl||`${l}/api/v1/metadata`,p=o?.callbackUrl||`${l}/api/v1/callbacks`,k=o?.webhookUrl||`${l}/webhooks`;await r.updateController({metadata_url:h,callback_url:p,webhook_url:k}),n.update(u=>({...u,needsInitialization:!1}))}catch(s){throw n.update(l=>({...l,loading:!1})),s}}};export{n as a,c as b};