From 47bf91e7ff602eae5c7d79252ef61b0e89af65f7 Mon Sep 17 00:00:00 2001 From: MrMelon54 Date: Wed, 13 Dec 2023 12:54:45 +0000 Subject: [PATCH] Add apiRequest function to auto refresh outdated access token --- src/utils/api-request.ts | 35 +++++++++++++++++ src/views/CertificatesView.svelte | 28 ++++++-------- src/views/GeneralView.svelte | 24 ++++++++++++ src/views/SitesView.svelte | 55 +++++++++------------------ src/views/TargetManagementView.svelte | 43 +++++++++------------ test-server/go.mod | 2 +- test-server/go.sum | 2 + test-server/main.go | 45 +++++++++++++++++++++- 8 files changed, 155 insertions(+), 79 deletions(-) create mode 100644 src/utils/api-request.ts diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts new file mode 100644 index 0000000..665c5b9 --- /dev/null +++ b/src/utils/api-request.ts @@ -0,0 +1,35 @@ +import {get} from "svelte/store"; +import {getBearer, loginStore} from "../stores/login"; + +const TOKEN_REFRESH_API = import.meta.env.VITE_SSO_ORIGIN + "/refresh"; + +export async function apiRequest(url: string, init?: RequestInit): Promise { + // setup authorization header + if (init == undefined) init = {}; + init.headers = {...init.headers, Authorization: getBearer()}; + + let f = await fetch(url, init); + if (f.status !== 403) return f; + + let refreshResp = await fetch(TOKEN_REFRESH_API, { + method: "POST", + mode: "cors", + cache: "no-cache", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({token: get(loginStore)?.tokens.refresh}), + }); + if (refreshResp.status !== 200) { + loginStore.set(null); + alert("Failed to refresh login session: please login again to continue"); + throw new Error("403 Unauthorized"); + } + let refreshJson = await refreshResp.json(); + loginStore.set(refreshJson); + + // update current authorization header + init.headers = {...init.headers, Authorization: getBearer()}; + return await fetch(url, init); +} diff --git a/src/views/CertificatesView.svelte b/src/views/CertificatesView.svelte index 594107a..de624cf 100644 --- a/src/views/CertificatesView.svelte +++ b/src/views/CertificatesView.svelte @@ -2,6 +2,8 @@ import {domainOption} from "../stores/domain-option"; import {getBearer} from "../stores/login"; import {type Cert, certsTable} from "../stores/certs"; + import {apiRequest} from "../utils/api-request"; + import {onMount} from "svelte"; const apiOrchid = import.meta.env.VITE_API_ORCHID; @@ -27,25 +29,17 @@ return p.endsWith(domain); } - let promiseForTable: Promise = Object.entries($certsTable).length === 0 ? reloadTable() : Promise.resolve(); + let promiseForTable: Promise = Object.entries($certsTable).length === 0 ? reloadTable() : reloadTable(); - function reloadTable(): Promise { - return new Promise((res, rej) => { - fetch(apiOrchid + "/owned", {headers: {Authorization: getBearer()}}) - .then(x => { - if (x.status !== 200) throw new Error("Unexpected status code: " + x.status); - return x.json(); - }) - .then(x => { - let rows = x as Map; - Object.values(rows).forEach(x => { - $certsTable[Object(x.id).toString()] = x; - }); - console.log($certsTable); - res(); - }) - .catch(x => rej(x)); + async function reloadTable(): Promise { + let f = await apiRequest(apiOrchid + "/owned"); + if (f.status !== 200) throw new Error("Unexpected status code: " + f.status); + let fJson = await f.json(); + let rows = fJson as Map; + Object.values(rows).forEach(x => { + $certsTable[Object(x.id).toString()] = x; }); + console.log($certsTable); } diff --git a/src/views/GeneralView.svelte b/src/views/GeneralView.svelte index f3cd28b..103277e 100644 --- a/src/views/GeneralView.svelte +++ b/src/views/GeneralView.svelte @@ -1,5 +1,29 @@ + +
Warning: This is currently still under development
+ +
{diffExp === 0 ? "No token" : diffExp}
diff --git a/src/views/SitesView.svelte b/src/views/SitesView.svelte index a646647..a3b10ad 100644 --- a/src/views/SitesView.svelte +++ b/src/views/SitesView.svelte @@ -2,6 +2,7 @@ import {domainOption} from "../stores/domain-option"; import {getBearer} from "../stores/login"; import {type Site, sitesTable} from "../stores/sites"; + import {apiRequest} from "../utils/api-request"; const apiSiteHosting = import.meta.env.VITE_API_SITE_HOSTING; @@ -22,51 +23,33 @@ let promiseForTable: Promise = Object.entries($sitesTable).length === 0 ? reloadTable() : Promise.resolve(); - function reloadTable(): Promise { - return new Promise((res, rej) => { - fetch(apiSiteHosting, {headers: {Authorization: getBearer()}}) - .then(x => { - if (x.status !== 200) throw new Error("Unexpected status code: " + x.status); - return x.json(); - }) - .then(x => { - let rows = x as Site[]; - rows.forEach(x => { - $sitesTable[x.domain] = x; - }); - res(); - }) - .catch(x => rej(x)); + async function reloadTable(): Promise { + let f = await apiRequest(apiSiteHosting); + if (f.status !== 200) throw new Error("Unexpected status code: " + f.status); + let fJson = await f.json(); + let rows = fJson as Site[]; + rows.forEach(x => { + $sitesTable[x.domain] = x; }); } - function deleteBranch(site: Site, branch: string) { - fetch(apiSiteHosting, { + async function deleteBranch(site: Site, branch: string) { + let f = await apiRequest(apiSiteHosting, { method: "POST", - headers: {Authorization: getBearer()}, body: JSON.stringify({submit: "delete-branch", site: site.domain, branch}), - }) - .then(x => { - if (x.status !== 200) throw new Error("Unexpected status code: " + x.status); - promiseForTable = reloadTable(); - }) - .catch(x => alert("Error deleting branch: " + x)); + }); + if (f.status !== 200) throw new Error("Unexpected status code: " + f.status); + promiseForTable = reloadTable(); } - function resetSiteSecret(site: Site) { - fetch(apiSiteHosting, { + async function resetSiteSecret(site: Site) { + let f = await apiRequest(apiSiteHosting, { method: "POST", - headers: {Authorization: getBearer()}, body: JSON.stringify({submit: "secret", site: site.domain}), - }) - .then(x => { - if (x.status !== 200) throw new Error("Unexpected status code: " + x.status); - return x.json(); - }) - .then(x => { - alert("New secret: " + x.secret); - }) - .catch(x => alert("Error resetting secret: " + x)); + }); + if (f.status !== 200) throw new Error("Unexpected status code: " + f.status); + let fJson = await f.json(); + alert("New secret: " + fJson.secret); } diff --git a/src/views/TargetManagementView.svelte b/src/views/TargetManagementView.svelte index 80e500f..65b8b4b 100644 --- a/src/views/TargetManagementView.svelte +++ b/src/views/TargetManagementView.svelte @@ -5,6 +5,8 @@