mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-03 16:09:35 +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
94
lib/features/onboarding/providers/oauth_provider.dart
Normal file
94
lib/features/onboarding/providers/oauth_provider.dart
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:vaani/api/api_provider.dart';
|
||||
import 'package:vaani/models/error_response.dart';
|
||||
|
||||
import '../models/flow.dart';
|
||||
|
||||
part 'oauth_provider.g.dart';
|
||||
|
||||
/// the string state of a flow started by user
|
||||
typedef State = String;
|
||||
|
||||
/// the verifier string of a flow started by user
|
||||
typedef Verifier = String;
|
||||
|
||||
/// the code returned by the oauth provider
|
||||
typedef Code = String;
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class OauthFlows extends _$OauthFlows {
|
||||
@override
|
||||
Map<State, Flow> build() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void addFlow(
|
||||
State oauthState, {
|
||||
required Verifier verifier,
|
||||
required Uri serverUri,
|
||||
required Cookie cookie,
|
||||
bool replaceExisting = false,
|
||||
}) {
|
||||
if (state.containsKey(oauthState) && !replaceExisting) {
|
||||
return;
|
||||
}
|
||||
state = {
|
||||
...state,
|
||||
oauthState: Flow(
|
||||
state: oauthState,
|
||||
verifier: verifier,
|
||||
serverUri: serverUri,
|
||||
cookie: cookie,
|
||||
isFlowComplete: false,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
void markComplete(State oauthState, String? authToken) {
|
||||
if (!state.containsKey(oauthState)) {
|
||||
return;
|
||||
}
|
||||
state = {
|
||||
...state,
|
||||
oauthState: state[oauthState]!
|
||||
.copyWith(isFlowComplete: true, authToken: authToken),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// the code returned by the server in exchange for the verifier
|
||||
@riverpod
|
||||
Future<String?> loginInExchangeForCode(
|
||||
LoginInExchangeForCodeRef ref, {
|
||||
required State oauthState,
|
||||
required Code code,
|
||||
ErrorResponseHandler? responseHandler,
|
||||
}) async {
|
||||
final flows = ref.watch(oauthFlowsProvider);
|
||||
final flow = flows[oauthState];
|
||||
if (flow == null) {
|
||||
throw StateError('No flow active for state: $oauthState');
|
||||
}
|
||||
|
||||
if (flow.authToken != null) {
|
||||
return flow.authToken;
|
||||
}
|
||||
|
||||
final api = ref.read(audiobookshelfApiProvider(flow.serverUri));
|
||||
final response = await api.server.oauth2Callback(
|
||||
code: code,
|
||||
codeVerifier: flow.verifier,
|
||||
state: oauthState,
|
||||
cookie: flow.cookie,
|
||||
responseErrorHandler: responseHandler?.storeError,
|
||||
);
|
||||
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ref.read(oauthFlowsProvider.notifier).markComplete(oauthState, api.token);
|
||||
return api.token;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue