Skip to content

Commit

Permalink
feat: add app redirect for each authenticator option on authenticator…
Browse files Browse the repository at this point in the history
… setup page
  • Loading branch information
ice-ajax committed Jan 15, 2025
1 parent e4eb143 commit 0e40af5
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 14 deletions.
7 changes: 7 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<package android:name="com.google.android.apps.authenticator2" />
<package android:name="com.azure.authenticator" />
<package android:name="com.lastpass.authenticator" />
<package android:name="com.authy.authy" />
<package android:name="com.isdecisions.userlockpush" />
</queries>

<!-- allowBackup:false https://pub.dev/packages/flutter_secure_storage#getting-started -->
Expand Down Expand Up @@ -50,6 +55,8 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.android.camera.CropImage"/>
Expand Down
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ PODS:
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- external_app_launcher (0.0.1):
- Flutter
- ffmpeg-kit-ios-full-gpl (6.0)
- ffmpeg_kit_flutter_full_gpl (6.0.3):
- ffmpeg_kit_flutter_full_gpl/full-gpl (= 6.0.3)
Expand Down Expand Up @@ -225,6 +227,7 @@ DEPENDENCIES:
- BanubaPhotoEditorSDK (= 1.2.5)
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- external_app_launcher (from `.symlinks/plugins/external_app_launcher/ios`)
- ffmpeg_kit_flutter_full_gpl (from `.symlinks/plugins/ffmpeg_kit_flutter_full_gpl/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- file_saver (from `.symlinks/plugins/file_saver/ios`)
Expand Down Expand Up @@ -300,6 +303,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/camera_avfoundation/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
external_app_launcher:
:path: ".symlinks/plugins/external_app_launcher/ios"
ffmpeg_kit_flutter_full_gpl:
:path: ".symlinks/plugins/ffmpeg_kit_flutter_full_gpl/ios"
file_picker:
Expand Down Expand Up @@ -383,6 +388,7 @@ SPEC CHECKSUMS:
device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
external_app_launcher: ad55ac844aa21f2d2197d7cec58ff0d0dc40bbc0
ffmpeg-kit-ios-full-gpl: 80adc341962e55ef709e36baa8ed9a70cf4ea62b
ffmpeg_kit_flutter_full_gpl: ce18b888487c05c46ed252cd2e7956812f2e3bd1
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
Expand Down
5 changes: 5 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
<key>LSApplicationQueriesSchemes</key>
<array>
<string>https</string>
<string>totp</string>
<string>msauthv3</string>
<string>lastpassmfa</string>
<string>authy</string>
<string>userlock</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,62 @@
import 'package:flutter/material.dart';
import 'package:ion/generated/assets.gen.dart';

enum AutethenticatorType {
enum AuthenticatorType {
google,
micsrosoft,
microsoft,
lastpass,
authy,
userLockPush;

String getDisplayName(BuildContext context) {
return switch (this) {
AutethenticatorType.google => 'Google Authenticator',
AutethenticatorType.micsrosoft => 'Microsoft Authenticator',
AutethenticatorType.lastpass => 'LastPass Authenticator',
AutethenticatorType.authy => 'Authy',
AutethenticatorType.userLockPush => 'UserLock Push',
AuthenticatorType.google => 'Google Authenticator',
AuthenticatorType.microsoft => 'Microsoft Authenticator',
AuthenticatorType.lastpass => 'LastPass Authenticator',
AuthenticatorType.authy => 'Authy',
AuthenticatorType.userLockPush => 'UserLock Push',
};
}

String get iconAsset {
return switch (this) {
AutethenticatorType.google => Assets.svg.icon2faGoogleauth,
AutethenticatorType.micsrosoft => Assets.svg.icon2famicrosoft,
AutethenticatorType.lastpass => Assets.svg.icon2faLastpass,
AutethenticatorType.authy => Assets.svg.icon2faAuthy,
AutethenticatorType.userLockPush => Assets.svg.icon2faUserlock,
AuthenticatorType.google => Assets.svg.icon2faGoogleauth,
AuthenticatorType.microsoft => Assets.svg.icon2famicrosoft,
AuthenticatorType.lastpass => Assets.svg.icon2faLastpass,
AuthenticatorType.authy => Assets.svg.icon2faAuthy,
AuthenticatorType.userLockPush => Assets.svg.icon2faUserlock,
};
}

String get androidPackageName {
return switch (this) {
AuthenticatorType.google => 'com.google.android.apps.authenticator2',
AuthenticatorType.microsoft => 'com.azure.authenticator',
AuthenticatorType.lastpass => 'com.lastpass.authenticator',
AuthenticatorType.authy => 'com.authy.authy',
AuthenticatorType.userLockPush => 'com.isdecisions.userlockpush',
};
}

String get iosAppUrlScheme {
return switch (this) {
AuthenticatorType.google => 'totp://',
AuthenticatorType.microsoft => 'msauthv3://',
AuthenticatorType.lastpass => 'lastpassmfa://',
AuthenticatorType.authy => 'authy://',
AuthenticatorType.userLockPush => 'userlock://',
};
}

String get appStoreLink {
return switch (this) {
AuthenticatorType.google => 'https://apps.apple.com/us/app/google-authenticator/id388497605',
AuthenticatorType.microsoft =>
'https://apps.apple.com/us/app/microsoft-authenticator/id983156458',
AuthenticatorType.lastpass =>
'https://apps.apple.com/us/app/lastpass-authenticator/id1079110004',
AuthenticatorType.authy => 'https://apps.apple.com/us/app/authy/id494168017',
AuthenticatorType.userLockPush => 'https://apps.apple.com/us/app/userlock-push/id1633085926',
};
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// SPDX-License-Identifier: ice License 1.0

import 'dart:io';

import 'package:external_app_launcher/external_app_launcher.dart';
import 'package:flutter/material.dart';
import 'package:ion/app/components/button/button.dart';
import 'package:ion/app/components/screen_offset/screen_bottom_offset.dart';
Expand All @@ -15,6 +18,7 @@ import 'package:ion/app/router/components/navigation_app_bar/navigation_app_bar.
import 'package:ion/app/router/components/navigation_app_bar/navigation_close_button.dart';
import 'package:ion/app/router/components/sheet_content/sheet_content.dart';
import 'package:ion/generated/assets.gen.dart';
import 'package:url_launcher/url_launcher.dart';

class AuthenticatorSetupOptionsPage extends StatelessWidget {
const AuthenticatorSetupOptionsPage({
Expand All @@ -23,7 +27,7 @@ class AuthenticatorSetupOptionsPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
const authenticatorTypes = AutethenticatorType.values;
const authenticatorTypes = AuthenticatorType.values;

return SheetContent(
body: CustomScrollView(
Expand Down Expand Up @@ -69,7 +73,7 @@ class AuthenticatorSetupOptionsPage extends StatelessWidget {
isEnabled: false,
title: type.getDisplayName(context),
icon: type.iconAsset.icon(),
onTap: () {},
onTap: () => _onOptionTap(type),
),
);
},
Expand All @@ -95,4 +99,22 @@ class AuthenticatorSetupOptionsPage extends StatelessWidget {
),
);
}

Future<void> _onOptionTap(AuthenticatorType type) async {
// LaunchApp currently doesn't work on iOS because of a bug
// https://github.com/GeekyAnts/external_app_launcher/issues/41
// TODO: Replace canLaunch and launchUrl with LaunchApp.openApp when library is fixed
if (Platform.isAndroid) {
await LaunchApp.openApp(
androidPackageName: type.androidPackageName,
);
} else {
final canLaunch = await canLaunchUrl(Uri.parse(type.iosAppUrlScheme));
if (canLaunch) {
await launchUrl(Uri.parse(type.iosAppUrlScheme));
} else {
await launchUrl(Uri.parse(type.appStoreLink));
}
}
}
}
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "12.0.0"
external_app_launcher:
dependency: "direct main"
description:
name: external_app_launcher
sha256: "69d843ae16598cbf86be8d65ae5f206bb403fbfb75ca9aaaa9ea91b15b040571"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
fake_async:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies:
email_validator: ^3.0.0
es_compression: ^2.0.13
extended_text: ^14.1.0
external_app_launcher: ^4.0.1
ffmpeg_kit_flutter_full_gpl: ^6.0.3
ffmpeg_wasm: ^1.0.3
file: ^7.0.1
Expand Down

0 comments on commit 0e40af5

Please sign in to comment.