commit 77c374a395800a1b98cbc6d30bcb4493422f8098
parent 39f7da9c11a0e6ba2993e23465a38bf4ebc68ec4
Author: Christian Grothoff <christian@grothoff.org>
Date: Sat, 6 Dec 2025 19:32:42 +0100
fix #10741
Diffstat:
11 files changed, 85 insertions(+), 47 deletions(-)
diff --git a/contrib/typst/vqf_902_11.typ b/contrib/typst/vqf_902_11.typ
@@ -183,9 +183,9 @@
v(0.5em)
// Signature Section
- let submitted_by = get("SUBMITTED_BY")
+ let submitted_by_officer = get("BY_AML_OFFICER")
- if submitted_by == "CUSTOMER" {
+ if submitted_by_officer == false {
table(
columns: (40%, 10%, 50%),
stroke: 0.5pt + black,
@@ -203,7 +203,7 @@
text(size: 9pt, style: "italic")[
It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, documents forgery).
]
- } else if submitted_by == "AML_OFFICER" {
+ } else if submitted_by_officer == true {
text(weight: "bold")[Signed declaration by the customer]
v(0.5em)
@@ -224,7 +224,7 @@
[#if get("ATTACHMENT_SIGNED_DOCUMENT") != "" [Document attached] else [No document]]
)
} else {
- text(weight: "bold")[Invalid submitter (#submitted_by)]
+ text(weight: "bold")[Invalid submitter (#submitted_by_officer)]
}
}
@@ -241,7 +241,7 @@
),
),
"THIRD_PARTY_OWNERSHIP": false,
- "SUBMITTED_BY": "CUSTOMER",
+ "BY_AML_OFFICER": false,
"SIGNATURE": "Jane Smith",
"SIGN_DATE": "10.11.2025",
))
\ No newline at end of file
diff --git a/contrib/typst/vqf_902_11_customer.typ b/contrib/typst/vqf_902_11_customer.typ
@@ -179,9 +179,9 @@
v(0.5em)
// Signature Section
- let submitted_by = get("SUBMITTED_BY")
+ let submitted_by_officer = get("BY_AML_OFFICER")
- if submitted_by == "CUSTOMER" {
+ if submitted_by_officer == false {
table(
columns: (40%, 10%, 50%),
stroke: 0.5pt + black,
@@ -199,7 +199,7 @@
text(size: 9pt, style: "italic")[
It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, documents forgery).
]
- } else if submitted_by == "AML_OFFICER" {
+ } else if submitted_by_officer == true {
text(weight: "bold")[Signed declaration by the customer]
v(0.5em)
@@ -220,7 +220,7 @@
[#if get("ATTACHMENT_SIGNED_DOCUMENT") != "" [Document attached] else [No document]]
)
} else {
- text(weight: "bold")[Invalid submitter (#submitted_by)]
+ text(weight: "bold")[Invalid submitter (#submitted_by_officer)]
}
}
@@ -237,7 +237,7 @@
),
),
"THIRD_PARTY_OWNERSHIP": false,
- "SUBMITTED_BY": "CUSTOMER",
+ "BY_AML_OFFICER": false,
"SIGNATURE": "Jane Smith",
"SIGN_DATE": "10.11.2025",
))
\ No newline at end of file
diff --git a/contrib/typst/vqf_902_11_officer.typ b/contrib/typst/vqf_902_11_officer.typ
@@ -179,9 +179,9 @@
v(0.5em)
// Signature Section
- let submitted_by = get("SUBMITTED_BY")
+ let submitted_by_officer = get("BY_AML_OFFICER")
- if submitted_by == "CUSTOMER" {
+ if submitted_by_officer == false {
table(
columns: (40%, 10%, 50%),
stroke: 0.5pt + black,
@@ -199,7 +199,7 @@
text(size: 9pt, style: "italic")[
It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, documents forgery).
]
- } else if submitted_by == "AML_OFFICER" {
+ } else if submitted_by_officer == true {
text(weight: "bold")[Signed declaration by the customer]
v(0.5em)
@@ -220,7 +220,7 @@
[#if get("ATTACHMENT_SIGNED_DOCUMENT") != "" [Document attached] else [No document]]
)
} else {
- text(weight: "bold")[Invalid submitter (#submitted_by)]
+ text(weight: "bold")[Invalid submitter (#submitted_by_officer)]
}
}
@@ -238,7 +238,7 @@
),
),
"THIRD_PARTY_OWNERSHIP": false,
- "SUBMITTED_BY": "OFFICER",
+ "BY_AML_OFFICER": true,
"SIGNATURE": "Jane Smith",
"SIGN_DATE": "10.11.2025",
))
\ No newline at end of file
diff --git a/contrib/typst/vqf_902_9.typ b/contrib/typst/vqf_902_9.typ
@@ -141,9 +141,9 @@
v(1.5em)
// Signature Section
- let submitted_by = get("SUBMITTED_BY")
+ let submitted_by_officer = get("BY_AML_OFFICER")
- if submitted_by == "CUSTOMER" {
+ if submitted_by_officer == false {
table(
columns: (40%, 10%, 50%),
stroke: 0.5pt + black,
@@ -161,7 +161,7 @@
text(size: 9pt, style: "italic")[
It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)
]
- } else if submitted_by == "AML_OFFICER" {
+ } else if submitted_by_officer == true {
text(weight: "bold")[Signed declaration by the customer]
v(0.5em)
@@ -187,7 +187,7 @@
]
)
} else {
- text(weight: "bold")[Invalid submitter (#submitted_by)]
+ text(weight: "bold")[Invalid submitter (#submitted_by_officer)]
}
}
@@ -204,7 +204,7 @@
"DOMICILE_ADDRESS": "Teststrasse 123\n8001 Zurich"
),
),
- "SUBMITTED_BY": "CUSTOMER",
+ "BY_AML_OFFICER": false,
"SIGNATURE": "John Doe",
"SIGN_DATE": "10.11.2025",
))
\ No newline at end of file
diff --git a/contrib/typst/vqf_902_9_customer.typ b/contrib/typst/vqf_902_9_customer.typ
@@ -137,9 +137,9 @@
v(1.5em)
// Signature Section
- let submitted_by = get("SUBMITTED_BY")
+ let submitted_by_officer = get("BY_AML_OFFICER")
- if submitted_by == "CUSTOMER" {
+ if submitted_by_officer == false {
table(
columns: (40%, 10%, 50%),
stroke: 0.5pt + black,
@@ -157,7 +157,7 @@
text(size: 9pt, style: "italic")[
It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)
]
- } else if submitted_by == "AML_OFFICER" {
+ } else if submitted_by_officer == true {
text(weight: "bold")[Signed declaration by the customer]
v(0.5em)
@@ -183,7 +183,7 @@
]
)
} else {
- text(weight: "bold")[Invalid submitter (#submitted_by)]
+ text(weight: "bold")[Invalid submitter (#submitted_by_officer)]
}
}
@@ -200,7 +200,7 @@
"DOMICILE_ADDRESS": "Teststrasse 123\n8001 Zurich"
),
),
- "SUBMITTED_BY": "CUSTOMER",
+ "BY_AML_OFFICER": false,
"SIGNATURE": "John Doe",
"SIGN_DATE": "10.11.2025",
))
\ No newline at end of file
diff --git a/contrib/typst/vqf_902_9_officer.typ b/contrib/typst/vqf_902_9_officer.typ
@@ -137,9 +137,9 @@
v(1.5em)
// Signature Section
- let submitted_by = get("SUBMITTED_BY")
+ let submitted_by_officer = get("BY_AML_OFFICER")
- if submitted_by == "CUSTOMER" {
+ if submitted_by_officer == false {
table(
columns: (40%, 10%, 50%),
stroke: 0.5pt + black,
@@ -157,7 +157,7 @@
text(size: 9pt, style: "italic")[
It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)
]
- } else if submitted_by == "AML_OFFICER" {
+ } else if submitted_by_officer == true {
text(weight: "bold")[Signed declaration by the customer]
v(0.5em)
@@ -183,7 +183,7 @@
]
)
} else {
- text(weight: "bold")[Invalid submitter (#submitted_by)]
+ text(weight: "bold")[Invalid submitter (#submitted_by_officer)]
}
}
@@ -201,7 +201,7 @@
"DOMICILE_ADDRESS": "Teststrasse 123\n8001 Zurich"
),
),
- "SUBMITTED_BY": "OFFICER",
+ "BY_AML_OFFICER": true,
"SIGNATURE": "John Doe",
"SIGN_DATE": "10.11.2025",
))
\ No newline at end of file
diff --git a/src/exchange/taler-exchange-httpd_aml-attributes-get.c b/src/exchange/taler-exchange-httpd_aml-attributes-get.c
@@ -273,6 +273,7 @@ dump_attachments (struct ResponseContext *rc,
* @param row_id current row in kyc_attributes table
* @param collection_time when were the attributes collected
* @param by_aml_officer was the attribute set filed by the AML officer
+ * @param staff_name name of the officer, NULL if not @a by_aml_officer
* @param enc_attributes_size length of @a enc_attributes
* @param enc_attributes the encrypted collected attributes
*/
@@ -282,6 +283,7 @@ detail_cb (
uint64_t row_id,
struct GNUNET_TIME_Timestamp collection_time,
bool by_aml_officer,
+ const char *staff_name,
size_t enc_attributes_size,
const void *enc_attributes)
{
@@ -344,6 +346,17 @@ detail_cb (
json_object_set_new (attrs,
"BY_AML_OFFICER",
json_boolean (by_aml_officer)));
+ GNUNET_assert (0 ==
+ json_object_set_new (attrs,
+ "FILING_DATE",
+ json_string (
+ GNUNET_STRINGS_timestamp_to_string (
+ collection_time))));
+ if (by_aml_officer)
+ GNUNET_assert (0 ==
+ json_object_set_new (attrs,
+ "AML_STAFF_NAME",
+ json_string (staff_name)));
{
char *have;
diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql
@@ -239,7 +239,7 @@ THEN
-- Process starts and finishes instantly
,in_decision_time
,'aml-officer'
- ,in_decider_pub
+ ,ENCODE(in_decider_pub, 'base64')
,TRUE
)
RETURNING legitimization_process_serial_id
diff --git a/src/exchangedb/exchangedb_history.c b/src/exchangedb/exchangedb_history.c
@@ -296,6 +296,7 @@ struct DecryptContext
* @param row_id current row in kyc_attributes table
* @param collection_time when were the attributes collected
* @param by_aml_officer true if filed by AML officer
+ * @param officer_name name of the officer, NULL if not @a by_aml_officer
* @param enc_attributes_size size of @a enc_attributes
* @param enc_attributes the encrypted collected attributes
*/
@@ -305,6 +306,7 @@ decrypt_attributes (
uint64_t row_id,
struct GNUNET_TIME_Timestamp collection_time,
bool by_aml_officer,
+ const char *officer_name,
size_t enc_attributes_size,
const void *enc_attributes)
{
@@ -312,6 +314,7 @@ decrypt_attributes (
(void) row_id;
(void) collection_time;
+ (void) officer_name;
decon->attr
= TALER_CRYPTO_kyc_attributes_decrypt (decon->hbc->attribute_key,
enc_attributes,
diff --git a/src/exchangedb/pg_select_aml_attributes.c b/src/exchangedb/pg_select_aml_attributes.c
@@ -73,6 +73,7 @@ handle_aml_attributes (void *cls,
{
uint64_t rowid;
struct GNUNET_TIME_Timestamp collection_time;
+ char *officer_name = NULL;
bool by_aml_officer;
size_t enc_attributes_size;
void *enc_attributes;
@@ -83,6 +84,10 @@ handle_aml_attributes (void *cls,
&collection_time),
GNUNET_PQ_result_spec_bool ("by_aml_officer",
&by_aml_officer),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("decider_name",
+ &officer_name),
+ NULL),
GNUNET_PQ_result_spec_variable_size ("encrypted_attributes",
&enc_attributes,
&enc_attributes_size),
@@ -103,6 +108,7 @@ handle_aml_attributes (void *cls,
rowid,
collection_time,
by_aml_officer,
+ officer_name,
enc_attributes_size,
enc_attributes);
GNUNET_PQ_cleanup_result (rs);
@@ -141,26 +147,40 @@ TEH_PG_select_aml_attributes (
PREPARE (pg,
"select_aml_attributes_inc",
"SELECT"
- " kyc_attributes_serial_id"
- ",collection_time"
- ",by_aml_officer"
- ",encrypted_attributes"
- " FROM kyc_attributes"
- " WHERE h_payto=$1"
- " AND kyc_attributes_serial_id > $2"
- " ORDER BY kyc_attributes_serial_id ASC"
+ " ka.kyc_attributes_serial_id"
+ ",ka.collection_time"
+ ",ka.by_aml_officer"
+ ",astaff.decider_name"
+ ",ka.encrypted_attributes"
+ " FROM kyc_attributes ka"
+ " LEFT JOIN legitimization_processes lp"
+ " ON (ka.by_aml_officer AND"
+ " (ka.legitimization_serial = lp.legitimization_process_serial_id))"
+ " LEFT JOIN aml_staff astaff"
+ " ON (ka.by_aml_officer AND"
+ " (DECODE(lp.provider_user_id, 'base64') = astaff.decider_pub))"
+ " WHERE ka.h_payto=$1"
+ " AND ka.kyc_attributes_serial_id > $2"
+ " ORDER BY ka.kyc_attributes_serial_id ASC"
" LIMIT $3");
PREPARE (pg,
"select_aml_attributes_dec",
"SELECT"
- " kyc_attributes_serial_id"
- ",collection_time"
- ",by_aml_officer"
- ",encrypted_attributes"
- " FROM kyc_attributes"
- " WHERE h_payto=$1"
- " AND kyc_attributes_serial_id < $2"
- " ORDER BY kyc_attributes_serial_id DESC"
+ " ka.kyc_attributes_serial_id"
+ ",ka.collection_time"
+ ",ka.by_aml_officer"
+ ",astaff.decider_name"
+ ",ka.encrypted_attributes"
+ " FROM kyc_attributes ka"
+ " LEFT JOIN legitimization_processes lp"
+ " ON (ka.by_aml_officer AND"
+ " (ka.legitimization_serial = lp.legitimization_process_serial_id))"
+ " LEFT JOIN aml_staff astaff"
+ " ON (ka.by_aml_officer AND"
+ " (DECODE(lp.provider_user_id, 'base64') = astaff.decider_pub))"
+ " WHERE ka.h_payto=$1"
+ " AND ka.kyc_attributes_serial_id < $2"
+ " ORDER BY ka.kyc_attributes_serial_id DESC"
" LIMIT $3");
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
stmt,
diff --git a/src/include/taler/taler_exchangedb_plugin.h b/src/include/taler/taler_exchangedb_plugin.h
@@ -3905,6 +3905,7 @@ typedef void
* @param row_id current row in kyc_attributes table
* @param collection_time when were the attributes collected
* @param by_aml_officer true if the data was filed by an AML officer
+ * @param officer_name name of the officer, NULL if not @a by_aml_officer
* @param enc_attributes_size size of @a enc_attributes
* @param enc_attributes the encrypted collected attributes
*/
@@ -3914,6 +3915,7 @@ typedef void
uint64_t row_id,
struct GNUNET_TIME_Timestamp collection_time,
bool by_aml_officer,
+ const char *officer_name,
size_t enc_attributes_size,
const void *enc_attributes);