commit 8a81f4aa08d607caffcd8b3c2fca21fe9605cb64
parent ec9ede6a90cb49f0d628c14bd60cb4795c78b7d1
Author: Sebastian <sebasjm@taler-systems.com>
Date: Thu, 9 Apr 2026 11:11:09 -0300
better way to handle differant up/low case on taler:// parsing
Diffstat:
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts
@@ -390,6 +390,12 @@ export namespace TalerUris {
* do not check path component format
*/
ignoreComponentError?: boolean;
+ /**
+ * tolerate upper-case on taler:// and
+ * target action.
+ * Userful for user input
+ */
+ ignoreUppercase?: boolean;
}
export type InvalidTargetPathDetail =
@@ -458,9 +464,10 @@ export namespace TalerUris {
> {
// check prefix
let isHttp = false;
+ const prefixCheck = opts.ignoreUppercase ? s.toLowerCase() : s
if (
- !s.startsWith(TALER_PREFIX) &&
- !(isHttp = s.startsWith(TALER_HTTP_PREFIX))
+ !prefixCheck.startsWith(TALER_PREFIX) &&
+ !(isHttp = prefixCheck.startsWith(TALER_HTTP_PREFIX))
) {
return Result.error(TalerUriParseError.WRONG_PREFIX);
}
@@ -473,9 +480,12 @@ export namespace TalerUris {
// check if supported
const firstSlashPos = path.indexOf("/");
- const uriType = (
+ const uriTypeUncased = (
firstSlashPos === -1 ? path : path.slice(0, firstSlashPos)
) as TalerUriAction;
+
+ const uriType = opts.ignoreUppercase ? uriTypeUncased.toLowerCase() as TalerUriAction : uriTypeUncased;
+
if (!supported_targets[uriType]) {
return Result.errorWithDetail(TalerUriParseError.UNSUPPORTED, {
uriType,
diff --git a/packages/taler-wallet-webextension/src/wallet/QrReader.tsx b/packages/taler-wallet-webextension/src/wallet/QrReader.tsx
@@ -353,18 +353,18 @@ export function QrReaderPage({ onDetected }: Props): VNode {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [error, setError] = useState<TranslatedString | undefined>();
const [value, setValue] = useState("");
+ const [uri, setUri] = useState<TalerUris.URI>();
const [show, setShow] = useState<"canvas" | "video" | "nothing">("nothing");
const { i18n } = useTranslationContext();
async function onChangeDetect(str: string) {
+ setValue(str);
if (str) {
- const lstr = str.toLowerCase();
- const uriResp = TalerUris.fromString(lstr);
+ const uriResp = TalerUris.fromString(str, { ignoreUppercase: true });
if (uriResp.tag === "error") {
setError(translateTalerUriError(uriResp, i18n));
- setValue(str);
return;
}
const { value: uri } = uriResp;
@@ -372,32 +372,28 @@ export function QrReaderPage({ onDetected }: Props): VNode {
const errorMsg = await testValidUriDebounced(uri, i18n);
if (errorMsg) {
setError(errorMsg);
- setValue(str);
return;
}
onDetected(uri);
setError(undefined);
- setValue(str);
+ setUri(uri);
} else {
setError(undefined);
- setValue(str);
}
}
function onChange(str: string) {
+ setValue(str);
if (str) {
- const lstr = str.toLowerCase();
- const uriResp = TalerUris.fromString(lstr);
-
+ const uriResp = TalerUris.fromString(str, { ignoreUppercase: true });
if (uriResp.tag === "error") {
setError(translateTalerUriError(uriResp, i18n));
- setValue(str);
return;
}
const { value: uri } = uriResp;
setError(i18n.str`checking...`);
- setValue(str);
+ setUri(uri);
testValidUriDebounced(uri, i18n).then((errorMsg) => {
if (errorMsg) {
setError(errorMsg);
@@ -407,7 +403,6 @@ export function QrReaderPage({ onDetected }: Props): VNode {
});
} else {
setError(undefined);
- setValue(str);
}
}
@@ -458,7 +453,6 @@ export function QrReaderPage({ onDetected }: Props): VNode {
setError(i18n.str`Unexpected error happen reading the file: ${error}`);
}
}
- const uri = Result.orElse(TalerUris.fromString(value), undefined);
return (
<Container>