taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit f6b6215673e829cab3bb9d62ecc334b6346d49d3
parent 22cefcd92bcb88771f1b198a3a00dc05e1f9e8a4
Author: Florian Dold <florian@dold.me>
Date:   Mon, 21 Jul 2025 22:52:06 +0200

make accept-tos form work with PDF-only download link

Diffstat:
Mpackages/aml-backoffice-ui/src/pages/AccountList.tsx | 2--
Mpackages/kyc-ui/src/pages/FillForm.tsx | 37+++++++++++++++++++++++--------------
Mpackages/web-util/src/forms/forms-types.ts | 5++++-
Mpackages/web-util/src/forms/gana/accept-tos.ts | 93+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
4 files changed, 85 insertions(+), 52 deletions(-)

diff --git a/packages/aml-backoffice-ui/src/pages/AccountList.tsx b/packages/aml-backoffice-ui/src/pages/AccountList.tsx @@ -35,8 +35,6 @@ import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js"; import { useOfficer } from "../hooks/officer.js"; import { Profile } from "./Profile.js"; -const TALER_SCREEN_ID = 115; - export function AccountList({ routeToAccountById: caseByIdRoute, }: { diff --git a/packages/kyc-ui/src/pages/FillForm.tsx b/packages/kyc-ui/src/pages/FillForm.tsx @@ -60,34 +60,43 @@ async function getContextByFormId( requirement: KycRequirementInformation, ): Promise<object> { if (id === "accept-tos") { - const reqContx: any = requirement.context; - if (!reqContx) { + const context: any = requirement.context; + if (!context) { throw Error( "accept-tos form requires context with 'tos_url' property. No context present.", ); } - const tos_url = reqContx["tos_url"]; - if (!tos_url) { + const tosUrl = context["tos_url"]; + if (!tosUrl) { throw Error( "accept-tos form requires context with 'tos_url' property. No URL present.", ); } - const resp = await fetch(tos_url); - const tosVersion = resp.headers.get("Taler-Terms-Version"); + // If the tos_version is specified explicitly in the context, + // we take that version. + // Otherwise, we assum the tos_url is a Taler-style "/terms" + // endpoint and request the current version from there. + + let tosVersion = context["tos_version"]; if (!tosVersion) { - throw Error( - "accept-tos form requires 'Taler-Terms-Version' in request response to the 'tos_url'", - ); + const resp = await fetch(tosUrl); + tosVersion = resp.headers.get("Taler-Terms-Version"); + + if (!tosVersion) { + throw Error( + "accept-tos form requires 'Taler-Terms-Version' in request response to the 'tos_url'", + ); + } } const ctx: AcceptTermOfServiceContext = { - tos_url, - tosVersion, - expiration_time: reqContx["expiration_time"], - provider_name: reqContx["provider_name"], - successor_measure: reqContx["successor_measure"], + tos_url: tosUrl, + tos_version: tosVersion, + expiration_time: context["expiration_time"], + provider_name: context["provider_name"], + successor_measure: context["successor_measure"], }; return ctx; } diff --git a/packages/web-util/src/forms/forms-types.ts b/packages/web-util/src/forms/forms-types.ts @@ -239,16 +239,19 @@ type UIFormFieldTextArea = { type: "textArea" } & UIFormFieldBaseConfig; type UIFormFieldToggle = { type: "toggle"; threeState?: boolean; + /** * When the toggle is true use the field is going to have this value. */ trueValue?: any; + /** * When the toggle is false use the field is going to have this value. */ falseValue?: any; + /** - * Only true value, when the google is false the field is going to be undefined. + * Only true value, when the toggle is false the field is going to be undefined. */ onlyTrueValue?: boolean; } & UIFormFieldBaseConfig; diff --git a/packages/web-util/src/forms/gana/accept-tos.ts b/packages/web-util/src/forms/gana/accept-tos.ts @@ -21,6 +21,7 @@ import { import type { InternationalizationAPI, SingleColumnFormDesign, + UIFormElementConfig, } from "@gnu-taler/web-util/browser"; export type AcceptTermOfServiceContext = { @@ -28,16 +29,19 @@ export type AcceptTermOfServiceContext = { provider_name?: string; expiration_time?: TalerProtocolDuration; successor_measure?: string; - tosVersion: string; -}; + tos_version: string; + + /** + * Only open the attached link, do not offer both "view in browser" + * and "download PDF" options. + */ + link_only?: boolean; -// Example context -// { -// "tos_url":"https://exchange.taler-ops.ch/terms", -// "provider_name":"Taler Operations AG", -// "expiration_time":{"d_us": 157680000000000}, -// "successor_measure":"accept-tos" -// } + /** + * @deprecated deprecated alias of tos_version. + */ + tosVersion?: string; +}; /** * @@ -45,35 +49,54 @@ export type AcceptTermOfServiceContext = { * @param context * @returns */ -export const acceptTos = ( +export function acceptTos( i18n: InternationalizationAPI, context: AcceptTermOfServiceContext, -): SingleColumnFormDesign => ({ - type: "single-column" as const, - fields: [ - { +): SingleColumnFormDesign { + const myFields: UIFormElementConfig[] = []; + + if (context.link_only) { + myFields.push({ type: "external-link", id: TalerFormAttributes.DOWNLOADED_TERMS_OF_SERVICE, required: true, url: context.tos_url, - label: i18n.str`View in Browser`, - }, - { - type: "download-link", - id: TalerFormAttributes.DOWNLOADED_TERMS_OF_SERVICE, - url: context.tos_url, - label: i18n.str`Download PDF version`, - required: true, - media: "application/pdf", - help: i18n.str`You must download to proceed`, - }, - { - type: "toggle", - id: TalerFormAttributes.ACCEPTED_TERMS_OF_SERVICE, - required: true, - trueValue: context.tosVersion, - onlyTrueValue: true, - label: i18n.str`Do you accept the terms of service?`, - }, - ], -}); + label: i18n.str`Terms of service`, + help: i18n.str`You must open/download the terms of service to proceed`, + }); + } else { + myFields.push( + { + type: "external-link", + id: TalerFormAttributes.DOWNLOADED_TERMS_OF_SERVICE, + required: true, + url: context.tos_url, + label: i18n.str`View in Browser`, + }, + { + type: "download-link", + id: TalerFormAttributes.DOWNLOADED_TERMS_OF_SERVICE, + url: context.tos_url, + label: i18n.str`Download PDF version`, + required: true, + media: "application/pdf", + help: i18n.str`You must download to proceed`, + }, + ); + } + + return { + type: "single-column" as const, + fields: [ + ...myFields, + { + type: "toggle", + id: TalerFormAttributes.ACCEPTED_TERMS_OF_SERVICE, + required: true, + trueValue: context.tos_version ?? context.tosVersion, + onlyTrueValue: true, + label: i18n.str`Do you accept the terms of service?`, + }, + ], + }; +}