mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 07:28:26 +00:00
[auth] Enable login via totp when both passkey & totp are enabled
This commit is contained in:
parent
08160f251a
commit
14fe9bcb72
@ -156,6 +156,7 @@
|
||||
"twoFactorAuthTitle": "Two-factor authentication",
|
||||
"passkeyAuthTitle": "Passkey verification",
|
||||
"verifyPasskey": "Verify passkey",
|
||||
"loginWithTOTP": "Login with TOTP",
|
||||
"recoverAccount": "Recover account",
|
||||
"enterRecoveryKeyHint": "Enter your recovery key",
|
||||
"recover": "Recover",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:ente_auth/core/network.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
@ -24,6 +25,10 @@ class PasskeyService {
|
||||
return response.data!["isPasskeyRecoveryEnabled"] as bool;
|
||||
}
|
||||
|
||||
String get accountsUrl {
|
||||
return kDebugMode ? "http://localhost:3001" : "https://accounts.ente.io";
|
||||
}
|
||||
|
||||
Future<void> configurePasskeyRecovery(
|
||||
String secret,
|
||||
String userEncryptedSecret,
|
||||
@ -42,7 +47,7 @@ class PasskeyService {
|
||||
Future<void> openPasskeyPage(BuildContext context) async {
|
||||
try {
|
||||
final jwtToken = await getJwtToken();
|
||||
final url = "https://accounts.ente.io/passkeys?token=$jwtToken";
|
||||
final url = "$accountsUrl/passkeys?token=$jwtToken";
|
||||
await launchUrlString(
|
||||
url,
|
||||
mode: LaunchMode.externalApplication,
|
||||
|
@ -84,7 +84,7 @@ class UserService {
|
||||
"${_config.getHttpEndpoint()}/users/ott",
|
||||
data: {
|
||||
"email": email,
|
||||
"purpose": isChangeEmail ? "change" : purpose ?? "",
|
||||
"purpose": isChangeEmail ? "change" : purpose ?? "",
|
||||
},
|
||||
);
|
||||
await dialog.hide();
|
||||
@ -379,11 +379,17 @@ class UserService {
|
||||
if (response.statusCode == 200) {
|
||||
Widget page;
|
||||
final String passkeySessionID = response.data["passkeySessionID"];
|
||||
final String twoFASessionID = response.data["twoFactorSessionID"];
|
||||
if (twoFASessionID.isNotEmpty) {
|
||||
String twoFASessionID = response.data["twoFactorSessionID"];
|
||||
if (twoFASessionID.isEmpty) {
|
||||
twoFASessionID = response.data["twoFactorSessionIDV2"];
|
||||
}
|
||||
if (passkeySessionID.isNotEmpty) {
|
||||
page = PasskeyPage(
|
||||
passkeySessionID,
|
||||
totp2FASessionID: twoFASessionID,
|
||||
);
|
||||
} else if (twoFASessionID.isNotEmpty) {
|
||||
page = TwoFactorAuthenticationPage(twoFASessionID);
|
||||
} else if (passkeySessionID.isNotEmpty) {
|
||||
page = PasskeyPage(passkeySessionID);
|
||||
} else {
|
||||
await _saveConfiguration(response);
|
||||
if (Configuration.instance.getEncryptedToken() != null) {
|
||||
@ -685,13 +691,18 @@ class UserService {
|
||||
if (response.statusCode == 200) {
|
||||
Widget? page;
|
||||
final String passkeySessionID = response.data["passkeySessionID"];
|
||||
final String twoFASessionID = response.data["twoFactorSessionID"];
|
||||
String twoFASessionID = response.data["twoFactorSessionID"];
|
||||
if (twoFASessionID.isEmpty) {
|
||||
twoFASessionID = response.data["twoFactorSessionIDV2"];
|
||||
}
|
||||
Configuration.instance.setVolatilePassword(userPassword);
|
||||
|
||||
if (twoFASessionID.isNotEmpty) {
|
||||
if (passkeySessionID.isNotEmpty) {
|
||||
page = PasskeyPage(
|
||||
passkeySessionID,
|
||||
totp2FASessionID: twoFASessionID,
|
||||
);
|
||||
} else if (twoFASessionID.isNotEmpty) {
|
||||
page = TwoFactorAuthenticationPage(twoFASessionID);
|
||||
} else if (passkeySessionID.isNotEmpty) {
|
||||
page = PasskeyPage(passkeySessionID);
|
||||
} else {
|
||||
await _saveConfiguration(response);
|
||||
if (Configuration.instance.getEncryptedToken() != null) {
|
||||
|
@ -5,10 +5,13 @@ import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/core/errors.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/account/two_factor.dart';
|
||||
import 'package:ente_auth/services/passkey_service.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/components/buttons/button_widget.dart';
|
||||
import 'package:ente_auth/ui/components/models/button_type.dart';
|
||||
import 'package:ente_auth/ui/two_factor_authentication_page.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:ente_auth/utils/navigation_util.dart';
|
||||
import 'package:ente_auth/utils/toast_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@ -16,9 +19,11 @@ import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class PasskeyPage extends StatefulWidget {
|
||||
final String sessionID;
|
||||
final String totp2FASessionID;
|
||||
|
||||
const PasskeyPage(
|
||||
this.sessionID, {
|
||||
required this.totp2FASessionID,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@ -42,8 +47,9 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
}
|
||||
|
||||
Future<void> launchPasskey() async {
|
||||
final String accountsUrl = PasskeyService.instance.accountsUrl;
|
||||
await launchUrlString(
|
||||
"https://accounts.ente.io/passkeys/verify?"
|
||||
"$accountsUrl/passkeys/verify?"
|
||||
"passkeySessionID=${widget.sessionID}"
|
||||
"&redirect=enteauth://passkey"
|
||||
"&clientPackage=io.ente.auth",
|
||||
@ -175,6 +181,30 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
shouldSurfaceExecutionStates: true,
|
||||
),
|
||||
const Padding(padding: EdgeInsets.all(30)),
|
||||
if (widget.totp2FASessionID.isNotEmpty)
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
routeToPage(
|
||||
context,
|
||||
TwoFactorAuthenticationPage(
|
||||
widget.totp2FASessionID,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Center(
|
||||
child: Text(
|
||||
context.l10n.loginWithTOTP,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user