From 7dde324689f216e4bdde0433edc39ef5fb00bda0 Mon Sep 17 00:00:00 2001 From: Kieran Klukas Date: Mon, 27 Jul 2026 04:10:09 -0400 Subject: [PATCH] bug: fix biome issues --- src/client/admin-clients.ts | 37 ++++++++------- src/client/admin-invites.ts | 28 ++++++++---- src/html/admin-clients.html | 29 +++--------- src/html/admin-invites.html | 6 +-- src/index.ts | 24 ++++------ src/lib/oauth/pages.ts | 90 +++++++++++++++++-------------------- src/routes/api.ts | 12 ++--- src/routes/auth.ts | 2 +- src/routes/oauth/device.ts | 6 ++- src/routes/oauth/profile.ts | 54 ++++++++++------------ src/routes/oauth/token.ts | 5 +++ src/routes/passkeys.ts | 8 ++-- 12 files changed, 144 insertions(+), 157 deletions(-) diff --git a/src/client/admin-clients.ts b/src/client/admin-clients.ts index e947938..5921af3 100644 --- a/src/client/admin-clients.ts +++ b/src/client/admin-clients.ts @@ -1,3 +1,18 @@ +declare global { + interface Window { + toggleClient: (clientId: string) => Promise; + setUserRole: ( + clientId: string, + username: string, + role: string, + ) => Promise; + editClient: (clientId: string) => Promise; + deleteClient: (clientId: string, event?: Event) => Promise; + removeRedirectUri: (btn: HTMLButtonElement) => void; + regenerateSecret: (clientId: string, event?: Event) => Promise; + revokeUserPermission: (clientId: string, username: string) => Promise; + } +} const token = localStorage.getItem("indiko_session"); import "./ds"; @@ -80,14 +95,6 @@ interface ClientUser { lastUsed: number; } -interface AppPermission { - username: string; - name: string; - scopes: string[]; - grantedAt: number; - lastUsed: number; -} - async function loadClients() { try { const response = await fetch("/api/admin/clients", { @@ -167,7 +174,7 @@ function displayClients(clients: Client[]) { .join(""); } -(window as any).toggleClient = async (clientId: string) => { +window.toggleClient = async (clientId: string) => { const card = document.querySelector( `[data-client-id="${clientId}"]`, ) as HTMLElement; @@ -295,7 +302,7 @@ function displayClients(clients: Client[]) { } }; -(window as any).setUserRole = async ( +window.setUserRole = async ( clientId: string, username: string, role: string, @@ -324,7 +331,7 @@ function displayClients(clients: Client[]) { } }; -(window as any).editClient = async (clientId: string) => { +window.editClient = async (clientId: string) => { try { const response = await fetch( `/api/admin/clients/${encodeURIComponent(clientId)}`, @@ -374,7 +381,7 @@ function displayClients(clients: Client[]) { } }; -(window as any).deleteClient = async (clientId: string, event?: Event) => { +window.deleteClient = async (clientId: string, event?: Event) => { const btn = event?.target as HTMLButtonElement | undefined; // Double-click confirmation pattern @@ -455,7 +462,7 @@ addRedirectUriBtn.addEventListener("click", () => { redirectUrisList.appendChild(newItem); }); -(window as any).removeRedirectUri = (btn: HTMLButtonElement) => { +window.removeRedirectUri = (btn: HTMLButtonElement) => { const items = redirectUrisList.querySelectorAll(".redirect-uri-item"); if (items.length > 1) { btn.parentElement?.remove(); @@ -576,7 +583,7 @@ clientForm.addEventListener("submit", async (e) => { } }); -(window as any).regenerateSecret = async (clientId: string, event?: Event) => { +window.regenerateSecret = async (clientId: string, event?: Event) => { const btn = event?.target as HTMLButtonElement | undefined; // Double-click confirmation pattern (same as delete) @@ -647,7 +654,7 @@ clientForm.addEventListener("submit", async (e) => { } }; -(window as any).revokeUserPermission = async ( +window.revokeUserPermission = async ( clientId: string, username: string, event?: Event, diff --git a/src/client/admin-invites.ts b/src/client/admin-invites.ts index 298d753..01077ea 100644 --- a/src/client/admin-invites.ts +++ b/src/client/admin-invites.ts @@ -1,5 +1,15 @@ import "./ds"; +declare global { + interface Window { + submitCreateInvite: () => Promise; + closeCreateInviteModal: () => void; + editInvite: (inviteId: number) => Promise; + submitEditInvite: () => Promise; + closeEditInviteModal: () => void; + deleteInvite: (inviteId: number, event?: Event) => Promise; + } +} const token = localStorage.getItem("indiko_session"); const invitesList = document.getElementById("invitesList") as HTMLElement; const createInviteBtn = document.getElementById( @@ -244,8 +254,8 @@ function closeCreateInviteModal() { } // Expose functions to global scope for HTML onclick handlers -(window as any).submitCreateInvite = submitCreateInvite; -(window as any).closeCreateInviteModal = closeCreateInviteModal; +window.submitCreateInvite = submitCreateInvite; +window.closeCreateInviteModal = closeCreateInviteModal; async function loadInvites() { try { @@ -386,7 +396,7 @@ createInviteBtn.addEventListener("click", createInvite); document.addEventListener("keydown", (e) => { if (e.key === "Escape") { closeCreateInviteModal(); - closeEditInviteModal(); + window.closeEditInviteModal(); } }); @@ -399,14 +409,14 @@ document.getElementById("createInviteModal")?.addEventListener("click", (e) => { document.getElementById("editInviteModal")?.addEventListener("click", (e) => { if (e.target === e.currentTarget) { - closeEditInviteModal(); + window.closeEditInviteModal(); } }); let currentEditInviteId: number | null = null; // Make editInvite globally available for onclick handler -(window as any).editInvite = async (inviteId: number) => { +window.editInvite = async (inviteId: number) => { try { const response = await fetch("/api/invites", { headers: { @@ -466,7 +476,7 @@ let currentEditInviteId: number | null = null; } }; -(window as any).submitEditInvite = async () => { +window.submitEditInvite = async () => { if (currentEditInviteId === null) return; const maxUsesInput = document.getElementById( @@ -510,7 +520,7 @@ let currentEditInviteId: number | null = null; } await loadInvites(); - closeEditInviteModal(); + window.closeEditInviteModal(); } catch (error) { console.error("Failed to update invite:", error); alert("Failed to update invite"); @@ -520,7 +530,7 @@ let currentEditInviteId: number | null = null; } }; -(window as any).closeEditInviteModal = () => { +window.closeEditInviteModal = () => { const modal = document.getElementById("editInviteModal"); if (modal) { modal.style.display = "none"; @@ -535,7 +545,7 @@ let currentEditInviteId: number | null = null; } }; -(window as any).deleteInvite = async (inviteId: number, event?: Event) => { +window.deleteInvite = async (inviteId: number, event?: Event) => { const btn = event?.target as HTMLButtonElement | undefined; // Double-click confirmation pattern diff --git a/src/html/admin-clients.html b/src/html/admin-clients.html index b5aa1b1..8500c6c 100644 --- a/src/html/admin-clients.html +++ b/src/html/admin-clients.html @@ -126,23 +126,6 @@ letter-spacing: 0.05rem; } - footer a { - color: var(--berry-crush); - text-decoration: none; - transition: color 0.2s; - } - - footer a:hover { - color: var(--rosewood); - text-decoration: underline; - } - - .back-link { - margin-top: 0.5rem; - font-size: 0.875rem; - color: var(--old-rose); - } - .actions { display: flex; justify-content: space-between; @@ -643,8 +626,8 @@ -
- +
+ Redirect URIs
@@ -652,9 +635,9 @@
-
+
- +

Define which roles can be assigned to users for this app. Leave empty to allow free-text roles.

@@ -682,14 +665,14 @@ ⚠️ Save these credentials now. You won't be able to see the secret again!

- + Client ID
- + Client Secret
diff --git a/src/html/admin-invites.html b/src/html/admin-invites.html index fd64933..b97ff87 100644 --- a/src/html/admin-invites.html +++ b/src/html/admin-invites.html @@ -324,13 +324,13 @@
Public message that will be shown to users when they use this invite
-
- +
+ app role assignments (optional)
Users who register with this invite will automatically be assigned these roles
Loading apps...
-
+