add anastasis skeleton, put crypto in taler-util
This commit is contained in:
parent
2c3456608e
commit
e2fe2d6db1
30
packages/anastasis-core/package.json
Normal file
30
packages/anastasis-core/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "anastasis-core",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prepare": "tsc",
|
||||
"compile": "tsc",
|
||||
"pretty": "prettier --write src",
|
||||
"test": "tsc && ava",
|
||||
"coverage": "tsc && nyc ava",
|
||||
"clean": "rimraf dist lib tsconfig.tsbuildinfo"
|
||||
},
|
||||
"author": "Florian Dold <dold@taler.net>",
|
||||
"license": "AGPL-3-or-later",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"ava": "^3.15.0",
|
||||
"typescript": "^4.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@gnu-taler/taler-util": "workspace:^0.8.3",
|
||||
"hash-wasm": "^4.9.0"
|
||||
},
|
||||
"ava": {
|
||||
"files": [
|
||||
"lib/**/*test.*"
|
||||
]
|
||||
}
|
||||
}
|
742
packages/anastasis-core/src/anastasis-data.ts
Normal file
742
packages/anastasis-core/src/anastasis-data.ts
Normal file
@ -0,0 +1,742 @@
|
||||
// This file is auto-generated, do not modify.
|
||||
// Generated from v0.2.0-4-g61ea83c on Tue, 05 Oct 2021 10:40:32 +0200
|
||||
// To re-generate, run contrib/gen-ts.sh from the main anastasis code base.
|
||||
|
||||
export const anastasisData = {
|
||||
providersList: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
anastasis_provider: [
|
||||
{
|
||||
url: "https://anastasis.demo.taler.net/",
|
||||
currency: "KUDOS",
|
||||
},
|
||||
{
|
||||
url: "https://kudos.demo.anastasis.lu/",
|
||||
currency: "KUDOS",
|
||||
},
|
||||
{
|
||||
url: "http://localhost:8086/",
|
||||
currency: "TESTKUDOS",
|
||||
},
|
||||
{
|
||||
url: "http://localhost:8087/",
|
||||
currency: "TESTKUDOS",
|
||||
},
|
||||
{
|
||||
url: "http://localhost:8088/",
|
||||
currency: "TESTKUDOS",
|
||||
},
|
||||
{
|
||||
url: "http://localhost:8089/",
|
||||
currency: "TESTKUDOS",
|
||||
},
|
||||
],
|
||||
},
|
||||
countriesList: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
countries: [
|
||||
{
|
||||
code: "al",
|
||||
name: "Albania",
|
||||
continent: "Europe",
|
||||
name_i18n: {
|
||||
de_DE: "Albanien",
|
||||
en_UK: "Albania",
|
||||
},
|
||||
currency: "ALL",
|
||||
call_code: "+355",
|
||||
},
|
||||
{
|
||||
code: "be",
|
||||
name: "Belgium",
|
||||
continent: "Europe",
|
||||
name_i18n: {
|
||||
de_DE: "Belgien",
|
||||
en_UK: "Belgium",
|
||||
},
|
||||
currency: "EUR",
|
||||
call_code: "+32",
|
||||
},
|
||||
{
|
||||
code: "ch",
|
||||
name: "Switzerland",
|
||||
continent: "Europe",
|
||||
name_i18n: {
|
||||
de_DE: "Schweiz",
|
||||
de_CH: "Schwiiz",
|
||||
fr_FR: "Suisse",
|
||||
en_UK: "Swiss",
|
||||
},
|
||||
currency: "CHF",
|
||||
call_code: "+41",
|
||||
},
|
||||
{
|
||||
code: "cz",
|
||||
name: "Czech Republic",
|
||||
continent: "Europe",
|
||||
name_i18n: {
|
||||
en_UK: "Czech Republic",
|
||||
},
|
||||
currency: "CZK",
|
||||
call_code: "+420",
|
||||
},
|
||||
{
|
||||
code: "de",
|
||||
name: "Germany",
|
||||
continent: "Europe",
|
||||
continent_i18n: { de_DE: "Europa" },
|
||||
name_i18n: {
|
||||
de_DE: "Deutschland",
|
||||
de_CH: "Deutschland",
|
||||
fr_FR: "Allemagne",
|
||||
en_UK: "Germany",
|
||||
},
|
||||
currency: "EUR",
|
||||
call_code: "+49",
|
||||
},
|
||||
{
|
||||
code: "dk",
|
||||
name: "Denmark",
|
||||
continent: "Europe",
|
||||
continent_i18n: { de_DE: "Europa" },
|
||||
name_i18n: {
|
||||
en_UK: "Denmark",
|
||||
},
|
||||
currency: "DKK",
|
||||
call_code: "+45",
|
||||
},
|
||||
{
|
||||
code: "es",
|
||||
name: "Spain",
|
||||
continent: "Europe",
|
||||
continent_i18n: { es_ES: "Europa" },
|
||||
name_i18n: {
|
||||
es_ES: "España",
|
||||
},
|
||||
currency: "EUR",
|
||||
call_code: "+44",
|
||||
},
|
||||
{
|
||||
code: "in",
|
||||
name: "India",
|
||||
continent: "India",
|
||||
continent_i18n: { en_EN: "India" },
|
||||
name_i18n: {
|
||||
de_DE: "Indien",
|
||||
de_CH: "Indien",
|
||||
fr_FR: "l'Inde",
|
||||
en_UK: "India",
|
||||
},
|
||||
currency: "INR",
|
||||
call_code: "+91",
|
||||
},
|
||||
{
|
||||
code: "it",
|
||||
name: "Italy",
|
||||
continent: "Europe",
|
||||
name_i18n: {
|
||||
de_DE: "Italien",
|
||||
en_UK: "Italy",
|
||||
},
|
||||
currency: "EUR",
|
||||
call_code: "+39",
|
||||
},
|
||||
{
|
||||
code: "jp",
|
||||
name: "Japan",
|
||||
continent: "Asia",
|
||||
continent_i18n: { en_EN: "Japan" },
|
||||
name_i18n: {
|
||||
de_DE: "Japan",
|
||||
de_CH: "Japan",
|
||||
en_UK: "Japan",
|
||||
},
|
||||
currency: "JPY",
|
||||
call_code: "+81",
|
||||
},
|
||||
{
|
||||
code: "sl",
|
||||
name: "Slovakia",
|
||||
continent: "Europe",
|
||||
name_i18n: {
|
||||
en_UK: "Slovakia",
|
||||
},
|
||||
currency: "EUR",
|
||||
call_code: "+421",
|
||||
},
|
||||
{
|
||||
code: "us",
|
||||
name: "United States of America (USA)",
|
||||
continent: "North America",
|
||||
continent_i18n: { de_DE: "Nordamerika" },
|
||||
name_i18n: {
|
||||
de_DE: "Vereinigte Staaten von Amerika (USA)",
|
||||
de_CH: "Vereinigte Staaten von Amerika (USA)",
|
||||
fr_FR: "États-Unis d'Amérique (USA)",
|
||||
en_UK: "United States of America (USA)",
|
||||
},
|
||||
currency: "USD",
|
||||
call_code: "+1",
|
||||
},
|
||||
{
|
||||
code: "xx",
|
||||
name: "Testland",
|
||||
continent: "Testcontinent",
|
||||
continent_i18n: { de_DE: "Testkontinent" },
|
||||
name_i18n: {
|
||||
de_DE: "Testlandt",
|
||||
de_CH: "Testlandi",
|
||||
fr_FR: "Testpais",
|
||||
en_UK: "Testland",
|
||||
},
|
||||
currency: "TESTKUDOS",
|
||||
call_code: "+00",
|
||||
},
|
||||
{
|
||||
code: "xy",
|
||||
name: "Demoland",
|
||||
continent: "Testcontinent",
|
||||
continent_i18n: { de_DE: "Testkontinent" },
|
||||
name_i18n: {
|
||||
de_DE: "Demolandt",
|
||||
de_CH: "Demolandi",
|
||||
fr_FR: "Demopais",
|
||||
en_UK: "Demoland",
|
||||
},
|
||||
currency: "KUDOS",
|
||||
call_code: "+01",
|
||||
},
|
||||
],
|
||||
},
|
||||
countryDetails: {
|
||||
al: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "nid_number",
|
||||
label: "Numri i Identitetit",
|
||||
label_i18n: {
|
||||
en: "Identity Number",
|
||||
al: "Numri i Identitetit",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_nid_al",
|
||||
uuid: "256e5d30-d65e-481b-9ac4-55f5ac03b24a",
|
||||
"validation-regex":
|
||||
"^[0-9A-T][0-9](((0|5)[0-9])|10|11|51|52)[0-9]{3}[A-W]$",
|
||||
"validation-logic": "AL_NID_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
be: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "nrn_number",
|
||||
label: "National Register Number",
|
||||
label_i18n: {
|
||||
en: "National Register Number",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_nid_be",
|
||||
uuid: "0452f99a-06f7-48bd-8ac0-2e4ed9a24560",
|
||||
"validation-regex": "^[0-9]{11}$",
|
||||
"validation-logic": "BE_NRN_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
ch: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "ahv_number",
|
||||
label: "AHV number",
|
||||
label_i18n: {
|
||||
de_DE: "AHV-Nummer",
|
||||
de_CH: "AHV-Nummer",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_ahv",
|
||||
uuid: "1da87570-ba16-4f62-8a7e-cbda92f51591",
|
||||
"validation-regex":
|
||||
"^(756).[0-9]{4}.[0-9]{4}.[0-9]{2}|(756)[0-9]{10}$",
|
||||
"validation-logic": "CH_AHV_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
cz: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birth_number",
|
||||
label: "Birth Number",
|
||||
label_i18n: {
|
||||
en: "Birth Number",
|
||||
cz: "rodné číslo",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_birthnumber_cz",
|
||||
uuid: "03e3a05b-1192-44f1-ac36-7425512eee1a",
|
||||
"validation-regex":
|
||||
"^[0-9]{2}(((0|2|5|7)[0-9])|10|11|31|32|51|52|81|82)/[0-9]{3}[0-9]?$",
|
||||
"validation-logic": "CZ_BN_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
de: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "tax_number",
|
||||
label: "Taxpayer identification number",
|
||||
label_i18n: {
|
||||
de_DE: "Steuerliche Identifikationsnummer",
|
||||
en: "German taxpayer identification number",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_tax_de",
|
||||
uuid: "dae48f85-e3ff-47a4-a4a3-ed981ed8c3c6",
|
||||
"validation-regex": "^[0-9]{11}$",
|
||||
"validation-logic": "DE_TIN_check",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "social_security_number",
|
||||
label: "Social security number",
|
||||
label_i18n: {
|
||||
de_DE: "Deutsche Sozialversicherungsnummer",
|
||||
en: "German Social security number",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_ssn_de",
|
||||
uuid: "d5e2aa79-1c88-4cf4-a4d2-252508b38e05",
|
||||
"validation-regex": "^[0-9]{8}[[:upper:]][0-9]{3}$",
|
||||
"validation-logic": "DE_SVN_check",
|
||||
optional: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
dk: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "cpr_number",
|
||||
label: "CPR-nummer",
|
||||
label_i18n: {
|
||||
en: "CPR Number",
|
||||
dk: "CPR-nummer",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_cpr_dk",
|
||||
uuid: "38f13a4d-4302-4ada-ada1-c3ff4a8ff689",
|
||||
"validation-regex":
|
||||
"^(0[1-9]|[1-2][0-9]|30|31)((0[1-9]|10|11|12))[0-9]{2}-[0-9A-Z]{4}$",
|
||||
},
|
||||
],
|
||||
},
|
||||
es: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "tax_number",
|
||||
label: "Tax number",
|
||||
label_i18n: {
|
||||
es_ES: "Número de Identificación Fiscal (DNI, NIE)",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_es_dni",
|
||||
uuid: "ac8bd865-6be8-445c-b650-6a18eef16a49",
|
||||
"validation-regex": "^[0-9MXYZ][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$",
|
||||
"validation-logic": "ES_DNI_check",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "ssn_number",
|
||||
label: "Social security number",
|
||||
label_i18n: {
|
||||
es_ES: "Número de Seguridad Social",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_es_ssn",
|
||||
uuid: "22396a19-f3bb-497e-b63a-961fd639140e",
|
||||
"validation-regex": "^[0-9]{11}$",
|
||||
},
|
||||
],
|
||||
},
|
||||
in: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "aadhar_number",
|
||||
label: "Aadhar number",
|
||||
label_i18n: {
|
||||
en: "Aadhar number",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_aadhar_in",
|
||||
uuid: "55afe97a-98bc-48d1-bb37-a9658be3fdc9",
|
||||
"validation-regex": "^[2-9]{1}[0-9]{3}\\s[0-9]{4}\\s[0-9]{4}$",
|
||||
"validation-logic": "IN_AADHAR_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
it: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "fiscal_code",
|
||||
label: "Codice fiscale",
|
||||
label_i18n: {
|
||||
it: "Codice fiscale",
|
||||
en: "Fiscal code",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_cf_it",
|
||||
uuid: "88f53c51-52ad-4d63-a163-ec042589f925",
|
||||
"validation-regex":
|
||||
"^[[:upper:]]{6}[0-9]{2}[A-EHLMPRT](([0-24-6][0-9])|(30|31|70|71))[A-MZ][0-9]{3}[A-Z]$",
|
||||
"validation-logic": "IT_CF_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
jp: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "my_number",
|
||||
label: "My number",
|
||||
label_i18n: {
|
||||
en: "My number",
|
||||
jp: "マイナンバー",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_my_jp",
|
||||
uuid: "90848f42-a83e-4226-8186-329696c14152",
|
||||
"validation-regex": "^[0-9]{12}$",
|
||||
},
|
||||
],
|
||||
},
|
||||
sk: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birth_number",
|
||||
label: "Birth Number",
|
||||
label_i18n: {
|
||||
en: "Birth Number",
|
||||
sk: "rodné číslo",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_birthnumber_sk",
|
||||
uuid: "1cd372fe-2cea-4928-9f29-66f2bdd8555c",
|
||||
"validation-regex":
|
||||
"^[0-9]{2}(((0|2|5|7)[0-9])|10|11|31|32|51|52|81|82)/[0-9]{3}[0-9]?$",
|
||||
"validation-logic": "CZ_BN_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
us: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "birthplace",
|
||||
label: "Birthplace",
|
||||
widget: "anastasis_gtk_ia_birthplace",
|
||||
uuid: "4c822e8e-89c6-11eb-95c4-8b077ad8489f",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "social_security_number",
|
||||
label: "Social security number",
|
||||
label_i18n: {
|
||||
en: "US Social security number",
|
||||
},
|
||||
widget: "anastasis_gtk_ia_ssn_us",
|
||||
uuid: "310a138c-b0b7-4985-b8b8-d00e765e9f9b",
|
||||
"validation-regex": "^d{3}-d{2}-d{4}$",
|
||||
},
|
||||
],
|
||||
},
|
||||
xx: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "sq_number",
|
||||
label: "Square number",
|
||||
widget: "anastasis_gtk_xx_square",
|
||||
uuid: "ed790bca-89bf-11eb-96f2-233996cf644e",
|
||||
"validation-regex": "^[0-9]+$",
|
||||
"validation-logic": "XX_SQUARE_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
xy: {
|
||||
license: "GPLv3+",
|
||||
"SPDX-License-Identifier": "GPL3.0-or-later",
|
||||
required_attributes: [
|
||||
{
|
||||
type: "string",
|
||||
name: "full_name",
|
||||
label: "Full name",
|
||||
widget: "anastasis_gtk_ia_full_name",
|
||||
uuid: "9e8f463f-575f-42cb-85f3-759559997331",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
name: "birthdate",
|
||||
label: "Birthdate",
|
||||
widget: "anastasis_gtk_ia_birthdate",
|
||||
uuid: "83d655c7-bdb6-484d-904e-80c1058c8854",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "prime_number",
|
||||
label: "Prime number",
|
||||
widget: "anastasis_gtk_xx_prime",
|
||||
uuid: "39190a95-cacb-4412-8bae-1f7da3f980b4",
|
||||
"validation-regex": "^[0-9]+$",
|
||||
"validation-logic": "XY_PRIME_check",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
16
packages/anastasis-core/src/crypto.test.ts
Normal file
16
packages/anastasis-core/src/crypto.test.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import test from "ava";
|
||||
|
||||
// Vector generated with taler-anastasis-tvg
|
||||
const userIdVector = {
|
||||
input_id_data: {
|
||||
name: "Fleabag",
|
||||
ssn: "AB123",
|
||||
},
|
||||
input_server_salt: "FZ48EFS7WS3R2ZR4V53A3GFFY4",
|
||||
output_id:
|
||||
"YS45R6CGJV84K1NN7T14ZBCPVTZ6H15XJSM1FV0R748MHPV82SM0126EBZKBAAGCR34Q9AFKPEW1HRT2Q9GQ5JRA3642AB571DKZS18",
|
||||
};
|
||||
|
||||
test("user ID derivation", async (t) => {
|
||||
t.fail();
|
||||
});
|
21
packages/anastasis-core/src/crypto.ts
Normal file
21
packages/anastasis-core/src/crypto.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { argon2id } from "hash-wasm";
|
||||
|
||||
async function userIdentifierDerive(
|
||||
idData: any,
|
||||
serverSalt: string,
|
||||
): Promise<string> {
|
||||
throw Error("not implemented");
|
||||
}
|
||||
|
||||
// interface Keypair {
|
||||
// pub: string;
|
||||
// priv: string;
|
||||
// }
|
||||
|
||||
// async function accountKeypairDerive(): Promise<Keypair> {}
|
||||
|
||||
// async function secureAnswerHash(
|
||||
// answer: string,
|
||||
// truthUuid: string,
|
||||
// questionSalt: string,
|
||||
// ): Promise<string> {}
|
14
packages/anastasis-core/src/index.ts
Normal file
14
packages/anastasis-core/src/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { md5, sha1, sha512, sha3 } from 'hash-wasm';
|
||||
|
||||
async function run() {
|
||||
console.log('MD5:', await md5('demo'));
|
||||
|
||||
const int8Buffer = new Uint8Array([0, 1, 2, 3]);
|
||||
console.log('SHA1:', await sha1(int8Buffer));
|
||||
console.log('SHA512:', await sha512(int8Buffer));
|
||||
|
||||
const int32Buffer = new Uint32Array([1056, 641]);
|
||||
console.log('SHA3-256:', await sha3(int32Buffer, 256));
|
||||
}
|
||||
|
||||
run();
|
30
packages/anastasis-core/tsconfig.json
Normal file
30
packages/anastasis-core/tsconfig.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"target": "ES2018",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"lib": ["es6"],
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"strict": true,
|
||||
"strictPropertyInitialization": false,
|
||||
"outDir": "lib",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"incremental": true,
|
||||
"esModuleInterop": true,
|
||||
"importHelpers": true,
|
||||
"rootDir": "src",
|
||||
"baseUrl": "./src",
|
||||
"typeRoots": ["./node_modules/@types"]
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../taler-util/"
|
||||
}
|
||||
]
|
||||
}
|
@ -805,7 +805,7 @@ export class BridgeIDBFactory {
|
||||
oldVersion,
|
||||
});
|
||||
request.dispatchEvent(event2);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
request.error = new Error();
|
||||
request.error.name = err.name;
|
||||
request.readyState = "done";
|
||||
@ -846,7 +846,7 @@ export class BridgeIDBFactory {
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log("TRACE: connected!");
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log(
|
||||
"TRACE: caught exception while trying to connect with backend",
|
||||
@ -2704,7 +2704,7 @@ export class BridgeIDBTransaction
|
||||
this._active = false;
|
||||
throw err;
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log("TRACING: error during operation: ", err);
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ export function is_transaction_active(
|
||||
e.stopPropagation();
|
||||
};
|
||||
return true;
|
||||
} catch (ex) {
|
||||
} catch (ex: any) {
|
||||
console.log(ex.stack);
|
||||
t.deepEqual(
|
||||
ex.name,
|
||||
|
@ -3,19 +3,17 @@
|
||||
"version": "0.8.3",
|
||||
"description": "Generic helper functionality for GNU Taler",
|
||||
"exports": {
|
||||
".": "./lib/index.js"
|
||||
},
|
||||
"module": "./lib/index.js",
|
||||
"main": "./lib/index.js",
|
||||
"browser": {
|
||||
"./lib/index.js": "./lib/index.browser.js"
|
||||
".": "./lib/index.node.js"
|
||||
},
|
||||
"module": "./lib/index.node.js",
|
||||
"main": "./lib/index.node.js",
|
||||
"browser": "./lib/index.browser.js",
|
||||
"type": "module",
|
||||
"types": "./lib/index.d.ts",
|
||||
"types": "./lib/index.node.d.ts",
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"lib/index.d.ts": [
|
||||
"lib/index.d.ts"
|
||||
"lib/index.node.d.ts": [
|
||||
"lib/index.node.d.ts"
|
||||
],
|
||||
"src/*": [],
|
||||
"*": []
|
||||
@ -40,6 +38,7 @@
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"big-integer": "^1.6.48",
|
||||
"jed": "^1.1.1",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { TalerErrorCode } from "./taler-error-codes.js";
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2021 Taler Systems S.A.
|
||||
|
||||
export { TalerErrorCode };
|
||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
export * from "./amounts.js";
|
||||
export * from "./backupTypes.js";
|
||||
export * from "./codec.js";
|
||||
export * from "./helpers.js";
|
||||
export * from "./libtool-version.js";
|
||||
export * from "./notifications.js";
|
||||
export * from "./payto.js";
|
||||
export * from "./ReserveStatus.js";
|
||||
export * from "./ReserveTransaction.js";
|
||||
export * from "./talerTypes.js";
|
||||
export * from "./taleruri.js";
|
||||
export * from "./time.js";
|
||||
export * from "./transactionsTypes.js";
|
||||
export * from "./walletTypes.js";
|
||||
export * from "./i18n.js";
|
||||
export * from "./logging.js";
|
||||
export * from "./url.js";
|
||||
export { fnutil } from "./fnutils.js";
|
||||
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Entry point for the browser.
|
||||
|
||||
import { loadBrowserPrng } from "./prng-browser.js";
|
||||
loadBrowserPrng();
|
||||
export * from "./index.js";
|
||||
|
23
packages/taler-util/src/index.node.ts
Normal file
23
packages/taler-util/src/index.node.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2021 Taler Systems S.A.
|
||||
|
||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Entry point for nodejs.
|
||||
|
||||
import { initNodePrng } from "./prng-node.js";
|
||||
initNodePrng();
|
||||
export * from "./index.js";
|
||||
export * from "./talerconfig.js";
|
||||
export * from "./globbing/minimatch.js";
|
@ -1,3 +1,25 @@
|
||||
export * from "./index.browser.js";
|
||||
export * from "./talerconfig.js";
|
||||
export * from "./globbing/minimatch.js";
|
||||
import { TalerErrorCode } from "./taler-error-codes.js";
|
||||
|
||||
export { TalerErrorCode };
|
||||
|
||||
export * from "./amounts.js";
|
||||
export * from "./backupTypes.js";
|
||||
export * from "./codec.js";
|
||||
export * from "./helpers.js";
|
||||
export * from "./libtool-version.js";
|
||||
export * from "./notifications.js";
|
||||
export * from "./payto.js";
|
||||
export * from "./ReserveStatus.js";
|
||||
export * from "./ReserveTransaction.js";
|
||||
export * from "./talerTypes.js";
|
||||
export * from "./taleruri.js";
|
||||
export * from "./time.js";
|
||||
export * from "./transactionsTypes.js";
|
||||
export * from "./walletTypes.js";
|
||||
export * from "./i18n.js";
|
||||
export * from "./logging.js";
|
||||
export * from "./url.js";
|
||||
export { fnutil } from "./fnutils.js";
|
||||
export * from "./kdf.js";
|
||||
export * from "./talerCrypto.js";
|
||||
export { randomBytes, secretbox, secretbox_open } from "./nacl-fast.js";
|
||||
|
5
packages/taler-util/src/kdf.d.ts
vendored
Normal file
5
packages/taler-util/src/kdf.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export declare function sha512(data: Uint8Array): Uint8Array;
|
||||
export declare function hmac(digest: (d: Uint8Array) => Uint8Array, blockSize: number, key: Uint8Array, message: Uint8Array): Uint8Array;
|
||||
export declare function hmacSha512(key: Uint8Array, message: Uint8Array): Uint8Array;
|
||||
export declare function hmacSha256(key: Uint8Array, message: Uint8Array): Uint8Array;
|
||||
export declare function kdf(outputLength: number, ikm: Uint8Array, salt: Uint8Array, info: Uint8Array): Uint8Array;
|
76
packages/taler-util/src/kdf.js
Normal file
76
packages/taler-util/src/kdf.js
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2019 GNUnet e.V.
|
||||
|
||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
import * as nacl from "./nacl-fast.js";
|
||||
import { sha256 } from "./sha256.js";
|
||||
export function sha512(data) {
|
||||
return nacl.hash(data);
|
||||
}
|
||||
export function hmac(digest, blockSize, key, message) {
|
||||
if (key.byteLength > blockSize) {
|
||||
key = digest(key);
|
||||
}
|
||||
if (key.byteLength < blockSize) {
|
||||
const k = key;
|
||||
key = new Uint8Array(blockSize);
|
||||
key.set(k, 0);
|
||||
}
|
||||
const okp = new Uint8Array(blockSize);
|
||||
const ikp = new Uint8Array(blockSize);
|
||||
for (let i = 0; i < blockSize; i++) {
|
||||
ikp[i] = key[i] ^ 0x36;
|
||||
okp[i] = key[i] ^ 0x5c;
|
||||
}
|
||||
const b1 = new Uint8Array(blockSize + message.byteLength);
|
||||
b1.set(ikp, 0);
|
||||
b1.set(message, blockSize);
|
||||
const h0 = digest(b1);
|
||||
const b2 = new Uint8Array(blockSize + h0.length);
|
||||
b2.set(okp, 0);
|
||||
b2.set(h0, blockSize);
|
||||
return digest(b2);
|
||||
}
|
||||
export function hmacSha512(key, message) {
|
||||
return hmac(sha512, 128, key, message);
|
||||
}
|
||||
export function hmacSha256(key, message) {
|
||||
return hmac(sha256, 64, key, message);
|
||||
}
|
||||
export function kdf(outputLength, ikm, salt, info) {
|
||||
// extract
|
||||
const prk = hmacSha512(salt, ikm);
|
||||
// expand
|
||||
const N = Math.ceil(outputLength / 32);
|
||||
const output = new Uint8Array(N * 32);
|
||||
for (let i = 0; i < N; i++) {
|
||||
let buf;
|
||||
if (i == 0) {
|
||||
buf = new Uint8Array(info.byteLength + 1);
|
||||
buf.set(info, 0);
|
||||
}
|
||||
else {
|
||||
buf = new Uint8Array(info.byteLength + 1 + 32);
|
||||
for (let j = 0; j < 32; j++) {
|
||||
buf[j] = output[(i - 1) * 32 + j];
|
||||
}
|
||||
buf.set(info, 32);
|
||||
}
|
||||
buf[buf.length - 1] = i + 1;
|
||||
const chunk = hmacSha256(prk, buf);
|
||||
output.set(chunk, i * 32);
|
||||
}
|
||||
return output.slice(0, outputLength);
|
||||
}
|
||||
//# sourceMappingURL=kdf.js.map
|
1
packages/taler-util/src/kdf.js.map
Normal file
1
packages/taler-util/src/kdf.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"kdf.js","sourceRoot":"","sources":["kdf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,MAAM,CAAC,IAAgB;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,MAAqC,EACrC,SAAiB,EACjB,GAAe,EACf,OAAmB;IAEnB,IAAI,GAAG,CAAC,UAAU,GAAG,SAAS,EAAE;QAC9B,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;KACnB;IACD,IAAI,GAAG,CAAC,UAAU,GAAG,SAAS,EAAE;QAC9B,MAAM,CAAC,GAAG,GAAG,CAAC;QACd,GAAG,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;QAChC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACf;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;QAClC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACvB,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;KACxB;IACD,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1D,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACf,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACtB,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IACjD,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACf,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAe,EAAE,OAAmB;IAC7D,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAe,EAAE,OAAmB;IAC7D,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,GAAG,CACjB,YAAoB,EACpB,GAAe,EACf,IAAgB,EAChB,IAAgB;IAEhB,UAAU;IACV,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAElC,SAAS;IACT,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QAC1B,IAAI,GAAG,CAAC;QACR,IAAI,CAAC,IAAI,CAAC,EAAE;YACV,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YAC1C,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;SAClB;aAAM;YACL,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;gBAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;aACnC;YACD,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;SACnB;QACD,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;KAC3B;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACvC,CAAC"}
|
19
packages/taler-util/src/prng-browser.ts
Normal file
19
packages/taler-util/src/prng-browser.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { setPRNG } from "./nacl-fast.js";
|
||||
|
||||
export function loadBrowserPrng() {
|
||||
// Initialize PRNG if environment provides CSPRNG.
|
||||
// If not, methods calling randombytes will throw.
|
||||
// @ts-ignore-error
|
||||
const cr = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
|
||||
|
||||
const QUOTA = 65536;
|
||||
setPRNG(function (x: Uint8Array, n: number) {
|
||||
let i;
|
||||
const v = new Uint8Array(n);
|
||||
for (i = 0; i < n; i += QUOTA) {
|
||||
cr.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
|
||||
}
|
||||
for (i = 0; i < n; i++) x[i] = v[i];
|
||||
for (i = 0; i < v.length; i++) v[i] = 0;
|
||||
});
|
||||
}
|
30
packages/taler-util/src/prng-node.ts
Normal file
30
packages/taler-util/src/prng-node.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2021 Taler Systems S.A.
|
||||
|
||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { setPRNG } from "./nacl-fast.js";
|
||||
import cr from "crypto";
|
||||
|
||||
export function initNodePrng() {
|
||||
// Initialize PRNG if environment provides CSPRNG.
|
||||
// If not, methods calling randombytes will throw.
|
||||
if (cr && cr.randomBytes) {
|
||||
setPRNG(function (x: Uint8Array, n: number) {
|
||||
const v = cr.randomBytes(n);
|
||||
for (let i = 0; i < n; i++) x[i] = v[i];
|
||||
for (let i = 0; i < v.length; i++) v[i] = 0;
|
||||
});
|
||||
}
|
||||
}
|
@ -25,14 +25,11 @@ import {
|
||||
eddsaGetPublic,
|
||||
keyExchangeEddsaEcdhe,
|
||||
keyExchangeEcdheEddsa,
|
||||
rsaBlind,
|
||||
rsaUnblind,
|
||||
stringToBytes,
|
||||
bytesToString,
|
||||
rsaVerify,
|
||||
} from "./talerCrypto.js";
|
||||
import { sha512, kdf } from "./primitives/kdf.js";
|
||||
import * as nacl from "./primitives/nacl-fast.js";
|
||||
import { sha512, kdf } from "./kdf.js";
|
||||
import * as nacl from "./nacl-fast.js";
|
||||
|
||||
test("encoding", (t) => {
|
||||
const s = "Hello, World";
|
@ -21,9 +21,12 @@
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
import * as nacl from "./primitives/nacl-fast.js";
|
||||
import * as nacl from "./nacl-fast.js";
|
||||
import { kdf } from "./kdf.js";
|
||||
import bigint from "big-integer";
|
||||
import { kdf } from "./primitives/kdf.js";
|
||||
import { initNodePrng } from "./prng-node.js";
|
||||
|
||||
initNodePrng();
|
||||
|
||||
export function getRandomBytes(n: number): Uint8Array {
|
||||
return nacl.randomBytes(n);
|
@ -40,14 +40,14 @@ import {
|
||||
codecForString,
|
||||
Logger,
|
||||
Configuration,
|
||||
decodeCrock,
|
||||
rsaBlind,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
NodeHttpLib,
|
||||
getDefaultNodeWallet,
|
||||
OperationFailedAndReportedError,
|
||||
OperationFailedError,
|
||||
decodeCrock,
|
||||
rsaBlind,
|
||||
NodeThreadCryptoWorkerFactory,
|
||||
CryptoApi,
|
||||
walletCoreDebugFlags,
|
||||
@ -810,7 +810,7 @@ advancedCli
|
||||
coinPubList = coinPubListCodec.decode(
|
||||
JSON.parse(args.suspendCoins.coinPubSpec),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
console.log("could not parse coin list:", e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
@ -835,7 +835,7 @@ advancedCli
|
||||
coinPubList = coinPubListCodec.decode(
|
||||
JSON.parse(args.unsuspendCoins.coinPubSpec),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
console.log("could not parse coin list:", e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
@ -44,11 +44,6 @@ import {
|
||||
MerchantInstancesResponse,
|
||||
} from "./merchantApiTypes";
|
||||
import {
|
||||
createEddsaKeyPair,
|
||||
eddsaGetPublic,
|
||||
EddsaKeyPair,
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
openPromise,
|
||||
OperationFailedError,
|
||||
WalletCoreApiClient,
|
||||
@ -64,6 +59,11 @@ import {
|
||||
Duration,
|
||||
parsePaytoUri,
|
||||
CoreApiResponse,
|
||||
createEddsaKeyPair,
|
||||
eddsaGetPublic,
|
||||
EddsaKeyPair,
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { CoinConfig } from "./denomStructures.js";
|
||||
|
||||
@ -441,7 +441,7 @@ export async function pingProc(
|
||||
const resp = await axios.get(url);
|
||||
console.log(`service ${serviceName} available`);
|
||||
return;
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
console.log(`service ${serviceName} not ready:`, e.toString());
|
||||
await delayMs(1000);
|
||||
}
|
||||
@ -1074,8 +1074,12 @@ export class ExchangeService implements ExchangeServiceInterface {
|
||||
|
||||
async purgeSecmodKeys(): Promise<void> {
|
||||
const cfg = Configuration.load(this.configFilename);
|
||||
const rsaKeydir = cfg.getPath("taler-exchange-secmod-rsa", "KEY_DIR").required();
|
||||
const eddsaKeydir = cfg.getPath("taler-exchange-secmod-eddsa", "KEY_DIR").required();
|
||||
const rsaKeydir = cfg
|
||||
.getPath("taler-exchange-secmod-rsa", "KEY_DIR")
|
||||
.required();
|
||||
const eddsaKeydir = cfg
|
||||
.getPath("taler-exchange-secmod-eddsa", "KEY_DIR")
|
||||
.required();
|
||||
// Be *VERY* careful when changing this, or you will accidentally delete user data.
|
||||
await sh(this.globalState, "rm-secmod-keys", `rm -rf ${rsaKeydir}/COIN_*`);
|
||||
await sh(this.globalState, "rm-secmod-keys", `rm ${eddsaKeydir}/*`);
|
||||
@ -1119,11 +1123,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
||||
|
||||
this.exchangeHttpProc = this.globalState.spawnService(
|
||||
"taler-exchange-httpd",
|
||||
[
|
||||
"-c",
|
||||
this.configFilename,
|
||||
...this.timetravelArgArr,
|
||||
],
|
||||
["-c", this.configFilename, ...this.timetravelArgArr],
|
||||
`exchange-httpd-${this.name}`,
|
||||
);
|
||||
|
||||
|
@ -28,7 +28,7 @@ import {
|
||||
BankAccessApi,
|
||||
CreditDebitIndicator,
|
||||
} from "./harness";
|
||||
import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-wallet-core";
|
||||
import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util";
|
||||
import { defaultCoinConfig } from "./denomStructures";
|
||||
|
||||
/**
|
||||
|
@ -21,13 +21,10 @@ import {
|
||||
ConfirmPayResultType,
|
||||
PreparePayResultType,
|
||||
URL,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
NodeHttpLib,
|
||||
WalletApiOperation,
|
||||
} from "@gnu-taler/taler-wallet-core";
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { NodeHttpLib, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||
import {
|
||||
BankService,
|
||||
ExchangeService,
|
||||
@ -566,11 +563,9 @@ async function testWithoutClaimToken(
|
||||
* specification of the endpoint.
|
||||
*/
|
||||
export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) {
|
||||
const {
|
||||
bank,
|
||||
exchange,
|
||||
merchant,
|
||||
} = await createSimpleTestkudosEnvironment(t);
|
||||
const { bank, exchange, merchant } = await createSimpleTestkudosEnvironment(
|
||||
t,
|
||||
);
|
||||
|
||||
// Base URL for the default instance.
|
||||
const merchantBaseUrl = merchant.makeInstanceBaseUrl();
|
||||
|
@ -35,9 +35,9 @@ import {
|
||||
codecForExchangeKeysJson,
|
||||
codecForKeysManagementResponse,
|
||||
Configuration,
|
||||
decodeCrock,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
decodeCrock,
|
||||
NodeHttpLib,
|
||||
readSuccessResponseJsonOrThrow,
|
||||
} from "@gnu-taler/taler-wallet-core";
|
||||
|
@ -63,9 +63,9 @@ import {
|
||||
setupTipPlanchet,
|
||||
setupWithdrawPlanchet,
|
||||
eddsaGetPublic,
|
||||
} from "../talerCrypto.js";
|
||||
import { randomBytes } from "../primitives/nacl-fast.js";
|
||||
import { kdf } from "../primitives/kdf.js";
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { randomBytes } from "@gnu-taler/taler-util";
|
||||
import { kdf } from "@gnu-taler/taler-util";
|
||||
import { Timestamp, timestampTruncateToSecond } from "@gnu-taler/taler-util";
|
||||
|
||||
import { Logger } from "@gnu-taler/taler-util";
|
||||
|
@ -28,8 +28,7 @@ import {
|
||||
import { RequestThrottler } from "../util/RequestThrottler.js";
|
||||
import Axios, { AxiosResponse } from "axios";
|
||||
import { OperationFailedError, makeErrorDetails } from "../errors.js";
|
||||
import { Logger } from "@gnu-taler/taler-util";
|
||||
import { bytesToString } from "../crypto/talerCrypto.js";
|
||||
import { Logger, bytesToString } from "@gnu-taler/taler-util";
|
||||
import { TalerErrorCode, URL } from "@gnu-taler/taler-util";
|
||||
|
||||
const logger = new Logger("NodeHttpLib.ts");
|
||||
@ -83,7 +82,7 @@ export class NodeHttpLib implements HttpRequestLibrary {
|
||||
timeout,
|
||||
maxRedirects: 0,
|
||||
});
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw OperationFailedError.fromCode(
|
||||
TalerErrorCode.WALLET_NETWORK_ERROR,
|
||||
`${e.message}`,
|
||||
|
@ -92,7 +92,7 @@ export async function getDefaultNodeWallet(
|
||||
});
|
||||
const dbContent = JSON.parse(dbContentStr);
|
||||
myBackend.importDump(dbContent);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
const code: string = e.code;
|
||||
if (code === "ENOENT") {
|
||||
logger.trace("wallet file doesn't exist yet");
|
||||
|
@ -15,58 +15,3 @@
|
||||
*/
|
||||
|
||||
export * from "./index.js";
|
||||
|
||||
import { setPRNG } from './crypto/primitives/nacl-fast.js';
|
||||
// export default API;
|
||||
|
||||
function cleanup(arr: Uint8Array): void {
|
||||
for (let i = 0; i < arr.length; i++) arr[i] = 0;
|
||||
}
|
||||
|
||||
// Initialize PRNG if environment provides CSPRNG.
|
||||
// If not, methods calling randombytes will throw.
|
||||
// @ts-ignore-error
|
||||
const cr = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
|
||||
|
||||
const QUOTA = 65536;
|
||||
setPRNG(function (x: Uint8Array, n: number) {
|
||||
let i;
|
||||
const v = new Uint8Array(n);
|
||||
for (i = 0; i < n; i += QUOTA) {
|
||||
cr.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
|
||||
}
|
||||
for (i = 0; i < n; i++) x[i] = v[i];
|
||||
cleanup(v);
|
||||
});
|
||||
// function initPRNG() {
|
||||
// // Initialize PRNG if environment provides CSPRNG.
|
||||
// // If not, methods calling randombytes will throw.
|
||||
// // @ts-ignore-error
|
||||
// const cr = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
|
||||
// if (cr && cr.getRandomValues) {
|
||||
// // Browsers.
|
||||
// const QUOTA = 65536;
|
||||
// setPRNG(function (x: Uint8Array, n: number) {
|
||||
// let i;
|
||||
// const v = new Uint8Array(n);
|
||||
// for (i = 0; i < n; i += QUOTA) {
|
||||
// cr.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
|
||||
// }
|
||||
// for (i = 0; i < n; i++) x[i] = v[i];
|
||||
// cleanup(v);
|
||||
// });
|
||||
// } else if (typeof require !== "undefined") {
|
||||
// // Node.js.
|
||||
// // eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
// const cr = require("crypto");
|
||||
// if (cr && cr.randomBytes) {
|
||||
// setPRNG(function (x: Uint8Array, n: number) {
|
||||
// const v = cr.randomBytes(n);
|
||||
// for (let i = 0; i < n; i++) x[i] = v[i];
|
||||
// cleanup(v);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// initPRNG();
|
@ -22,22 +22,4 @@ export {
|
||||
getDefaultNodeWallet,
|
||||
DefaultNodeWalletArgs,
|
||||
} from "./headless/helpers.js";
|
||||
|
||||
import { setPRNG } from './crypto/primitives/nacl-fast.js';
|
||||
import cr from 'crypto';
|
||||
|
||||
function cleanup(arr: Uint8Array): void {
|
||||
for (let i = 0; i < arr.length; i++) arr[i] = 0;
|
||||
}
|
||||
|
||||
// Initialize PRNG if environment provides CSPRNG.
|
||||
// If not, methods calling randombytes will throw.
|
||||
if (cr && cr.randomBytes) {
|
||||
setPRNG(function (x: Uint8Array, n: number) {
|
||||
const v = cr.randomBytes(n);
|
||||
for (let i = 0; i < n; i++) x[i] = v[i];
|
||||
cleanup(v);
|
||||
});
|
||||
}
|
||||
|
||||
export * from "./crypto/workers/nodeThreadWorker.js";
|
||||
|
@ -36,7 +36,6 @@ export * from "./db-utils.js";
|
||||
export { CryptoImplementation } from "./crypto/workers/cryptoImplementation.js";
|
||||
export type { CryptoWorker } from "./crypto/workers/cryptoWorker.js";
|
||||
export { CryptoWorkerFactory, CryptoApi } from "./crypto/workers/cryptoApi.js";
|
||||
export * from "./crypto/talerCrypto.js";
|
||||
|
||||
export * from "./pending-types.js";
|
||||
|
||||
|
@ -53,14 +53,12 @@ import {
|
||||
Logger,
|
||||
timestampToIsoString,
|
||||
WalletBackupContentV1,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { InternalWalletState } from "../../common.js";
|
||||
import { hash } from "../../crypto/primitives/nacl-fast.js";
|
||||
import {
|
||||
hash,
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
stringToBytes,
|
||||
} from "../../crypto/talerCrypto.js";
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { InternalWalletState } from "../../common.js";
|
||||
import {
|
||||
AbortStatus,
|
||||
CoinSourceType,
|
||||
|
@ -55,11 +55,11 @@ import {
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { gunzipSync, gzipSync } from "fflate";
|
||||
import { InternalWalletState } from "../../common.js";
|
||||
import { kdf } from "../../crypto/primitives/kdf.js";
|
||||
import { kdf } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
secretbox,
|
||||
secretbox_open,
|
||||
} from "../../crypto/primitives/nacl-fast.js";
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
bytesToString,
|
||||
decodeCrock,
|
||||
@ -70,7 +70,7 @@ import {
|
||||
hash,
|
||||
rsaBlind,
|
||||
stringToBytes,
|
||||
} from "../../crypto/talerCrypto.js";
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { CryptoApi } from "../../crypto/workers/cryptoApi.js";
|
||||
import {
|
||||
BackupProviderRecord,
|
||||
|
@ -14,7 +14,7 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { encodeCrock, getRandomBytes } from "../../crypto/talerCrypto.js";
|
||||
import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
ConfigRecord,
|
||||
WalletBackupConfState,
|
||||
|
@ -39,12 +39,12 @@ import {
|
||||
URL,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { InternalWalletState } from "../common.js";
|
||||
import { kdf } from "../crypto/primitives/kdf.js";
|
||||
import { kdf } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
stringToBytes,
|
||||
} from "../crypto/talerCrypto.js";
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { DepositGroupRecord } from "../db.js";
|
||||
import { guardOperationException } from "../errors.js";
|
||||
import { selectPayCoins } from "../util/coinSelection.js";
|
||||
|
@ -40,7 +40,7 @@ import {
|
||||
TalerErrorDetails,
|
||||
Timestamp,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { decodeCrock, encodeCrock, hash } from "../crypto/talerCrypto.js";
|
||||
import { decodeCrock, encodeCrock, hash } from "@gnu-taler/taler-util";
|
||||
import { CryptoApi } from "../crypto/workers/cryptoApi.js";
|
||||
import {
|
||||
DenominationRecord,
|
||||
|
@ -54,7 +54,7 @@ import {
|
||||
URL,
|
||||
getDurationRemaining,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
|
||||
import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
PayCoinSelection,
|
||||
CoinCandidateSelection,
|
||||
|
@ -32,7 +32,7 @@ import {
|
||||
RefreshReason,
|
||||
TalerErrorDetails,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
|
||||
import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
CoinRecord,
|
||||
CoinSourceType,
|
||||
|
@ -14,7 +14,7 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
|
||||
import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
CoinRecord,
|
||||
CoinSourceType,
|
||||
|
@ -32,7 +32,7 @@ import {
|
||||
TalerErrorCode,
|
||||
addPaytoQueryParams,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { randomBytes } from "../crypto/primitives/nacl-fast.js";
|
||||
import { randomBytes } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
ReserveRecordStatus,
|
||||
ReserveBankInfo,
|
||||
@ -63,7 +63,7 @@ import {
|
||||
processWithdrawGroup,
|
||||
getBankWithdrawalInfo,
|
||||
} from "./withdraw.js";
|
||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
|
||||
import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
|
||||
import { Logger, URL } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
readSuccessResponseJsonOrErrorCode,
|
||||
|
@ -55,7 +55,7 @@ import {
|
||||
getHttpResponseErrorDetails,
|
||||
readSuccessResponseJsonOrThrow,
|
||||
} from "../util/http.js";
|
||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto.js";
|
||||
import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
|
||||
|
||||
const logger = new Logger("operations/tip.ts");
|
||||
|
||||
|
@ -15,14 +15,14 @@
|
||||
*/
|
||||
|
||||
import { canonicalJson } from "@gnu-taler/taler-util";
|
||||
import { kdf } from "../crypto/primitives/kdf.js";
|
||||
import { kdf } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
decodeCrock,
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
hash,
|
||||
stringToBytes,
|
||||
} from "../crypto/talerCrypto.js";
|
||||
} from "@gnu-taler/taler-util";
|
||||
|
||||
export namespace ContractTermsUtil {
|
||||
export type PathPredicate = (path: string[]) => boolean;
|
||||
|
@ -198,7 +198,7 @@ export async function readSuccessResponseJsonOrErrorCode<T>(
|
||||
let parsedResponse: T;
|
||||
try {
|
||||
parsedResponse = codec.decode(respJson);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw OperationFailedError.fromCode(
|
||||
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
|
||||
"Response invalid",
|
||||
|
@ -14,13 +14,24 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Amounts, BackupBackupProviderTerms, canonicalizeBaseUrl, i18n } from "@gnu-taler/taler-util";
|
||||
import { verify } from "@gnu-taler/taler-wallet-core/src/crypto/primitives/nacl-fast";
|
||||
import {
|
||||
Amounts,
|
||||
BackupBackupProviderTerms,
|
||||
canonicalizeBaseUrl,
|
||||
i18n,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { VNode, h } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { Checkbox } from "../components/Checkbox";
|
||||
import { ErrorMessage } from "../components/ErrorMessage";
|
||||
import { Button, ButtonPrimary, Input, LightText, PopupBox, SmallLightText } from "../components/styled/index";
|
||||
import {
|
||||
Button,
|
||||
ButtonPrimary,
|
||||
Input,
|
||||
LightText,
|
||||
PopupBox,
|
||||
SmallLightText,
|
||||
} from "../components/styled/index";
|
||||
import * as wxApi from "../wxApi";
|
||||
|
||||
interface Props {
|
||||
@ -30,52 +41,65 @@ interface Props {
|
||||
|
||||
function getJsonIfOk(r: Response) {
|
||||
if (r.ok) {
|
||||
return r.json()
|
||||
return r.json();
|
||||
} else {
|
||||
if (r.status >= 400 && r.status < 500) {
|
||||
throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`)
|
||||
throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`);
|
||||
} else {
|
||||
throw new Error(`Try another server: (${r.status}) ${r.statusText || 'internal server error'}`)
|
||||
throw new Error(
|
||||
`Try another server: (${r.status}) ${
|
||||
r.statusText || "internal server error"
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function ProviderAddPage({ onBack }: Props): VNode {
|
||||
const [verifying, setVerifying] = useState<{ url: string, name: string, provider: BackupBackupProviderTerms } | undefined>(undefined)
|
||||
const [verifying, setVerifying] = useState<
|
||||
| { url: string; name: string; provider: BackupBackupProviderTerms }
|
||||
| undefined
|
||||
>(undefined);
|
||||
|
||||
async function getProviderInfo(url: string): Promise<BackupBackupProviderTerms> {
|
||||
async function getProviderInfo(
|
||||
url: string,
|
||||
): Promise<BackupBackupProviderTerms> {
|
||||
return fetch(`${url}config`)
|
||||
.catch(e => { throw new Error(`Network error`) })
|
||||
.then(getJsonIfOk)
|
||||
.catch((e) => {
|
||||
throw new Error(`Network error`);
|
||||
})
|
||||
.then(getJsonIfOk);
|
||||
}
|
||||
|
||||
if (!verifying) {
|
||||
return <SetUrlView
|
||||
onCancel={onBack}
|
||||
onVerify={(url) => getProviderInfo(url)}
|
||||
onConfirm={(url, name) => getProviderInfo(url)
|
||||
.then((provider) => {
|
||||
setVerifying({ url, name, provider });
|
||||
})
|
||||
.catch(e => e.message)
|
||||
}
|
||||
/>
|
||||
return (
|
||||
<SetUrlView
|
||||
onCancel={onBack}
|
||||
onVerify={(url) => getProviderInfo(url)}
|
||||
onConfirm={(url, name) =>
|
||||
getProviderInfo(url)
|
||||
.then((provider) => {
|
||||
setVerifying({ url, name, provider });
|
||||
})
|
||||
.catch((e) => e.message)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <ConfirmProviderView
|
||||
provider={verifying.provider}
|
||||
url={verifying.url}
|
||||
onCancel={() => {
|
||||
setVerifying(undefined);
|
||||
}}
|
||||
onConfirm={() => {
|
||||
wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack)
|
||||
}}
|
||||
|
||||
/>
|
||||
return (
|
||||
<ConfirmProviderView
|
||||
provider={verifying.provider}
|
||||
url={verifying.url}
|
||||
onCancel={() => {
|
||||
setVerifying(undefined);
|
||||
}}
|
||||
onConfirm={() => {
|
||||
wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export interface SetUrlViewProps {
|
||||
initialValue?: string;
|
||||
onCancel: () => void;
|
||||
@ -84,83 +108,137 @@ export interface SetUrlViewProps {
|
||||
withError?: string;
|
||||
}
|
||||
|
||||
export function SetUrlView({ initialValue, onCancel, onVerify, onConfirm, withError }: SetUrlViewProps) {
|
||||
const [value, setValue] = useState<string>(initialValue || "")
|
||||
const [urlError, setUrlError] = useState(false)
|
||||
const [name, setName] = useState<string|undefined>(undefined)
|
||||
const [error, setError] = useState<string | undefined>(withError)
|
||||
export function SetUrlView({
|
||||
initialValue,
|
||||
onCancel,
|
||||
onVerify,
|
||||
onConfirm,
|
||||
withError,
|
||||
}: SetUrlViewProps) {
|
||||
const [value, setValue] = useState<string>(initialValue || "");
|
||||
const [urlError, setUrlError] = useState(false);
|
||||
const [name, setName] = useState<string | undefined>(undefined);
|
||||
const [error, setError] = useState<string | undefined>(withError);
|
||||
useEffect(() => {
|
||||
try {
|
||||
const url = canonicalizeBaseUrl(value)
|
||||
onVerify(url).then(r => {
|
||||
setUrlError(false)
|
||||
setName(new URL(url).hostname)
|
||||
}).catch(() => {
|
||||
setUrlError(true)
|
||||
setName(undefined)
|
||||
})
|
||||
const url = canonicalizeBaseUrl(value);
|
||||
onVerify(url)
|
||||
.then((r) => {
|
||||
setUrlError(false);
|
||||
setName(new URL(url).hostname);
|
||||
})
|
||||
.catch(() => {
|
||||
setUrlError(true);
|
||||
setName(undefined);
|
||||
});
|
||||
} catch {
|
||||
setUrlError(true)
|
||||
setName(undefined)
|
||||
setUrlError(true);
|
||||
setName(undefined);
|
||||
}
|
||||
}, [value])
|
||||
return <PopupBox>
|
||||
<section>
|
||||
<h1> Add backup provider</h1>
|
||||
<ErrorMessage title={error && "Could not get provider information"} description={error} />
|
||||
<LightText> Backup providers may charge for their service</LightText>
|
||||
<p>
|
||||
<Input invalid={urlError}>
|
||||
<label>URL</label>
|
||||
<input type="text" placeholder="https://" value={value} onChange={(e) => setValue(e.currentTarget.value)} />
|
||||
</Input>
|
||||
<Input>
|
||||
<label>Name</label>
|
||||
<input type="text" disabled={name === undefined} value={name} onChange={e => setName(e.currentTarget.value)}/>
|
||||
</Input>
|
||||
</p>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}><i18n.Translate> < Back</i18n.Translate></Button>
|
||||
<ButtonPrimary
|
||||
disabled={!value && !urlError}
|
||||
onClick={() => {
|
||||
const url = canonicalizeBaseUrl(value)
|
||||
return onConfirm(url, name!).then(r => r ? setError(r) : undefined)
|
||||
}}><i18n.Translate>Next</i18n.Translate></ButtonPrimary>
|
||||
</footer>
|
||||
</PopupBox>
|
||||
}, [value]);
|
||||
return (
|
||||
<PopupBox>
|
||||
<section>
|
||||
<h1> Add backup provider</h1>
|
||||
<ErrorMessage
|
||||
title={error && "Could not get provider information"}
|
||||
description={error}
|
||||
/>
|
||||
<LightText> Backup providers may charge for their service</LightText>
|
||||
<p>
|
||||
<Input invalid={urlError}>
|
||||
<label>URL</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="https://"
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.currentTarget.value)}
|
||||
/>
|
||||
</Input>
|
||||
<Input>
|
||||
<label>Name</label>
|
||||
<input
|
||||
type="text"
|
||||
disabled={name === undefined}
|
||||
value={name}
|
||||
onChange={(e) => setName(e.currentTarget.value)}
|
||||
/>
|
||||
</Input>
|
||||
</p>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate> < Back</i18n.Translate>
|
||||
</Button>
|
||||
<ButtonPrimary
|
||||
disabled={!value && !urlError}
|
||||
onClick={() => {
|
||||
const url = canonicalizeBaseUrl(value);
|
||||
return onConfirm(url, name!).then((r) =>
|
||||
r ? setError(r) : undefined,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<i18n.Translate>Next</i18n.Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</PopupBox>
|
||||
);
|
||||
}
|
||||
|
||||
export interface ConfirmProviderViewProps {
|
||||
provider: BackupBackupProviderTerms,
|
||||
url: string,
|
||||
provider: BackupBackupProviderTerms;
|
||||
url: string;
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
export function ConfirmProviderView({ url, provider, onCancel, onConfirm }: ConfirmProviderViewProps) {
|
||||
export function ConfirmProviderView({
|
||||
url,
|
||||
provider,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
}: ConfirmProviderViewProps) {
|
||||
const [accepted, setAccepted] = useState(false);
|
||||
|
||||
return <PopupBox>
|
||||
<section>
|
||||
<h1>Review terms of service</h1>
|
||||
<div>Provider URL: <a href={url} target="_blank">{url}</a></div>
|
||||
<SmallLightText>Please review and accept this provider's terms of service</SmallLightText>
|
||||
<h2>1. Pricing</h2>
|
||||
<p>
|
||||
{Amounts.isZero(provider.annual_fee) ? 'free of charge' : `${provider.annual_fee} per year of service`}
|
||||
</p>
|
||||
<h2>2. Storage</h2>
|
||||
<p>
|
||||
{provider.storage_limit_in_megabytes} megabytes of storage per year of service
|
||||
</p>
|
||||
<Checkbox label="Accept terms of service" name="terms" onToggle={() => setAccepted(old => !old)} enabled={accepted} />
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}><i18n.Translate> < Back</i18n.Translate></Button>
|
||||
<ButtonPrimary
|
||||
disabled={!accepted}
|
||||
onClick={onConfirm}><i18n.Translate>Add provider</i18n.Translate></ButtonPrimary>
|
||||
</footer>
|
||||
</PopupBox>
|
||||
return (
|
||||
<PopupBox>
|
||||
<section>
|
||||
<h1>Review terms of service</h1>
|
||||
<div>
|
||||
Provider URL:{" "}
|
||||
<a href={url} target="_blank">
|
||||
{url}
|
||||
</a>
|
||||
</div>
|
||||
<SmallLightText>
|
||||
Please review and accept this provider's terms of service
|
||||
</SmallLightText>
|
||||
<h2>1. Pricing</h2>
|
||||
<p>
|
||||
{Amounts.isZero(provider.annual_fee)
|
||||
? "free of charge"
|
||||
: `${provider.annual_fee} per year of service`}
|
||||
</p>
|
||||
<h2>2. Storage</h2>
|
||||
<p>
|
||||
{provider.storage_limit_in_megabytes} megabytes of storage per year of
|
||||
service
|
||||
</p>
|
||||
<Checkbox
|
||||
label="Accept terms of service"
|
||||
name="terms"
|
||||
onToggle={() => setAccepted((old) => !old)}
|
||||
enabled={accepted}
|
||||
/>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate> < Back</i18n.Translate>
|
||||
</Button>
|
||||
<ButtonPrimary disabled={!accepted} onClick={onConfirm}>
|
||||
<i18n.Translate>Add provider</i18n.Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</PopupBox>
|
||||
);
|
||||
}
|
||||
|
@ -14,13 +14,24 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Amounts, BackupBackupProviderTerms, canonicalizeBaseUrl, i18n } from "@gnu-taler/taler-util";
|
||||
import { verify } from "@gnu-taler/taler-wallet-core/src/crypto/primitives/nacl-fast";
|
||||
import {
|
||||
Amounts,
|
||||
BackupBackupProviderTerms,
|
||||
canonicalizeBaseUrl,
|
||||
i18n,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { VNode, h } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { Checkbox } from "../components/Checkbox";
|
||||
import { ErrorMessage } from "../components/ErrorMessage";
|
||||
import { Button, ButtonPrimary, Input, LightText, WalletBox, SmallLightText } from "../components/styled/index";
|
||||
import {
|
||||
Button,
|
||||
ButtonPrimary,
|
||||
Input,
|
||||
LightText,
|
||||
WalletBox,
|
||||
SmallLightText,
|
||||
} from "../components/styled/index";
|
||||
import * as wxApi from "../wxApi";
|
||||
|
||||
interface Props {
|
||||
@ -30,52 +41,65 @@ interface Props {
|
||||
|
||||
function getJsonIfOk(r: Response) {
|
||||
if (r.ok) {
|
||||
return r.json()
|
||||
return r.json();
|
||||
} else {
|
||||
if (r.status >= 400 && r.status < 500) {
|
||||
throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`)
|
||||
throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`);
|
||||
} else {
|
||||
throw new Error(`Try another server: (${r.status}) ${r.statusText || 'internal server error'}`)
|
||||
throw new Error(
|
||||
`Try another server: (${r.status}) ${
|
||||
r.statusText || "internal server error"
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function ProviderAddPage({ onBack }: Props): VNode {
|
||||
const [verifying, setVerifying] = useState<{ url: string, name: string, provider: BackupBackupProviderTerms } | undefined>(undefined)
|
||||
const [verifying, setVerifying] = useState<
|
||||
| { url: string; name: string; provider: BackupBackupProviderTerms }
|
||||
| undefined
|
||||
>(undefined);
|
||||
|
||||
async function getProviderInfo(url: string): Promise<BackupBackupProviderTerms> {
|
||||
async function getProviderInfo(
|
||||
url: string,
|
||||
): Promise<BackupBackupProviderTerms> {
|
||||
return fetch(`${url}config`)
|
||||
.catch(e => { throw new Error(`Network error`) })
|
||||
.then(getJsonIfOk)
|
||||
.catch((e) => {
|
||||
throw new Error(`Network error`);
|
||||
})
|
||||
.then(getJsonIfOk);
|
||||
}
|
||||
|
||||
if (!verifying) {
|
||||
return <SetUrlView
|
||||
onCancel={onBack}
|
||||
onVerify={(url) => getProviderInfo(url)}
|
||||
onConfirm={(url, name) => getProviderInfo(url)
|
||||
.then((provider) => {
|
||||
setVerifying({ url, name, provider });
|
||||
})
|
||||
.catch(e => e.message)
|
||||
}
|
||||
/>
|
||||
return (
|
||||
<SetUrlView
|
||||
onCancel={onBack}
|
||||
onVerify={(url) => getProviderInfo(url)}
|
||||
onConfirm={(url, name) =>
|
||||
getProviderInfo(url)
|
||||
.then((provider) => {
|
||||
setVerifying({ url, name, provider });
|
||||
})
|
||||
.catch((e) => e.message)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <ConfirmProviderView
|
||||
provider={verifying.provider}
|
||||
url={verifying.url}
|
||||
onCancel={() => {
|
||||
setVerifying(undefined);
|
||||
}}
|
||||
onConfirm={() => {
|
||||
wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack)
|
||||
}}
|
||||
|
||||
/>
|
||||
return (
|
||||
<ConfirmProviderView
|
||||
provider={verifying.provider}
|
||||
url={verifying.url}
|
||||
onCancel={() => {
|
||||
setVerifying(undefined);
|
||||
}}
|
||||
onConfirm={() => {
|
||||
wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export interface SetUrlViewProps {
|
||||
initialValue?: string;
|
||||
onCancel: () => void;
|
||||
@ -84,83 +108,137 @@ export interface SetUrlViewProps {
|
||||
withError?: string;
|
||||
}
|
||||
|
||||
export function SetUrlView({ initialValue, onCancel, onVerify, onConfirm, withError }: SetUrlViewProps) {
|
||||
const [value, setValue] = useState<string>(initialValue || "")
|
||||
const [urlError, setUrlError] = useState(false)
|
||||
const [name, setName] = useState<string|undefined>(undefined)
|
||||
const [error, setError] = useState<string | undefined>(withError)
|
||||
export function SetUrlView({
|
||||
initialValue,
|
||||
onCancel,
|
||||
onVerify,
|
||||
onConfirm,
|
||||
withError,
|
||||
}: SetUrlViewProps) {
|
||||
const [value, setValue] = useState<string>(initialValue || "");
|
||||
const [urlError, setUrlError] = useState(false);
|
||||
const [name, setName] = useState<string | undefined>(undefined);
|
||||
const [error, setError] = useState<string | undefined>(withError);
|
||||
useEffect(() => {
|
||||
try {
|
||||
const url = canonicalizeBaseUrl(value)
|
||||
onVerify(url).then(r => {
|
||||
setUrlError(false)
|
||||
setName(new URL(url).hostname)
|
||||
}).catch(() => {
|
||||
setUrlError(true)
|
||||
setName(undefined)
|
||||
})
|
||||
const url = canonicalizeBaseUrl(value);
|
||||
onVerify(url)
|
||||
.then((r) => {
|
||||
setUrlError(false);
|
||||
setName(new URL(url).hostname);
|
||||
})
|
||||
.catch(() => {
|
||||
setUrlError(true);
|
||||
setName(undefined);
|
||||
});
|
||||
} catch {
|
||||
setUrlError(true)
|
||||
setName(undefined)
|
||||
setUrlError(true);
|
||||
setName(undefined);
|
||||
}
|
||||
}, [value])
|
||||
return <WalletBox>
|
||||
<section>
|
||||
<h1> Add backup provider</h1>
|
||||
<ErrorMessage title={error && "Could not get provider information"} description={error} />
|
||||
<LightText> Backup providers may charge for their service</LightText>
|
||||
<p>
|
||||
<Input invalid={urlError}>
|
||||
<label>URL</label>
|
||||
<input type="text" placeholder="https://" value={value} onChange={(e) => setValue(e.currentTarget.value)} />
|
||||
</Input>
|
||||
<Input>
|
||||
<label>Name</label>
|
||||
<input type="text" disabled={name === undefined} value={name} onChange={e => setName(e.currentTarget.value)}/>
|
||||
</Input>
|
||||
</p>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}><i18n.Translate> < Back</i18n.Translate></Button>
|
||||
<ButtonPrimary
|
||||
disabled={!value && !urlError}
|
||||
onClick={() => {
|
||||
const url = canonicalizeBaseUrl(value)
|
||||
return onConfirm(url, name!).then(r => r ? setError(r) : undefined)
|
||||
}}><i18n.Translate>Next</i18n.Translate></ButtonPrimary>
|
||||
</footer>
|
||||
</WalletBox>
|
||||
}, [value]);
|
||||
return (
|
||||
<WalletBox>
|
||||
<section>
|
||||
<h1> Add backup provider</h1>
|
||||
<ErrorMessage
|
||||
title={error && "Could not get provider information"}
|
||||
description={error}
|
||||
/>
|
||||
<LightText> Backup providers may charge for their service</LightText>
|
||||
<p>
|
||||
<Input invalid={urlError}>
|
||||
<label>URL</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="https://"
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.currentTarget.value)}
|
||||
/>
|
||||
</Input>
|
||||
<Input>
|
||||
<label>Name</label>
|
||||
<input
|
||||
type="text"
|
||||
disabled={name === undefined}
|
||||
value={name}
|
||||
onChange={(e) => setName(e.currentTarget.value)}
|
||||
/>
|
||||
</Input>
|
||||
</p>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate> < Back</i18n.Translate>
|
||||
</Button>
|
||||
<ButtonPrimary
|
||||
disabled={!value && !urlError}
|
||||
onClick={() => {
|
||||
const url = canonicalizeBaseUrl(value);
|
||||
return onConfirm(url, name!).then((r) =>
|
||||
r ? setError(r) : undefined,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<i18n.Translate>Next</i18n.Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</WalletBox>
|
||||
);
|
||||
}
|
||||
|
||||
export interface ConfirmProviderViewProps {
|
||||
provider: BackupBackupProviderTerms,
|
||||
url: string,
|
||||
provider: BackupBackupProviderTerms;
|
||||
url: string;
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
export function ConfirmProviderView({ url, provider, onCancel, onConfirm }: ConfirmProviderViewProps) {
|
||||
export function ConfirmProviderView({
|
||||
url,
|
||||
provider,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
}: ConfirmProviderViewProps) {
|
||||
const [accepted, setAccepted] = useState(false);
|
||||
|
||||
return <WalletBox>
|
||||
<section>
|
||||
<h1>Review terms of service</h1>
|
||||
<div>Provider URL: <a href={url} target="_blank">{url}</a></div>
|
||||
<SmallLightText>Please review and accept this provider's terms of service</SmallLightText>
|
||||
<h2>1. Pricing</h2>
|
||||
<p>
|
||||
{Amounts.isZero(provider.annual_fee) ? 'free of charge' : `${provider.annual_fee} per year of service`}
|
||||
</p>
|
||||
<h2>2. Storage</h2>
|
||||
<p>
|
||||
{provider.storage_limit_in_megabytes} megabytes of storage per year of service
|
||||
</p>
|
||||
<Checkbox label="Accept terms of service" name="terms" onToggle={() => setAccepted(old => !old)} enabled={accepted} />
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}><i18n.Translate> < Back</i18n.Translate></Button>
|
||||
<ButtonPrimary
|
||||
disabled={!accepted}
|
||||
onClick={onConfirm}><i18n.Translate>Add provider</i18n.Translate></ButtonPrimary>
|
||||
</footer>
|
||||
</WalletBox>
|
||||
return (
|
||||
<WalletBox>
|
||||
<section>
|
||||
<h1>Review terms of service</h1>
|
||||
<div>
|
||||
Provider URL:{" "}
|
||||
<a href={url} target="_blank">
|
||||
{url}
|
||||
</a>
|
||||
</div>
|
||||
<SmallLightText>
|
||||
Please review and accept this provider's terms of service
|
||||
</SmallLightText>
|
||||
<h2>1. Pricing</h2>
|
||||
<p>
|
||||
{Amounts.isZero(provider.annual_fee)
|
||||
? "free of charge"
|
||||
: `${provider.annual_fee} per year of service`}
|
||||
</p>
|
||||
<h2>2. Storage</h2>
|
||||
<p>
|
||||
{provider.storage_limit_in_megabytes} megabytes of storage per year of
|
||||
service
|
||||
</p>
|
||||
<Checkbox
|
||||
label="Accept terms of service"
|
||||
name="terms"
|
||||
onToggle={() => setAccepted((old) => !old)}
|
||||
enabled={accepted}
|
||||
/>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate> < Back</i18n.Translate>
|
||||
</Button>
|
||||
<ButtonPrimary disabled={!accepted} onClick={onConfirm}>
|
||||
<i18n.Translate>Add provider</i18n.Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</WalletBox>
|
||||
);
|
||||
}
|
||||
|
@ -12,6 +12,19 @@ importers:
|
||||
'@linaria/shaker': 3.0.0-beta.7
|
||||
esbuild: 0.12.21
|
||||
|
||||
packages/anastasis-core:
|
||||
specifiers:
|
||||
'@gnu-taler/taler-util': workspace:^0.8.3
|
||||
ava: ^3.15.0
|
||||
hash-wasm: ^4.9.0
|
||||
typescript: ^4.4.3
|
||||
dependencies:
|
||||
'@gnu-taler/taler-util': link:../taler-util
|
||||
hash-wasm: 4.9.0
|
||||
devDependencies:
|
||||
ava: 3.15.0
|
||||
typescript: 4.4.3
|
||||
|
||||
packages/idb-bridge:
|
||||
specifiers:
|
||||
'@rollup/plugin-commonjs': ^17.1.0
|
||||
@ -52,6 +65,7 @@ importers:
|
||||
specifiers:
|
||||
'@types/node': ^14.14.22
|
||||
ava: ^3.15.0
|
||||
big-integer: ^1.6.48
|
||||
esbuild: ^0.9.2
|
||||
jed: ^1.1.1
|
||||
prettier: ^2.2.1
|
||||
@ -59,6 +73,7 @@ importers:
|
||||
tslib: ^2.1.0
|
||||
typescript: ^4.2.3
|
||||
dependencies:
|
||||
big-integer: 1.6.48
|
||||
jed: 1.1.1
|
||||
tslib: 2.1.0
|
||||
devDependencies:
|
||||
@ -11813,6 +11828,10 @@ packages:
|
||||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/hash-wasm/4.9.0:
|
||||
resolution: {integrity: sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==}
|
||||
dev: false
|
||||
|
||||
/hash.js/1.1.7:
|
||||
resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
|
||||
dependencies:
|
||||
@ -19292,6 +19311,12 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/typescript/4.4.3:
|
||||
resolution: {integrity: sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/uglify-js/3.12.5:
|
||||
resolution: {integrity: sha512-SgpgScL4T7Hj/w/GexjnBHi3Ien9WS1Rpfg5y91WXMj9SY997ZCQU76mH4TpLwwfmMvoOU8wiaRkIf6NaH3mtg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
Loading…
Reference in New Issue
Block a user