diff options
Diffstat (limited to 'packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts')
-rw-r--r-- | packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts b/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts index 0ab275f54..ed8301d65 100644 --- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts +++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts @@ -24,7 +24,7 @@ import { WithoutProviderType, WithProviderType } from "./views.js"; export type AuthProvByStatusMap = Record< AuthenticationProviderStatus["status"], (AuthenticationProviderStatus & { url: string })[] -> +>; export type State = NoReducer | InvalidState | WithType | WithoutType; @@ -63,42 +63,69 @@ const map: StateViewMap<State> = { "without-type": WithoutProviderType, }; -export default compose("AddingProviderScreen", useComponentState, map) - +export default compose("AddingProviderScreen", useComponentState, map); +const providerResponseCache = new Map<string, any>(); // `any` is the return type of res.json() export async function testProvider( url: string, expectedMethodType?: string, ): Promise<void> { + const testFatalPrefix = `Encountered a fatal error whilst testing the provider ${url}`; + let configUrl = ""; try { - const response = await fetch(new URL("config", url).href); - const json = await response.json().catch((d) => ({})); - if (!("methods" in json) || !Array.isArray(json.methods)) { - throw Error( - "This provider doesn't have authentication method. Check the provider URL", - ); - } - if (!expectedMethodType) { - return; - } - let found = false; - for (let i = 0; i < json.methods.length && !found; i++) { - found = json.methods[i].type === expectedMethodType; - } - if (!found) { - throw Error( - `This provider does not support authentication method ${expectedMethodType}`, - ); - } + configUrl = new URL("config", url).href; + } catch (error) { + throw new Error(`${testFatalPrefix}: Invalid Provider URL: ${url} +Error: ${error}`); + } + // TODO: look into using core.getProviderInfo :) + const providerHasUrl = providerResponseCache.has(url); + const json = providerHasUrl + ? providerResponseCache.get(url) + : await fetch(configUrl) + .catch((error) => { + throw new Error(`${testFatalPrefix}: Could not connect: ${error} +Please check the URL.`); + }) + .then(async (response) => { + if (!response.ok) + throw new Error( + `${testFatalPrefix}: The server ${response.url} responded with a non-2xx response.`, + ); + try { + return await response.json(); + } catch (error) { + throw new Error( + `${testFatalPrefix}: The server responded with malformed JSON.\nError: ${error}`, + ); + } + }); + if (typeof json !== "object") + throw new Error( + `${testFatalPrefix}: Did not get an object after decoding.`, + ); + if (!("name" in json) || json.name !== "anastasis") { + throw new Error( + `${testFatalPrefix}: The provider does not appear to be an Anastasis provider. Please check the provider's URL.`, + ); + } + if (!("methods" in json) || !Array.isArray(json.methods)) { + throw new Error( + "This provider doesn't have authentication method. Please check the provider's URL and ensure it is properly configured.", + ); + } + if (!providerHasUrl) providerResponseCache.set(url, json); + if (!expectedMethodType) { return; - } catch (e) { - console.log("ERROR testProvider", e); - const error = - e instanceof Error - ? Error( - `There was an error testing this provider, try another one. ${e.message}`, - ) - : Error(`There was an error testing this provider, try another one.`); - throw error; } + let found = false; + for (let i = 0; i < json.methods.length && !found; i++) { + found = json.methods[i].type === expectedMethodType; + } + if (!found) { + throw new Error( + `${testFatalPrefix}: This provider does not support authentication method ${expectedMethodType}`, + ); + } + return; } |