diff --git a/package-lock.json b/package-lock.json index d3a610f..14f8f7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.7.0", "dependencies": { "@deltablot/dropzone": "^7.4.3", - "@e4a/pg-js": "^1.10.0", + "@e4a/pg-js": "^1.11.0", "@iconify/svelte": "^5.2.1", "@privacybydesign/yivi-css": "^1.0.1", "country-flag-icons": "^1.6.17", @@ -59,9 +59,9 @@ } }, "node_modules/@e4a/pg-js": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@e4a/pg-js/-/pg-js-1.10.0.tgz", - "integrity": "sha512-grC1snIzsM2+VEL/oFRWz4+c2IRaLFR5duV8XUKso92S97r3e8z2IEZHXblS4uNtJEtOlbA+UA/1UWEHi0mimg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@e4a/pg-js/-/pg-js-1.11.0.tgz", + "integrity": "sha512-EKg6Bqv+frHD5Wx2xlbFaGCJ82za27E7s4Zi63GtucSZRWzON8D+NGZ7WNqA/ghMuNIgZObYMM60D/w4M5TyUA==", "license": "MIT", "dependencies": { "@e4a/pg-wasm": "^0.6.1", diff --git a/package.json b/package.json index e7846fc..8d27c79 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ }, "dependencies": { "@deltablot/dropzone": "^7.4.3", - "@e4a/pg-js": "^1.10.0", + "@e4a/pg-js": "^1.11.0", "@iconify/svelte": "^5.2.1", "@privacybydesign/yivi-css": "^1.0.1", "country-flag-icons": "^1.6.17", diff --git a/src/lib/components/filesharing/SendButton.svelte b/src/lib/components/filesharing/SendButton.svelte index e4e43db..15dc88b 100644 --- a/src/lib/components/filesharing/SendButton.svelte +++ b/src/lib/components/filesharing/SendButton.svelte @@ -19,6 +19,7 @@ import { MAX_UPLOAD_SIZE, ROLLING_LIMIT } from '$lib/env' import { parseLimitExceededBody, bytesToGB } from '$lib/usage' import { recordUpload, getLocalUsedBytes } from '$lib/localUsage' + import { SIGN_ATTRIBUTES } from './signAttributes' interface props { encryptState: EncryptState @@ -37,7 +38,7 @@ const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - let canEncrypt = $derived(() => { + let canEncrypt = $derived.by(() => { if (encryptState.files.length === 0) return false const totalSize = encryptState.files.reduce((a, f) => a + f.size, 0) if (totalSize >= MAX_UPLOAD_SIZE) return false @@ -138,7 +139,7 @@ await tick() try { - if (!canEncrypt()) return + if (!canEncrypt) return // Build recipients const recipients = encryptState.recipients.map( @@ -151,23 +152,11 @@ } ) - // Build sign method — email always included, other attributes optional + // Build sign method — email is always required; name is optional + // (any of four credentials accepted). See signAttributes.ts. const sign = pg.sign.yivi({ element: '#crypt-irma-qr', - attributes: [ - { - t: 'pbdf.gemeente.personalData.fullname', - optional: true, - }, - { - t: 'pbdf.sidn-pbdf.mobilenumber.mobilenumber', - optional: true, - }, - { - t: 'pbdf.gemeente.personalData.dateofbirth', - optional: true, - }, - ], + attributes: SIGN_ATTRIBUTES, includeSender: true, }) diff --git a/src/lib/components/filesharing/signAttributes.ts b/src/lib/components/filesharing/signAttributes.ts new file mode 100644 index 0000000..fb10b9c --- /dev/null +++ b/src/lib/components/filesharing/signAttributes.ts @@ -0,0 +1,37 @@ +import type { AttrConItem } from '@e4a/pg-js' + +/** + * Yivi attributes the sender may disclose when signing a PostGuard file + * share. The PKG prepends the mandatory email attribute automatically. + * + * The first entry is an optional name disjunction — the sender may prove + * their name from any one of four credentials, or skip entirely: + * + * - `pbdf.gemeente.personalData.fullname` (Dutch municipality), OR + * - `pbdf.pbdf.passport.{firstName,lastName}`, OR + * - `pbdf.pbdf.idcard.{firstName,lastName}`, OR + * - `pbdf.pbdf.drivinglicence.{firstName,lastName}`. + * + * The leading `[]` alternative makes the whole group optional per Yivi + * convention — senders without any of these credentials can still send. + */ +export const SIGN_ATTRIBUTES: AttrConItem[] = [ + [ + [], + [{ t: 'pbdf.gemeente.personalData.fullname' }], + [ + { t: 'pbdf.pbdf.passport.firstName' }, + { t: 'pbdf.pbdf.passport.lastName' }, + ], + [ + { t: 'pbdf.pbdf.idcard.firstName' }, + { t: 'pbdf.pbdf.idcard.lastName' }, + ], + [ + { t: 'pbdf.pbdf.drivinglicence.firstName' }, + { t: 'pbdf.pbdf.drivinglicence.lastName' }, + ], + ], + { t: 'pbdf.sidn-pbdf.mobilenumber.mobilenumber', optional: true }, + { t: 'pbdf.gemeente.personalData.dateofbirth', optional: true }, +] diff --git a/src/lib/locales/en.json b/src/lib/locales/en.json index 2df57fd..2eed2ec 100644 --- a/src/lib/locales/en.json +++ b/src/lib/locales/en.json @@ -202,7 +202,7 @@ "emailSender": "Email address", "emailSenderHeading": "Your information", "emailSenderSubHeadingToggle": "Why do you need this information?", - "emailSenderSubHeading": "Let the recipient(s) know these files are from you. Before sending, you sign the files by proving your email address and any additional personal data with the Yivi app.", + "emailSenderSubHeading": "Let the recipient(s) know these files are from you. Before sending, you sign the files with the Yivi app by proving your email address. You can optionally also share your name from a municipality, passport, ID card, or driving licence.", "messageHeading": "Message (optional)", "messageText": "This message will not be encrypted and will be included in the notification email.", "messagePlaceholder": "Type your message here...", @@ -210,7 +210,7 @@ "yiviInfo": "What is Yivi?", "yiviInfoText": "Yivi is a free and privacy-friendly authentication app. With Yivi you can prove who you are by selectively sharing personal data, such as your email address, phone number, or name. At PostGuard we use Yivi to securely encrypt and decrypt files.", "yiviInfoLink": "Learn more about Yivi", - "yiviTip": "Tip: In the Yivi app you can add optional data. This way you let the recipient(s) know for sure that these files come from you.", + "yiviTip": "Tip: In the Yivi app you can also add an optional phone number or date of birth. This way you let the recipient(s) know for sure that these files come from you.", "sending": "Your files are being sent", "retrying": "Connection hiccup, retrying… (attempt {attempt} of {max})", "encrypting": "Encrypting & uploading...", diff --git a/src/lib/locales/nl.json b/src/lib/locales/nl.json index 173f5be..4e3575c 100644 --- a/src/lib/locales/nl.json +++ b/src/lib/locales/nl.json @@ -201,7 +201,7 @@ "emailSender": "E-mailadres", "emailSenderHeading": "Jouw gegevens", "emailSenderSubHeadingToggle": "Waarom heb je deze gegevens nodig?", - "emailSenderSubHeading": "Laat de ontvanger(s) weten dat deze bestanden van jou afkomstig zijn. Voor het verzenden onderteken je de bestanden door je e-mailadres en eventuele aanvullende persoonlijke gegevens aan te tonen met de Yivi-app.", + "emailSenderSubHeading": "Laat de ontvanger(s) weten dat deze bestanden van jou afkomstig zijn. Voor het verzenden onderteken je de bestanden met de Yivi-app door je e-mailadres aan te tonen. Je kunt optioneel ook je naam delen vanuit je gemeente, paspoort, ID-kaart of rijbewijs.", "messageHeading": "Bericht (optioneel)", "messageText": "Dit bericht wordt niet versleuteld en wordt opgenomen in de notificatie-e-mail.", "messagePlaceholder": "Typ hier je bericht...", @@ -209,7 +209,7 @@ "yiviInfo": "Wat is Yivi?", "yiviInfoText": "Yivi is een gratis en privacy-vriendelijke authenticatie-app. Met Yivi kun je bewijzen wie je bent door selectief persoonlijke gegevens te delen, zoals je e-mailadres, telefoonnummer of naam. Bij PostGuard gebruiken we Yivi om bestanden veilig te versleutelen en ontsleutelen.", "yiviInfoLink": "Meer informatie over Yivi", - "yiviTip": "Tip: In de Yivi-app kun je optionele gegevens toevoegen. Zo laat je de ontvanger(s) zeker weten dat deze bestanden van jou komen.", + "yiviTip": "Tip: In de Yivi-app kun je ook een optioneel telefoonnummer of geboortedatum toevoegen. Zo laat je de ontvanger(s) zeker weten dat deze bestanden van jou komen.", "sending": "Je bestanden worden verzonden", "retrying": "Verbindingshapering, opnieuw proberen… (poging {attempt} van {max})", "encrypting": "Ondertekenen & verzenden...",