291 lines
8.2 KiB
TypeScript
291 lines
8.2 KiB
TypeScript
/*
|
|
This file is part of GNU Taler
|
|
(C) 2021-2023 Taler Systems S.A.
|
|
|
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
|
terms of the GNU General Public License as published by the Free Software
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
import {
|
|
HttpResponse,
|
|
HttpResponseOk,
|
|
RequestError,
|
|
} from "@gnu-taler/web-util/lib/index.browser";
|
|
import { useBackendContext } from "../context/backend.js";
|
|
import { MerchantBackend } from "../declaration.js";
|
|
import {
|
|
useBackendBaseRequest,
|
|
useBackendInstanceRequest,
|
|
useMatchMutate,
|
|
} from "./backend.js";
|
|
|
|
// FIX default import https://github.com/microsoft/TypeScript/issues/49189
|
|
import _useSWR, { SWRHook, useSWRConfig } from "swr";
|
|
const useSWR = _useSWR as unknown as SWRHook;
|
|
|
|
interface InstanceAPI {
|
|
updateInstance: (
|
|
data: MerchantBackend.Instances.InstanceReconfigurationMessage,
|
|
) => Promise<void>;
|
|
deleteInstance: () => Promise<void>;
|
|
clearToken: () => Promise<void>;
|
|
setNewToken: (token: string) => Promise<void>;
|
|
}
|
|
|
|
export function useAdminAPI(): AdminAPI {
|
|
const { request } = useBackendBaseRequest();
|
|
const mutateAll = useMatchMutate();
|
|
|
|
const createInstance = async (
|
|
instance: MerchantBackend.Instances.InstanceConfigurationMessage,
|
|
): Promise<void> => {
|
|
await request(`/management/instances`, {
|
|
method: "POST",
|
|
data: instance,
|
|
});
|
|
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
const deleteInstance = async (id: string): Promise<void> => {
|
|
await request(`/management/instances/${id}`, {
|
|
method: "DELETE",
|
|
});
|
|
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
const purgeInstance = async (id: string): Promise<void> => {
|
|
await request(`/management/instances/${id}`, {
|
|
method: "DELETE",
|
|
params: {
|
|
purge: "YES",
|
|
},
|
|
});
|
|
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
return { createInstance, deleteInstance, purgeInstance };
|
|
}
|
|
|
|
export interface AdminAPI {
|
|
createInstance: (
|
|
data: MerchantBackend.Instances.InstanceConfigurationMessage,
|
|
) => Promise<void>;
|
|
deleteInstance: (id: string) => Promise<void>;
|
|
purgeInstance: (id: string) => Promise<void>;
|
|
}
|
|
|
|
export function useManagementAPI(instanceId: string): InstanceAPI {
|
|
const mutateAll = useMatchMutate();
|
|
const { updateToken } = useBackendContext();
|
|
const { request } = useBackendBaseRequest();
|
|
|
|
const updateInstance = async (
|
|
instance: MerchantBackend.Instances.InstanceReconfigurationMessage,
|
|
): Promise<void> => {
|
|
await request(`/management/instances/${instanceId}`, {
|
|
method: "PATCH",
|
|
data: instance,
|
|
});
|
|
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
const deleteInstance = async (): Promise<void> => {
|
|
await request(`/management/instances/${instanceId}`, {
|
|
method: "DELETE",
|
|
});
|
|
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
const clearToken = async (): Promise<void> => {
|
|
await request(`/management/instances/${instanceId}/auth`, {
|
|
method: "POST",
|
|
data: { method: "external" },
|
|
});
|
|
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
const setNewToken = async (newToken: string): Promise<void> => {
|
|
await request(`/management/instances/${instanceId}/auth`, {
|
|
method: "POST",
|
|
data: { method: "token", token: newToken },
|
|
});
|
|
|
|
updateToken(newToken);
|
|
mutateAll(/\/management\/instances/);
|
|
};
|
|
|
|
return { updateInstance, deleteInstance, setNewToken, clearToken };
|
|
}
|
|
|
|
export function useInstanceAPI(): InstanceAPI {
|
|
const { mutate } = useSWRConfig();
|
|
const {
|
|
url: baseUrl,
|
|
token: adminToken,
|
|
updateLoginStatus,
|
|
} = useBackendContext();
|
|
const { request } = useBackendInstanceRequest();
|
|
|
|
const updateInstance = async (
|
|
instance: MerchantBackend.Instances.InstanceReconfigurationMessage,
|
|
): Promise<void> => {
|
|
await request(`/private/`, {
|
|
method: "PATCH",
|
|
data: instance,
|
|
});
|
|
|
|
if (adminToken) mutate(["/private/instances", adminToken, baseUrl], null);
|
|
mutate([`/private/`], null);
|
|
};
|
|
|
|
const deleteInstance = async (): Promise<void> => {
|
|
await request(`/private/`, {
|
|
method: "DELETE",
|
|
// token: adminToken,
|
|
});
|
|
|
|
if (adminToken) mutate(["/private/instances", adminToken, baseUrl], null);
|
|
mutate([`/private/`], null);
|
|
};
|
|
|
|
const clearToken = async (): Promise<void> => {
|
|
await request(`/private/auth`, {
|
|
method: "POST",
|
|
data: { method: "external" },
|
|
});
|
|
|
|
mutate([`/private/`], null);
|
|
};
|
|
|
|
const setNewToken = async (newToken: string): Promise<void> => {
|
|
await request(`/private/auth`, {
|
|
method: "POST",
|
|
data: { method: "token", token: newToken },
|
|
});
|
|
|
|
updateLoginStatus(baseUrl, newToken);
|
|
mutate([`/private/`], null);
|
|
};
|
|
|
|
return { updateInstance, deleteInstance, setNewToken, clearToken };
|
|
}
|
|
|
|
export function useInstanceDetails(): HttpResponse<
|
|
MerchantBackend.Instances.QueryInstancesResponse,
|
|
MerchantBackend.ErrorDetail
|
|
> {
|
|
const { fetcher } = useBackendInstanceRequest();
|
|
|
|
const { data, error, isValidating } = useSWR<
|
|
HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
|
|
RequestError<MerchantBackend.ErrorDetail>
|
|
>([`/private/`], fetcher, {
|
|
refreshInterval: 0,
|
|
refreshWhenHidden: false,
|
|
revalidateOnFocus: false,
|
|
revalidateOnReconnect: false,
|
|
refreshWhenOffline: false,
|
|
errorRetryCount: 0,
|
|
errorRetryInterval: 1,
|
|
shouldRetryOnError: false,
|
|
});
|
|
|
|
if (isValidating) return { loading: true, data: data?.data };
|
|
if (data) return data;
|
|
if (error) return error.info;
|
|
return { loading: true };
|
|
}
|
|
|
|
type KYCStatus =
|
|
| { type: "ok" }
|
|
| { type: "redirect"; status: MerchantBackend.Instances.AccountKycRedirects };
|
|
|
|
export function useInstanceKYCDetails(): HttpResponse<
|
|
KYCStatus,
|
|
MerchantBackend.ErrorDetail
|
|
> {
|
|
const { fetcher } = useBackendInstanceRequest();
|
|
|
|
const { data, error } = useSWR<
|
|
HttpResponseOk<MerchantBackend.Instances.AccountKycRedirects>,
|
|
RequestError<MerchantBackend.ErrorDetail>
|
|
>([`/private/kyc`], fetcher, {
|
|
refreshInterval: 60 * 1000,
|
|
refreshWhenHidden: false,
|
|
revalidateOnFocus: false,
|
|
revalidateIfStale: false,
|
|
revalidateOnMount: false,
|
|
revalidateOnReconnect: false,
|
|
refreshWhenOffline: false,
|
|
errorRetryCount: 0,
|
|
errorRetryInterval: 1,
|
|
shouldRetryOnError: false,
|
|
});
|
|
|
|
if (data) {
|
|
if (data.info?.status === 202)
|
|
return { ok: true, data: { type: "redirect", status: data.data } };
|
|
return { ok: true, data: { type: "ok" } };
|
|
}
|
|
if (error) return error.info;
|
|
return { loading: true };
|
|
}
|
|
|
|
export function useManagedInstanceDetails(
|
|
instanceId: string,
|
|
): HttpResponse<
|
|
MerchantBackend.Instances.QueryInstancesResponse,
|
|
MerchantBackend.ErrorDetail
|
|
> {
|
|
const { request } = useBackendBaseRequest();
|
|
|
|
const { data, error, isValidating } = useSWR<
|
|
HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
|
|
RequestError<MerchantBackend.ErrorDetail>
|
|
>([`/management/instances/${instanceId}`], request, {
|
|
refreshInterval: 0,
|
|
refreshWhenHidden: false,
|
|
revalidateOnFocus: false,
|
|
revalidateOnReconnect: false,
|
|
refreshWhenOffline: false,
|
|
errorRetryCount: 0,
|
|
errorRetryInterval: 1,
|
|
shouldRetryOnError: false,
|
|
});
|
|
|
|
if (isValidating) return { loading: true, data: data?.data };
|
|
if (data) return data;
|
|
if (error) return error.info;
|
|
return { loading: true };
|
|
}
|
|
|
|
export function useBackendInstances(): HttpResponse<
|
|
MerchantBackend.Instances.InstancesResponse,
|
|
MerchantBackend.ErrorDetail
|
|
> {
|
|
const { request } = useBackendBaseRequest();
|
|
|
|
const { data, error, isValidating } = useSWR<
|
|
HttpResponseOk<MerchantBackend.Instances.InstancesResponse>,
|
|
RequestError<MerchantBackend.ErrorDetail>
|
|
>(["/management/instances"], request);
|
|
|
|
if (isValidating) return { loading: true, data: data?.data };
|
|
if (data) return data;
|
|
if (error) return error.info;
|
|
return { loading: true };
|
|
}
|