mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-17 06:49:34 +00:00
feat: add deeplinking support for oauth login
This commit is contained in:
parent
38bad9671d
commit
61aeaf429f
23 changed files with 1310 additions and 343 deletions
116
lib/features/onboarding/view/user_login_with_open_id.dart
Normal file
116
lib/features/onboarding/view/user_login_with_open_id.dart
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shelfsdk/audiobookshelf_api.dart';
|
||||
import 'package:vaani/api/api_provider.dart';
|
||||
import 'package:vaani/features/onboarding/providers/oauth_provider.dart';
|
||||
import 'package:vaani/features/onboarding/view/user_login_with_password.dart';
|
||||
import 'package:vaani/main.dart';
|
||||
import 'package:vaani/models/error_response.dart';
|
||||
import 'package:vaani/router/router.dart';
|
||||
import 'package:vaani/settings/constants.dart';
|
||||
import 'package:vaani/settings/models/models.dart' as model;
|
||||
import 'package:vaani/shared/utils.dart';
|
||||
|
||||
class UserLoginWithOpenID extends HookConsumerWidget {
|
||||
UserLoginWithOpenID({
|
||||
super.key,
|
||||
required this.server,
|
||||
required this.addServer,
|
||||
this.openIDButtonText,
|
||||
});
|
||||
|
||||
final Uri server;
|
||||
final model.AudiobookShelfServer Function() addServer;
|
||||
final String? openIDButtonText;
|
||||
final responseErrorHandler = ErrorResponseHandler(name: 'OpenID');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final serverStatus = ref.watch(serverStatusProvider(server));
|
||||
void openIDLoginFlow() async {
|
||||
appLogger.fine('Clicked Login with OpenID');
|
||||
|
||||
final api = ref.read(audiobookshelfApiProvider(server));
|
||||
final (verifier, challenge) = generateVerifierAndChallenge();
|
||||
|
||||
appLogger.fine('Generated verifier: $verifier\nchallenge: $challenge');
|
||||
final appRedirectUri =
|
||||
'${AppMetadata.appScheme}://${Routes.openIDCallback.fullPath.substring(1)}';
|
||||
final (openIDLoginEndpoint, authCookie) = await api.server.oauth2Request(
|
||||
clientId: AppMetadata.appName,
|
||||
codeChallenge: challenge,
|
||||
// redirectUri: Uri(
|
||||
// scheme: AppMetadata.appScheme,
|
||||
// host: Routes.openIDCallback.path.substring(1),
|
||||
// ).toString(),
|
||||
redirectUri: appRedirectUri,
|
||||
responseErrorHandler: responseErrorHandler.storeError,
|
||||
);
|
||||
|
||||
if (openIDLoginEndpoint == null) {
|
||||
if (responseErrorHandler.response.statusCode == 400 &&
|
||||
responseErrorHandler.response.body
|
||||
.toLowerCase()
|
||||
.contains(RegExp(r'invalid.*redirect.*uri'))) {
|
||||
// show error
|
||||
handleServerError(
|
||||
context,
|
||||
responseErrorHandler,
|
||||
title: 'Failed to get OpenID login endpoint\n',
|
||||
body:
|
||||
'Please check that the redirect URI: "$appRedirectUri" is registered with the server.',
|
||||
outLink: server.replace(path: '${Routes.settings.fullPath}/auth'),
|
||||
outLinkText: 'Server settings',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// show error
|
||||
handleServerError(
|
||||
context,
|
||||
responseErrorHandler,
|
||||
title: 'Failed to get OpenID login endpoint',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// extract the state parameter
|
||||
final oauthState = openIDLoginEndpoint.queryParameters['state'];
|
||||
|
||||
if (oauthState == null) {
|
||||
handleServerError(
|
||||
context,
|
||||
responseErrorHandler,
|
||||
title: 'Failed to get OpenID login endpoint',
|
||||
body: 'No state parameter found in the response',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
appLogger.fine('Got OpenID login endpoint: $openIDLoginEndpoint');
|
||||
|
||||
// add the flow to the provider
|
||||
ref.read(oauthFlowsProvider.notifier).addFlow(
|
||||
oauthState,
|
||||
verifier: verifier,
|
||||
serverUri: server,
|
||||
cookie: Cookie.fromSetCookieValue(authCookie!),
|
||||
);
|
||||
|
||||
await handleLaunchUrl(
|
||||
openIDLoginEndpoint,
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: openIDLoginFlow,
|
||||
child: Text(openIDButtonText ?? 'Login with OpenID'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue