authenticateWithMagicLink method
Authenticate to this CARP service using an magic link URI generated by CAWS as part of an anonymous access flow.
The magic link can be found inside the .csv file downloaded from the portal.
Implementation
Future<CarpUser> authenticateWithMagicLink(String uri) async {
assert(_manager != null, 'Manager not configured. Call configure() first.');
if (!_manager!.didInit) await initManager();
String? code;
String? clientId = _authProperties?.clientId;
String? redirectUri = _authProperties?.anonymousRedirectURI?.toString();
uri = _constructAuthUri(uri);
TokenResponse tokenResponse =
await FlutterWebAuth2.authenticate(
url: uri,
callbackUrlScheme: redirectUri!.split(':/').first,
options: FlutterWebAuth2Options(
intentFlags: ephemeralIntentFlags,
preferEphemeral: true,
),
).then((result) async {
code = Uri.parse(result).queryParameters['code'];
if ((_currentUser == null || _currentUser!.isAuthenticated) &&
code != null) {
return await FlutterAppAuth().token(
TokenRequest(
clientId!,
redirectUri,
authorizationCode: code,
discoveryUrl: _authProperties?.discoveryURL
.replace(
pathSegments: [
...?_authProperties?.discoveryURL.pathSegments,
'.well-known',
'openid-configuration',
],
)
.toString(),
grantType: 'authorization_code',
),
);
}
return Future.error("No code in redirect URI");
});
_currentUser = getCurrentUserProfileFromTokenResponse(tokenResponse);
final accessToken = tokenResponse.accessToken;
final refreshToken = tokenResponse.refreshToken;
final idToken = tokenResponse.idToken;
final scopeString =
tokenResponse.tokenAdditionalParameters?['scope'] ??
tokenResponse.tokenType;
final scope = (scopeString is String) ? scopeString.split(' ') : <String>[];
final expiresAt =
tokenResponse.accessTokenExpirationDateTime ??
DateTime.now().add(const Duration(hours: 1));
if (_currentUser != null) {
_currentUser!.authenticated(
OAuthToken(
accessToken ?? '',
refreshToken ?? '',
idToken ?? '',
expiresAt,
scope,
idToken ?? '',
),
);
_authEventController.add(AuthEvent.authenticated);
return currentUser;
}
// All other cases are treated as a failed attempt
_authEventController.add(AuthEvent.failed);
throw CarpUnauthorizedException('Authentication failed.');
}