diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx')
-rw-r--r-- | packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx index 9fcfcc4bf..d12d1d2d3 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx @@ -19,6 +19,10 @@ * @author Sebastian Javier Marchano (sebasjm) */ +import { + Amounts, + MerchantTemplateContractDetails, +} from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; @@ -35,7 +39,10 @@ import { InputSelector } from "../../../../components/form/InputSelector.js"; import { InputWithAddon } from "../../../../components/form/InputWithAddon.js"; import { useBackendContext } from "../../../../context/backend.js"; import { MerchantBackend, WithId } from "../../../../declaration.js"; -import { randomBase32Key } from "../../../../utils/crypto.js"; +import { + isBase32RFC3548Charset, + randomBase32Key, +} from "../../../../utils/crypto.js"; import { undefinedIfEmpty } from "../../../../utils/table.js"; type Entity = MerchantBackend.Template.TemplatePatchDetails & WithId; @@ -46,12 +53,8 @@ interface Props { template: Entity; } -const algorithms = ["0", "1", "2"]; -const algorithmsNames = [ - "off", - "30s 8d TOTP-SHA1 without amount", - "30s 8d eTOTP-SHA1 with amount", -]; +const algorithms = [0, 1, 2]; +const algorithmsNames = ["off", "30s 8d TOTP-SHA1", "30s 8d eTOTP-SHA1"]; export function UpdatePage({ template, onUpdate, onBack }: Props): VNode { const { i18n } = useTranslationContext(); @@ -60,6 +63,10 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode { const [showKey, setShowKey] = useState(false); const [state, setState] = useState<Partial<Entity>>(template); + const parsedPrice = !state.template_contract?.amount + ? undefined + : Amounts.parse(state.template_contract?.amount); + const errors: FormErrors<Entity> = { template_description: !state.template_description ? i18n.str`should not be empty` @@ -67,6 +74,13 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode { template_contract: !state.template_contract ? undefined : undefinedIfEmpty({ + amount: !state.template_contract?.amount + ? undefined + : !parsedPrice + ? i18n.str`not valid` + : Amounts.isZero(parsedPrice) + ? i18n.str`must be greater than 0` + : undefined, minimum_age: state.template_contract.minimum_age < 0 ? i18n.str`should be greater that 0` @@ -78,7 +92,16 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode { : state.template_contract.pay_duration.d_us < 1000 * 1000 // less than one second ? i18n.str`to short` : undefined, - }), + } as Partial<MerchantTemplateContractDetails>), + pos_key: !state.pos_key + ? !state.pos_algorithm + ? undefined + : i18n.str`required` + : !isBase32RFC3548Charset(state.pos_key) + ? i18n.str`just letters and numbers from 2 to 7` + : state.pos_key.length !== 32 + ? i18n.str`size of the key should be 32` + : undefined, }; const hasErrors = Object.keys(errors).some( @@ -155,20 +178,21 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode { /> <InputSelector<Entity> name="pos_algorithm" - label={i18n.str`Veritifaction algorithm`} + label={i18n.str`Verification algorithm`} tooltip={i18n.str`Algorithm to use to verify transaction in offline mode`} values={algorithms} toStr={(v) => algorithmsNames[v]} - convert={(v) => Number(v)} + fromStr={(v) => Number(v)} /> {state.pos_algorithm && state.pos_algorithm > 0 ? ( <InputWithAddon<Entity> name="pos_key" label={i18n.str`Point-of-sale key`} inputType={showKey ? "text" : "password"} - help="" + help="Be sure to be very hard to guess or use the random generator" expand tooltip={i18n.str`Useful to validate the purchase`} + fromStr={(v) => v.toUpperCase()} addonAfter={ <span class="icon"> {showKey ? ( @@ -179,7 +203,7 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode { </span> } side={ - <span> + <span style={{ display: "flex" }}> <button data-tooltip={i18n.str`generate random secret key`} class="button is-info mr-3" |