manage provider screen
This commit is contained in:
parent
bc806e7b51
commit
c898eae296
@ -25,10 +25,10 @@ import { AddingProviderScreen as TestedComponent } from './AddingProviderScreen'
|
||||
|
||||
|
||||
export default {
|
||||
title: 'Pages/backup/AuthorizationMethod/AddingProvider',
|
||||
title: 'Pages/ManageProvider',
|
||||
component: TestedComponent,
|
||||
args: {
|
||||
order: 4,
|
||||
order: 1,
|
||||
},
|
||||
argTypes: {
|
||||
onUpdate: { action: 'onUpdate' },
|
||||
|
@ -1,11 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import {
|
||||
encodeCrock,
|
||||
stringToBytes
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { AuthenticationProviderStatusOk } from "anastasis-core";
|
||||
import { h, VNode } from "preact";
|
||||
import { useLayoutEffect, useRef, useState } from "preact/hooks";
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
|
||||
import { TextInput } from "../../components/fields/TextInput";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
import { authMethods, KnownAuthMethods } from "./authMethod";
|
||||
import { AnastasisClientFrame } from "./index";
|
||||
|
||||
@ -13,38 +10,70 @@ interface Props {
|
||||
providerType?: KnownAuthMethods;
|
||||
cancel: () => void;
|
||||
}
|
||||
|
||||
|
||||
async function testProvider(url: string, expectedMethodType?: string): Promise<void> {
|
||||
try {
|
||||
const response = await fetch(`${url}/config`)
|
||||
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}`)
|
||||
}
|
||||
return
|
||||
} catch (e) {
|
||||
console.log("error", 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function AddingProviderScreen({ providerType, cancel }: Props): VNode {
|
||||
const reducer = useAnastasisContext();
|
||||
|
||||
const [providerURL, setProviderURL] = useState("");
|
||||
const [error, setError] = useState<string | undefined>()
|
||||
const [testing, setTesting] = useState(false)
|
||||
const providerLabel = providerType ? authMethods[providerType].label : undefined
|
||||
|
||||
function testProvider(): void {
|
||||
setError(undefined)
|
||||
//FIXME: move this timeout logic into a hook
|
||||
const timeout = useRef<number | undefined>(undefined);
|
||||
useEffect(() => {
|
||||
if (timeout) window.clearTimeout(timeout.current)
|
||||
timeout.current = window.setTimeout(async () => {
|
||||
const url = providerURL.endsWith('/') ? providerURL.substring(0, providerURL.length - 1) : providerURL
|
||||
if (!url) return;
|
||||
try {
|
||||
setTesting(true)
|
||||
await testProvider(url, providerType)
|
||||
// this is use as tested but everything when ok
|
||||
// undefined will mean that the field is not dirty
|
||||
setError("")
|
||||
} catch (e) {
|
||||
console.log("tuvieja", e)
|
||||
if (e instanceof Error) setError(e.message)
|
||||
}
|
||||
setTesting(false)
|
||||
}, 1000);
|
||||
}, [providerURL])
|
||||
|
||||
fetch(`${providerURL}/config`)
|
||||
.then(r => r.json().catch(d => ({})))
|
||||
.then(r => {
|
||||
if (!("methods" in r) || !Array.isArray(r.methods)) {
|
||||
setError("This provider doesn't have authentication method. Check the provider URL")
|
||||
return;
|
||||
}
|
||||
if (!providerLabel) {
|
||||
setError("")
|
||||
return
|
||||
}
|
||||
let found = false
|
||||
for (let i = 0; i < r.methods.length && !found; i++) {
|
||||
found = r.methods[i].type !== providerType
|
||||
}
|
||||
if (!found) {
|
||||
setError(`This provider does not support authentication method ${providerLabel}`)
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
setError(`There was an error testing this provider, try another one. ${e.message}`)
|
||||
})
|
||||
|
||||
if (!reducer) {
|
||||
return <div>no reducer in context</div>;
|
||||
}
|
||||
|
||||
function addProvider(): void {
|
||||
// addAuthMethod({
|
||||
// authentication_method: {
|
||||
@ -54,10 +83,6 @@ export function AddingProviderScreen({ providerType, cancel }: Props): VNode {
|
||||
// },
|
||||
// });
|
||||
}
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
useLayoutEffect(() => {
|
||||
inputRef.current?.focus();
|
||||
}, []);
|
||||
|
||||
let errors = !providerURL ? 'Add provider URL' : undefined
|
||||
try {
|
||||
@ -69,14 +94,25 @@ export function AddingProviderScreen({ providerType, cancel }: Props): VNode {
|
||||
errors = error
|
||||
}
|
||||
|
||||
if (!reducer.currentReducerState || !("authentication_providers" in reducer.currentReducerState)) {
|
||||
return <div>invalid state</div>
|
||||
}
|
||||
|
||||
const authProviders = reducer.currentReducerState.authentication_providers || {}
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame hideNav
|
||||
title={!providerLabel ? `Backup: Adding a provider` : `Backup: Adding a ${providerLabel} provider`}
|
||||
title="Backup: Manage providers"
|
||||
hideNext={errors}>
|
||||
<div>
|
||||
<p>
|
||||
Add a provider url {errors}
|
||||
</p>
|
||||
{!providerLabel ?
|
||||
<p>
|
||||
Add a provider url
|
||||
</p> :
|
||||
<p>
|
||||
Add a provider url for a {providerLabel} service
|
||||
</p>
|
||||
}
|
||||
<div class="container">
|
||||
<TextInput
|
||||
label="Provider URL"
|
||||
@ -84,18 +120,60 @@ export function AddingProviderScreen({ providerType, cancel }: Props): VNode {
|
||||
grabFocus
|
||||
bind={[providerURL, setProviderURL]} />
|
||||
</div>
|
||||
<p class="block">
|
||||
Example: https://kudos.demo.anastasis.lu
|
||||
</p>
|
||||
|
||||
{testing && <p class="block has-text-info">Testing</p>}
|
||||
{!!error && <p class="block has-text-danger">{error}</p>}
|
||||
{error === "" && <p class="block has-text-success">This provider worked!</p>}
|
||||
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button class="button" onClick={testProvider}>TEST</button>
|
||||
</div>
|
||||
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
|
||||
|
||||
<div class="block" style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button class="button" onClick={cancel}>Cancel</button>
|
||||
<span data-tooltip={errors}>
|
||||
<button class="button is-info" disabled={errors !== undefined} onClick={addProvider}>Add</button>
|
||||
<button class="button is-info" disabled={error !== "" || testing} onClick={addProvider}>Add</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="subtitle">
|
||||
Current providers
|
||||
</p>
|
||||
{/* <table class="table"> */}
|
||||
{Object.keys(authProviders).map(k => {
|
||||
const p = authProviders[k]
|
||||
if (("currency" in p)) {
|
||||
return <TableRow url={k} info={p} />
|
||||
}
|
||||
}
|
||||
)}
|
||||
{/* </table> */}
|
||||
</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
function TableRow({ url, info }: { url: string, info: AuthenticationProviderStatusOk }) {
|
||||
const [status, setStatus] = useState("checking")
|
||||
useEffect(function () {
|
||||
testProvider(url.endsWith('/') ? url.substring(0, url.length - 1) : url)
|
||||
.then(function () { setStatus('responding') })
|
||||
.catch(function () { setStatus('failed to contact') })
|
||||
})
|
||||
return <div class="box" style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<div class="subtitle">{url}</div>
|
||||
<dl>
|
||||
<dt><b>Business Name</b></dt>
|
||||
<dd>{info.business_name}</dd>
|
||||
<dt><b>Supported methods</b></dt>
|
||||
<dd>{info.methods.map(m => m.type).join(',')}</dd>
|
||||
<dt><b>Maximum storage</b></dt>
|
||||
<dd>{info.storage_limit_in_megabytes} Mb</dd>
|
||||
<dt><b>Status</b></dt>
|
||||
<dd>{status}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="block" style={{ marginTop: 'auto', marginBottom: 'auto', display: 'flex', justifyContent: 'space-between', flexDirection: 'column' }}>
|
||||
<button class="button is-danger" >Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
Loading…
Reference in New Issue
Block a user