From 8f3fc7414af1fbd95ceddbff0f3c914cee208647 Mon Sep 17 00:00:00 2001 From: lilleman Date: Tue, 18 Aug 2026 22:07:12 +0200 Subject: [PATCH] Hint the code field's digits-only rule, so the browser's refusal isn't bare --- src/auth/flow-view.test.ts | 1 + src/auth/flow-view.ts | 3 ++- src/i18n/locales/en-US.ts | 1 + src/i18n/locales/sv-SE.ts | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/auth/flow-view.test.ts b/src/auth/flow-view.test.ts index 0aa0ec2..7e9aef9 100644 --- a/src/auth/flow-view.test.ts +++ b/src/auth/flow-view.test.ts @@ -113,6 +113,7 @@ test("the code field guards a pasted space: one-time-code autofill + numeric inp ); assert.deepEqual(view.fields.find((f) => f.name === "code"), { autocomplete: "one-time-code", // Kratos sends none for the OTP node — enable OS/email autofill + hint: "Digits only — no spaces.", // the pattern refusal alone reads as a bare "match the requested format" icon: "i-shield", id: "field-code", inputmode: "numeric", diff --git a/src/auth/flow-view.ts b/src/auth/flow-view.ts index 04826cb..8a8d677 100644 --- a/src/auth/flow-view.ts +++ b/src/auth/flow-view.ts @@ -11,6 +11,7 @@ import type { Flow, FlowType, UiNode } from "./kratos-public.ts"; export interface FlowField { autocomplete?: string; error?: { text: string }; + hint?: string; // muted helper text under the input icon?: string; // Lucide sprite id for the input id: string; inputmode?: string; // virtual-keyboard hint (e.g. "numeric" for the OTP code) @@ -139,7 +140,7 @@ function toField(node: UiNode, name: string, type: string, t: Translate): FlowFi ...(autocomplete ? { autocomplete } : {}), ...(errorMsg ? { error: { text: kratosText(t, errorMsg.text, idKey(errorMsg.id)) } } : {}), ...(icon ? { icon } : {}), - ...(isCode ? { inputmode: "numeric", pattern: "[0-9]*" } : {}), + ...(isCode ? { hint: t("auth.field.code.hint"), inputmode: "numeric", pattern: "[0-9]*" } : {}), ...(node.attributes["required"] === true ? { required: true } : {}), ...(value ? { value } : {}), }; diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 1c4bbc7..a1e095b 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -9,6 +9,7 @@ const messages = { "auth.continue": "Continue", // Kratos labels its own form fields; these translate the ones the built-in identity schema uses, // keyed on the input name. A deployment's extra traits keep Kratos' label until a plugin covers them. + "auth.field.code.hint": "Digits only — no spaces.", "auth.field.email": "Email", "auth.field.identifier": "Email", "auth.field.password": "Password", diff --git a/src/i18n/locales/sv-SE.ts b/src/i18n/locales/sv-SE.ts index 0fcd4d3..ff6cdbe 100644 --- a/src/i18n/locales/sv-SE.ts +++ b/src/i18n/locales/sv-SE.ts @@ -2,6 +2,7 @@ import type { CoreMessages } from "./en-US.ts"; const messages: CoreMessages = { "auth.continue": "Fortsätt", + "auth.field.code.hint": "Endast siffror — inga mellanslag.", "auth.field.email": "E-postadress", "auth.field.identifier": "E-postadress", "auth.field.password": "Lösenord",