[auth] Add endpoint to check passkey status
This commit is contained in:
@@ -42,3 +42,7 @@ class InvalidStateError extends AssertionError {
|
||||
class SrpSetupNotCompleteError extends Error {}
|
||||
|
||||
class AuthenticatorKeyNotFound extends Error {}
|
||||
|
||||
class PassKeySessionNotVerifiedError extends Error {}
|
||||
|
||||
class PassKeySessionExpiredError extends Error {}
|
||||
|
||||
@@ -266,6 +266,31 @@ class UserService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> getTokenForPasskeySession(String sessionID) async {
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
"${_config.getHttpEndpoint()}/users/two-factor/passkeys/get-token",
|
||||
queryParameters: {
|
||||
"sessionID": sessionID,
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
} on DioException catch (e) {
|
||||
if (e.response != null) {
|
||||
if (e.response!.statusCode == 404 || e.response!.statusCode == 410) {
|
||||
throw PassKeySessionExpiredError();
|
||||
}
|
||||
if (e.response!.statusCode == 400) {
|
||||
throw PassKeySessionNotVerifiedError();
|
||||
}
|
||||
}
|
||||
rethrow;
|
||||
} catch (e, s) {
|
||||
_logger.severe("unexpected error", e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onPassKeyVerified(BuildContext context, Map response) async {
|
||||
final ProgressDialog dialog =
|
||||
createProgressDialog(context, context.l10n.pleaseWait);
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:app_links/app_links.dart';
|
||||
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/user_service.dart';
|
||||
@@ -51,6 +52,24 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> checkStatus() async {
|
||||
late dynamic response;
|
||||
try {
|
||||
response = await UserService.instance
|
||||
.getTokenForPasskeySession(widget.sessionID);
|
||||
} on PassKeySessionNotVerifiedError catch (e) {
|
||||
showToast(context, "Verification is still pending.");
|
||||
} on PassKeySessionExpiredError catch (e) {
|
||||
showToast(context, "Passkey session expired. Please try again.");
|
||||
return;
|
||||
} catch (e, s) {
|
||||
_logger.severe("failed to check status", e, s);
|
||||
showGenericErrorDialog(context: context).ignore();
|
||||
return;
|
||||
}
|
||||
await UserService.instance.onPassKeyVerified(context, response);
|
||||
}
|
||||
|
||||
Future<void> _handleDeeplink(String? link) async {
|
||||
if (!context.mounted ||
|
||||
Configuration.instance.hasConfiguredAccount() ||
|
||||
@@ -129,6 +148,13 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
labelText: context.l10n.tryAgain,
|
||||
onTap: () => launchPasskey(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.neutral,
|
||||
labelText: context.l10n.checkForUpdates,
|
||||
onTap: checkStatus,
|
||||
shouldSurfaceExecutionStates: true,
|
||||
),
|
||||
const Padding(padding: EdgeInsets.all(30)),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
|
||||
Reference in New Issue
Block a user