commit 752d53e8a053bfc6656f9ab036215afe8d1efaed
parent 97cec69dfeda6d94e29897a1f329120fa0b2498c
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 16 Dec 2025 19:52:04 +0100
work on tops-aml-pdf test
Diffstat:
9 files changed, 201 insertions(+), 14 deletions(-)
diff --git a/contrib/typst/Makefile.am b/contrib/typst/Makefile.am
@@ -6,6 +6,8 @@ dist_formdata_DATA = \
accept-tos.typ \
challenger_postal.typ \
challenger_sms.typ \
+ generic_note.typ \
+ generic_upload.typ \
taler-logo.svg \
pointing_finger.svg \
vqf_902_1_customer.typ \
diff --git a/contrib/typst/generic_note.typ b/contrib/typst/generic_note.typ
@@ -0,0 +1,78 @@
+// Generic note form.
+
+#let form(data) = {
+ set page(
+ paper: "a4",
+ margin: (left: 2cm, right: 2cm, top: 2cm, bottom: 2.5cm),
+ footer: context [
+ #grid(
+ columns: (1fr, 1fr),
+ align: (left, right),
+ text(size: 8pt)[
+ ],
+ text(size: 8pt)[
+ Page #here().page() of #counter(page).final().first()
+ ]
+ )
+ ]
+ )
+
+ set text(font: "Liberation Sans", size: 10pt)
+ set par(justify: false, leading: 0.65em)
+
+ // Helper function to get value or empty string
+ let get(key, default: "") = {
+ data.at(key, default: default)
+ }
+
+ // Helper function for checkbox
+ let checkbox(checked) = {
+ box(
+ width: 3mm,
+ height: 3mm,
+ stroke: 0.5pt + black,
+ inset: 0.3mm,
+ if checked == true or checked == "true" {
+ place(center + horizon, text(size: 8pt, sym.checkmark))
+ }
+ )
+ }
+
+ // Header
+ align(center, text(size: 11pt, weight: "bold")[CONFIDENTIAL])
+
+ v(0.5em)
+
+ grid(
+ columns: (50%, 50%),
+ gutter: 1em,
+ image("taler-logo.svg", width: 80%),
+ align(right)[
+ #table(
+ columns: (1fr, 1fr),
+ stroke: 0.5pt + black,
+ inset: 5pt,
+ align: (left, left),
+ [AMLA File No.],
+ [#get("FILE_NUMBER")]
+ )
+ ]
+ )
+
+ v(1em)
+
+ // Section 1: Note
+ text(size: 11pt, weight: "bold")[Note:]
+
+ v(0.5em)
+
+ get("NOTE_TEXT")
+
+ v(0.5em)
+}
+
+// Example usage:
+#form((
+ "GENERIC_NOTE": "This is a great customer.",
+ "FILE_NUMBER": 42,
+))
+\ No newline at end of file
diff --git a/contrib/typst/generic_upload.typ b/contrib/typst/generic_upload.typ
@@ -0,0 +1,87 @@
+// Generic note form.
+
+#let form(data) = {
+ set page(
+ paper: "a4",
+ margin: (left: 2cm, right: 2cm, top: 2cm, bottom: 2.5cm),
+ footer: context [
+ #grid(
+ columns: (1fr, 1fr),
+ align: (left, right),
+ text(size: 8pt)[
+ ],
+ text(size: 8pt)[
+ Page #here().page() of #counter(page).final().first()
+ ]
+ )
+ ]
+ )
+
+ set text(font: "Liberation Sans", size: 10pt)
+ set par(justify: false, leading: 0.65em)
+
+ // Helper function to get value or empty string
+ let get(key, default: "") = {
+ data.at(key, default: default)
+ }
+
+ // Helper function for checkbox
+ let checkbox(checked) = {
+ box(
+ width: 3mm,
+ height: 3mm,
+ stroke: 0.5pt + black,
+ inset: 0.3mm,
+ if checked == true or checked == "true" {
+ place(center + horizon, text(size: 8pt, sym.checkmark))
+ }
+ )
+ }
+
+ // Header
+ align(center, text(size: 11pt, weight: "bold")[CONFIDENTIAL])
+
+ v(0.5em)
+
+ grid(
+ columns: (50%, 50%),
+ gutter: 1em,
+ image("taler-logo.svg", width: 80%),
+ align(right)[
+ #table(
+ columns: (1fr, 1fr),
+ stroke: 0.5pt + black,
+ inset: 5pt,
+ align: (left, left),
+ [AMLA File No.],
+ [#get("FILE_NUMBER")]
+ )
+ ]
+ )
+
+ v(1em)
+
+ // Section 1: File upload with note
+ text(size: 11pt, weight: "bold")[File upload with note:]
+
+ v(0.5em)
+
+ block(breakable: false)[
+ #v(0.5em)
+ #table(
+ columns: (35%, 65%),
+ stroke: 0.5pt + black,
+ inset: 5pt,
+ [Note:], [#get("NOTE_TEXT")],
+ [Filename:], [#get("FILE").at("FILENAME")],
+ )
+ #v(0.5em)
+ ]
+}
+
+// Example usage:
+#form((
+ "NOTE_TEXT": "This is a great customer.",
+ "FILE" : ( "FILENAME":"test.txt", "CONTENTS":"..."),
+ "FILE_NUMBER": 42,
+))
+\ No newline at end of file
diff --git a/contrib/typst/vqf_902_1_customer.typ b/contrib/typst/vqf_902_1_customer.typ
@@ -10,7 +10,7 @@
columns: (1fr, 1fr),
align: (left, right),
text(size: 8pt)[
- VQF doc. Nr. 902.1#linebreak()
+ VQF doc. Nr. 902.1-customer#linebreak()
Version of 1 September 2021
],
text(size: 8pt)[
diff --git a/contrib/typst/vqf_902_1_officer.typ b/contrib/typst/vqf_902_1_officer.typ
@@ -10,7 +10,7 @@
columns: (1fr, 1fr),
align: (left, right),
text(size: 8pt)[
- VQF doc. Nr. 902.1#linebreak()
+ VQF doc. Nr. 902.1-officer#linebreak()
Version of 1 September 2021
],
text(size: 8pt)[
diff --git a/contrib/typst/vqf_902_4.typ b/contrib/typst/vqf_902_4.typ
@@ -131,7 +131,7 @@
let pep_domestic = get("PEP_DOMESTIC")
let pep_intl = get("PEP_INTERNATIONAL_ORGANIZATION")
let any_pep = pep_foreign or pep_domestic or pep_intl
- let any_risk = get("ANY_RISK_CRITERION")
+ let pep_high_risk = get("PEP_HIGH_RISK")
block(breakable: false)[
#table(
@@ -174,8 +174,8 @@
#grid(
columns: (auto, 1fr),
gutter: 0.5em,
- checkbox(not any_risk), [No],
- checkbox(any_risk), [#grid(
+ checkbox(not pep_high_risk), [No],
+ checkbox(pep_high_risk), [#grid(
columns: (auto, auto, auto),
gutter: 0.5em,
[Yes],
@@ -653,15 +653,16 @@ text(size: 9pt, style: "italic")[⚠ *This form has to be updated immediately if
"FILING_DATE": "10.11.2025",
"PEP_FOREIGN": false,
"PEP_DOMESTIC": false,
- "PEP_ACCEPTANCE_DATE": "",
+ "PEP_HIGH_RISK": false,
+ "PEP_ACCEPTANCE_DATE": "2024-02-13",
"ANY_RISK_CRITERION": false,
"PEP_INTERNATIONAL_ORGANIZATION": false,
"HIGH_RISK_COUNTRY": false,
- "COUNTRY_RISK_ACCEPTANCE_DATE": "",
+ "COUNTRY_RISK_ACCEPTANCE_DATE": "2024-2-13",
"COUNTRY_RISK_NATIONALITY_LEVEL": "LOW",
"INDUSTRY_RISK_LEVEL": "TRANSPARENT",
"CONTACT_RISK_LEVEL": "LOW",
"RISK_CLASSIFICATION_LEVEL": "NO_HIGH_RISK",
"TRANSACTION_RISK_RULE": "more than 50k/month",
- "HIGH_RISK_ACCEPTANCE_DATE": "",
+ "HIGH_RISK_ACCEPTANCE_DATE": "2024-3-20",
))
\ No newline at end of file
diff --git a/contrib/typst/vqf_902_5.typ b/contrib/typst/vqf_902_5.typ
@@ -147,7 +147,6 @@
v(0.5em)
- let have_assets = get("BIZREL_HAVE_ASSETS")
let origin_cat = get("BIZREL_ORIGIN_CATEGORY")
block(breakable: false)[
@@ -156,7 +155,7 @@
stroke: 0.5pt + black,
inset: 5pt,
[Nature, amount and currency of the involved assets],
- [#if have_assets {get("BIZREL_ORIGIN_NATURE")} else {""}],
+ [#get("BIZREL_ORIGIN_NATURE")],
[Category],
[#grid(
columns: (auto, 1fr),
@@ -242,7 +241,6 @@
"FILING_DATE": "10.11.2025",
"BIZREL_PROFESSION": "Software Engineer",
"BIZREL_INCOME": "Annual income CHF 150,000",
- "BIZREL_HAVE_ASSETS": true,
"BIZREL_ORIGIN_NATURE": "CHF 50,000 in cash",
"BIZREL_ORIGIN_CATEGORY": "SAVINGS",
"BIZREL_PURPOSE": "Payment services",
diff --git a/src/exchange/taler-exchange-httpd_aml-attributes-get.c b/src/exchange/taler-exchange-httpd_aml-attributes-get.c
@@ -775,7 +775,7 @@ TEH_handler_aml_attributes_get (
rctx);
MHD_suspend_connection (rc->connection);
rctx->tc = TALER_MHD_typst (TEH_cfg,
- true,
+ false,
"exchange",
rctx->details.pdf.off,
rctx->details.pdf.docs,
diff --git a/src/mhd/mhd_typst.c b/src/mhd/mhd_typst.c
@@ -387,6 +387,21 @@ complete_response (void *cls)
/**
+ * Cancel typst. Wrapper task to do so asynchronously.
+ *
+ * @param[in] cls a `struct TALER_MHD_TypstContext`
+ */
+static void
+cancel_async (void *cls)
+{
+ struct TALER_MHD_TypstContext *tc = cls;
+
+ tc->t = NULL;
+ TALER_MHD_typst_cancel (tc);
+}
+
+
+/**
* Called when a typst helper exited.
*
* @param cls our `struct TypstStage *`
@@ -432,7 +447,9 @@ typst_done_cb (void *cls,
typst_context_fail (tc,
TALER_EC_EXCHANGE_GENERIC_TYPST_TEMPLATE_FAILURE,
err);
- TALER_MHD_typst_cancel (tc);
+ GNUNET_assert (NULL == tc->t);
+ tc->t = GNUNET_SCHEDULER_add_now (&cancel_async,
+ tc);
return;
}
break;
@@ -450,7 +467,9 @@ typst_done_cb (void *cls,
typst_context_fail (tc,
TALER_EC_EXCHANGE_GENERIC_TYPST_CRASH,
err);
- TALER_MHD_typst_cancel (tc);
+ GNUNET_assert (NULL == tc->t);
+ tc->t = GNUNET_SCHEDULER_add_now (&cancel_async,
+ tc);
return;
}
break;