authorizeDevice static method
Implementation
static Future<AuthorizationResponse> authorizeDevice(
{required DeviceAuthorizationRequest request}) async {
var response = await httpRetry(
() => http.post(
Uri.parse(request.configuration.deviceAuthorizationEndpoint!),
body: request.toMap(),
),
);
if (response == null) throw AuthenticationException(ERROR_INVALID_RESPONSE);
final codeResponse = DeviceCodeResponse.fromJson(response);
await launchUrl(
Uri.parse(codeResponse.verificationUrlComplete).replace(
queryParameters: <String, String>{
"user_code": codeResponse.userCode,
},
),
webViewConfiguration: WebViewConfiguration(
enableJavaScript: true,
),
);
final pollingUri = Uri.parse(request.configuration.tokenEndpoint);
var pollingBody = <String, String>{
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": codeResponse.deviceCode,
"client_id": request.clientId,
if (request.clientSecret != null) "client_secret": request.clientSecret!,
};
late AuthorizationResponse authorizationResponse;
var pollingInterval = codeResponse.pollingInterval;
while (true) {
await Future<void>.delayed(Duration(seconds: pollingInterval));
final pollingResponse = await http.post(pollingUri, body: pollingBody);
final json = jsonDecode(pollingResponse.body) as Map<String, dynamic>;
if (pollingResponse.statusCode >= 200 &&
pollingResponse.statusCode < 300) {
authorizationResponse = AuthorizationResponse.fromJson(json);
break;
}
//Check the error message
final error = json["error"]?.toString();
if (error == null ||
error == "invalid_token" ||
error == "expired_token" ||
error == "access_denied")
throw AuthenticationException(json["error_description"].toString());
if (error == "slow_down") pollingInterval += 2;
if (DateTime.now().isAfter(codeResponse.expiresAt))
throw AuthenticationException(ERROR_USER_CLOSED);
}
return authorizationResponse;
}