From e2bfbced7ab027c901913e83ff7dd82240661990 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 22 Mar 2024 13:56:16 -0300 Subject: work in progress, new api being used. merchant now should move into using the full API --- .../merchant-backoffice-ui/src/hooks/backend.ts | 245 ++++++++++++--------- 1 file changed, 138 insertions(+), 107 deletions(-) (limited to 'packages/merchant-backoffice-ui/src/hooks/backend.ts') diff --git a/packages/merchant-backoffice-ui/src/hooks/backend.ts b/packages/merchant-backoffice-ui/src/hooks/backend.ts index 4305a9309..37dfd8fd6 100644 --- a/packages/merchant-backoffice-ui/src/hooks/backend.ts +++ b/packages/merchant-backoffice-ui/src/hooks/backend.ts @@ -19,8 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { AbsoluteTime, HttpStatusCode } from "@gnu-taler/taler-util"; import { + AbsoluteTime, + AccessToken, + HttpStatusCode, +} from "@gnu-taler/taler-util"; +import { + EmptyObject, ErrorType, HttpError, HttpResponse, @@ -31,10 +36,8 @@ import { } from "@gnu-taler/web-util/browser"; import { useCallback, useEffect, useState } from "preact/hooks"; import { useSWRConfig } from "swr"; -import { useBackendContext } from "../context/backend.js"; -import { useInstanceContext } from "../context/instance.js"; -import { AccessToken, LoginToken, MerchantBackend, Timestamp } from "../declaration.js"; - +import { useSessionContext } from "../context/session.js"; +import { LoginToken, MerchantBackend, Timestamp } from "../declaration.js"; export function useMatchMutate(): ( re?: RegExp, @@ -49,18 +52,22 @@ export function useMatchMutate(): ( } return function matchRegexMutate(re?: RegExp) { - return mutate((key) => { - // evict if no key or regex === all - if (!key || !re) return true - // match string - if (typeof key === 'string' && re.test(key)) return true - // record or object have the path at [0] - if (typeof key === 'object' && re.test(key[0])) return true - //key didn't match regex - return false - }, undefined, { - revalidate: true, - }); + return mutate( + (key) => { + // evict if no key or regex === all + if (!key || !re) return true; + // match string + if (typeof key === "string" && re.test(key)) return true; + // record or object have the path at [0] + if (typeof key === "object" && re.test(key[0])) return true; + //key didn't match regex + return false; + }, + undefined, + { + revalidate: true, + }, + ); }; } @@ -97,30 +104,36 @@ export function useBackendConfig(): HttpResponse< const { request } = useBackendBaseRequest(); type Type = MerchantBackend.VersionResponse; - type State = { data: HttpResponse>, timer: number } - const [result, setResult] = useState({ data: { loading: true }, timer: 0 }); + type State = { + data: HttpResponse>; + timer: number; + }; + const [result, setResult] = useState({ + data: { loading: true }, + timer: 0, + }); useEffect(() => { if (result.timer) { - clearTimeout(result.timer) + clearTimeout(result.timer); } function tryConfig(): void { request(`/config`) .then((data) => { const timer: any = setTimeout(() => { - tryConfig() - }, CHECK_CONFIG_INTERVAL_OK) - setResult({ data, timer }) + tryConfig(); + }, CHECK_CONFIG_INTERVAL_OK); + setResult({ data, timer }); }) .catch((error) => { const timer: any = setTimeout(() => { - tryConfig() - }, CHECK_CONFIG_INTERVAL_FAIL) - const data = error.cause - setResult({ data, timer }) + tryConfig(); + }, CHECK_CONFIG_INTERVAL_FAIL); + const data = error.cause; + setResult({ data, timer }); }); } - tryConfig() + tryConfig(); }, [request]); return result.data; @@ -134,29 +147,29 @@ interface useBackendInstanceRequestType { fetcher: (endpoint: string) => Promise>; multiFetcher: (params: [url: string[]]) => Promise[]>; orderFetcher: ( - params: [endpoint: string, + params: [ + endpoint: string, paid?: YesOrNo, refunded?: YesOrNo, wired?: YesOrNo, searchDate?: Date, - delta?: number,] + delta?: number, + ], ) => Promise>; transferFetcher: ( - params: [endpoint: string, + params: [ + endpoint: string, payto_uri?: string, verified?: string, position?: string, - delta?: number,] + delta?: number, + ], ) => Promise>; templateFetcher: ( - params: [endpoint: string, - position?: string, - delta?: number] + params: [endpoint: string, position?: string, delta?: number], ) => Promise>; webhookFetcher: ( - params: [endpoint: string, - position?: string, - delta?: number] + params: [endpoint: string, position?: string, delta?: number], ) => Promise>; } interface useBackendBaseRequestType { @@ -167,14 +180,16 @@ interface useBackendBaseRequestType { } type YesOrNo = "yes" | "no"; -type LoginResult = { - valid: true; - token: string; - expiration: Timestamp; -} | { - valid: false; - cause: HttpError<{}>; -} +type LoginResult = + | { + valid: true; + token: string; + expiration: Timestamp; + } + | { + valid: false; + cause: HttpError; + }; export function useCredentialsChecker() { const { request } = useApiContext(); @@ -187,24 +202,34 @@ export function useCredentialsChecker() { const data: MerchantBackend.Instances.LoginTokenRequest = { scope: "write", duration: { - d_us: "forever" + d_us: "forever", }, refreshable: true, - } + }; try { - const response = await request(baseUrl, `/private/token`, { - method: "POST", - token, - data - }); - return { valid: true, token: response.data.token, expiration: response.data.expiration }; + const response = + await request( + baseUrl, + `/private/token`, + { + method: "POST", + token, + data, + }, + ); + return { + valid: true, + token: response.data.token, + expiration: response.data.expiration, + }; } catch (error) { if (error instanceof RequestError) { return { valid: false, cause: error.cause }; } return { - valid: false, cause: { + valid: false, + cause: { type: ErrorType.UNEXPECTED, loading: false, info: { @@ -212,23 +237,28 @@ export function useCredentialsChecker() { status: 0, options: {}, url: `/private/token`, - payload: {} + payload: {}, }, exception: error, - message: (error instanceof Error ? error.message : "unpexepected error") - } + message: + error instanceof Error ? error.message : "unpexepected error", + }, }; } - }; + } async function refreshLoginToken( baseUrl: string, - token: LoginToken + token: LoginToken, ): Promise { - - if (AbsoluteTime.isExpired(AbsoluteTime.fromProtocolTimestamp(token.expiration))) { + if ( + AbsoluteTime.isExpired( + AbsoluteTime.fromProtocolTimestamp(token.expiration), + ) + ) { return { - valid: false, cause: { + valid: false, + cause: { type: ErrorType.CLIENT, status: HttpStatusCode.Unauthorized, message: "login token expired, login again.", @@ -237,16 +267,16 @@ export function useCredentialsChecker() { status: 401, options: {}, url: `/private/token`, - payload: {} + payload: {}, }, - payload: {} + payload: {}, }, - } + }; } - return requestNewLoginToken(baseUrl, token.token as AccessToken) + return requestNewLoginToken(baseUrl, token.token as AccessToken); } - return { requestNewLoginToken, refreshLoginToken } + return { requestNewLoginToken, refreshLoginToken }; } /** @@ -255,37 +285,36 @@ export function useCredentialsChecker() { * @returns request handler to */ export function useBackendBaseRequest(): useBackendBaseRequestType { - const { url: backend, token: loginToken } = useBackendContext(); const { request: requestHandler } = useApiContext(); - const token = loginToken?.token; + const { state } = useSessionContext(); + const token = state.status === "loggedIn" ? state.token : undefined; + const baseUrl = state.backendUrl; const request = useCallback( function requestImpl( endpoint: string, options: RequestOptions = {}, ): Promise> { - return requestHandler(backend, endpoint, { ...options, token }).then(res => { - return res - }).catch(err => { - throw err - }); + return requestHandler(baseUrl, endpoint, { ...options, token }) + .then((res) => { + return res; + }) + .catch((err) => { + throw err; + }); }, - [backend, token], + [baseUrl, token], ); return { request }; } export function useBackendInstanceRequest(): useBackendInstanceRequestType { - const { url: rootBackendUrl, token: rootToken } = useBackendContext(); - const { token: instanceToken, admin } = useInstanceContext(); const { request: requestHandler } = useApiContext(); - const { baseUrl, token: loginToken } = !admin - ? { baseUrl: rootBackendUrl, token: rootToken } - : { baseUrl: rootBackendUrl, token: instanceToken }; - - const token = loginToken?.token; + const { state } = useSessionContext(); + const token = state.status === "loggedIn" ? state.token : undefined; + const baseUrl = state.backendUrl; const request = useCallback( function requestImpl( @@ -301,7 +330,7 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { function multiFetcherImpl( args: [endpoints: string[]], ): Promise[]> { - const [endpoints] = args + const [endpoints] = args; return Promise.all( endpoints.map((endpoint) => requestHandler(baseUrl, endpoint, { token }), @@ -320,18 +349,22 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { const orderFetcher = useCallback( function orderFetcherImpl( - args: [endpoint: string, + args: [ + endpoint: string, paid?: YesOrNo, refunded?: YesOrNo, wired?: YesOrNo, searchDate?: Date, - delta?: number,] + delta?: number, + ], ): Promise> { - const [endpoint, paid, refunded, wired, searchDate, delta] = args + const [endpoint, paid, refunded, wired, searchDate, delta] = args; const date_s = delta && delta < 0 && searchDate ? Math.floor(searchDate.getTime() / 1000) + 1 - : searchDate !== undefined ? Math.floor(searchDate.getTime() / 1000) : undefined; + : searchDate !== undefined + ? Math.floor(searchDate.getTime() / 1000) + : undefined; const params: any = {}; if (paid !== undefined) params.paid = paid; if (delta !== undefined) params.delta = delta; @@ -339,12 +372,12 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { if (wired !== undefined) params.wired = wired; if (date_s !== undefined) params.date_s = date_s; if (delta === 0) { - //in this case we can already assume the response + //in this case we can already assume the response //and avoid network return Promise.resolve({ ok: true, data: { orders: [] } as T, - }) + }); } return requestHandler(baseUrl, endpoint, { params, token }); }, @@ -353,23 +386,25 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { const transferFetcher = useCallback( function transferFetcherImpl( - args: [endpoint: string, + args: [ + endpoint: string, payto_uri?: string, verified?: string, position?: string, - delta?: number,] + delta?: number, + ], ): Promise> { - const [endpoint, payto_uri, verified, position, delta] = args + const [endpoint, payto_uri, verified, position, delta] = args; const params: any = {}; if (payto_uri !== undefined) params.payto_uri = payto_uri; if (verified !== undefined) params.verified = verified; if (delta === 0) { - //in this case we can already assume the response + //in this case we can already assume the response //and avoid network return Promise.resolve({ ok: true, data: { transfers: [] } as T, - }) + }); } if (delta !== undefined) { params.limit = delta; @@ -383,19 +418,17 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { const templateFetcher = useCallback( function templateFetcherImpl( - args: [endpoint: string, - position?: string, - delta?: number,] + args: [endpoint: string, position?: string, delta?: number], ): Promise> { - const [endpoint, position, delta] = args + const [endpoint, position, delta] = args; const params: any = {}; if (delta === 0) { - //in this case we can already assume the response + //in this case we can already assume the response //and avoid network return Promise.resolve({ ok: true, data: { templates: [] } as T, - }) + }); } if (delta !== undefined) { params.limit = delta; @@ -409,19 +442,17 @@ export function useBackendInstanceRequest(): useBackendInstanceRequestType { const webhookFetcher = useCallback( function webhookFetcherImpl( - args: [endpoint: string, - position?: string, - delta?: number,] + args: [endpoint: string, position?: string, delta?: number], ): Promise> { - const [endpoint, position, delta] = args + const [endpoint, position, delta] = args; const params: any = {}; if (delta === 0) { - //in this case we can already assume the response + //in this case we can already assume the response //and avoid network return Promise.resolve({ ok: true, data: { webhooks: [] } as T, - }) + }); } if (delta !== undefined) { params.limit = delta; -- cgit v1.2.3