fix(app): only an otpauth URI is shown as a QR code or opened

The instance sends the URI an authenticator is set up from; one that
isn't otpauth: (a web page, an Android intent) was drawn as a QR code and
handed to the system to open. Now it is neither; the key stays to type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-21 14:50:07 +02:00
commit 5270ce6775
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 64 additions and 3 deletions

View file

@ -18,6 +18,12 @@ final class const AuthenticatorSetup({
required final String id,
required final String uri,
}) with Equatable {
/// Whether [uri] is what an authenticator app opens (`otpauth:`): only
/// then is it shown as a QR code or handed to the system to open, as the
/// instance could send any address (a web page, an intent).
bool get isAuthenticatorUri =>
Uri.tryParse(uri)?.isScheme('otpauth') ?? false;
/// The secret the URI holds, Base32, in groups of four to type by hand.
String get secret {
final raw = Uri.tryParse(uri)?.queryParameters['secret'] ?? '';

View file

@ -550,13 +550,17 @@ class const AuthenticatorSetupView({
Widget build(BuildContext context) {
final l10n = HalkyonAppLocalizations.of(context);
final theme = Theme.of(context);
final phone = Platform.isAndroid || Platform.isIOS;
// Only an otpauth URI is shown as a QR code or opened ([AuthenticatorSetup.isAuthenticatorUri]).
final opens = setup.isAuthenticatorUri;
final phone = opens && (Platform.isAndroid || Platform.isIOS);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SheetIntro(l10n.passwordAuthenticatorIntro),
Center(child: QrCodeView(data: setup.uri)),
const SizedBox(height: 12),
if (opens) ...[
Center(child: QrCodeView(data: setup.uri)),
const SizedBox(height: 12),
],
Text(l10n.passwordAuthenticatorKey, style: theme.textTheme.labelLarge),
const SizedBox(height: 4),
Row(