From 019c2266955b5312cbf35946d6874e69fb6c63a7 Mon Sep 17 00:00:00 2001 From: Nullptrderef Date: Sun, 21 Apr 2024 10:18:31 +0200 Subject: input validation :) --- .../src/pages/home/AddingProviderScreen/index.ts | 116 ++++++++++----------- .../src/pages/home/AddingProviderScreen/state.ts | 24 +++-- 2 files changed, 70 insertions(+), 70 deletions(-) (limited to 'packages/anastasis-webui') diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts b/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts index 365d2e8e7..ed8301d65 100644 --- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts +++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen/index.ts @@ -70,72 +70,62 @@ export async function testProvider( url: string, expectedMethodType?: string, ): Promise { + const testFatalPrefix = `Encountered a fatal error whilst testing the provider ${url}`; + let configUrl = ""; try { - // TODO: look into using core.getProviderInfo :) - const providerHasUrl = providerResponseCache.has(url); - const json = providerHasUrl - ? providerResponseCache.get(url) - : await fetch(new URL("config", url).href) - .catch((error) => { - console.error("Provider HTTP Error:", error); + 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( - "Encountered a fatal error whilst testing the provider: " + url, + `${testFatalPrefix}: The server responded with malformed JSON.\nError: ${error}`, ); - }) - .then(async (response) => { - if (!response.ok) - throw new Error( - `The server ${response.url} responded with a non-2xx response.`, - ); - try { - return await response.json(); - } catch (error) { - console.error("Provider Parsing Error:", error); - throw new Error( - "Encountered a fatal error whilst testing the provider: " + url, - ); - } - }); - if (typeof json !== "object") - throw new Error( - "Encountered a fatal error whilst testing the provider: " + - url + - "\nError: Did not get an object after decoding.", - ); - if (!("name" in json) || json.name !== "anastasis") { - throw new Error( - "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; - } - let found = false; - for (let i = 0; i < json.methods.length && !found; i++) { - found = json.methods[i].type === expectedMethodType; - } - if (!found) { - throw new Error( - `This provider does not support authentication method ${expectedMethodType}`, - ); - } + } + }); + 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 - ? new Error( - `There was an error testing this provider, try another one. ${e.message}`, - ) - : new 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; } diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen/state.ts b/packages/anastasis-webui/src/pages/home/AddingProviderScreen/state.ts index f80f1c464..30e4d750d 100644 --- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen/state.ts +++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen/state.ts @@ -76,14 +76,23 @@ export default function useComponentState({ useEffect(() => { if (timeout.current) clearTimeout(timeout.current); timeout.current = setTimeout(async () => { - const url = providerURL.endsWith("/") ? providerURL : providerURL + "/"; - if (!providerURL || authProviders.includes(url)) return; + let url = providerURL; + if (!url || authProviders.includes(url)) return; + if (url && !url.match(/^(https?:)\/\/.+\/(?:config)?$/iu)) + return setError( + "Malformed URL: Must be an HTTP(S) URL ending with a /", + ); + if (url.endsWith("/config")) url = url.substring(0, url.length - 6); try { setTesting(true); await testProvider(url, providerType); setError(""); } catch (e) { if (e instanceof Error) setError(e.message); + else + throw new Error( + `Unexpected Error Type: ${typeof e} - Cannot handle. Error: ${e}`, + ); } setTesting(false); }, 200); @@ -114,11 +123,12 @@ export default function useComponentState({ let errors = !providerURL ? "Add provider URL" : undefined; let url: string | undefined; - try { - url = new URL("", providerURL).href; - } catch { - errors = "Check the URL"; - } + // We'll validate it in testProvider & via a regex above - there's no need in this :) + // try { + // url = new URL("", providerURL).href; + // } catch { + // errors = "Check the URL"; + // } const _url = url; if (!!error && !errors) { -- cgit v1.2.3