authorize method

  1. @override
Future<OAuthServiceToken?> authorize(
  1. BuildContext context,
  2. OAuthService service, {
  3. required String scope,
  4. bool forceNewTokens = false,
  5. InvokeAPIAction? tokenExchangeAPI,
})
override

Implementation

@override
Future<OAuthServiceToken?> authorize(
    BuildContext context, OAuthService service,
    {required String scope,
    bool forceNewTokens = false,
    InvokeAPIAction? tokenExchangeAPI}) async {
  // see if the tokens already exists
  const storage = FlutterSecureStorage();
  if (!forceNewTokens) {
    String? accessToken =
        await storage.read(key: service.name + accessTokenKey);
    String? refreshToken =
        await storage.read(key: service.name + refreshTokenKey);
    if (accessToken != null) {
      return OAuthServiceToken(
          accessToken: accessToken, refreshToken: refreshToken);
    }
  }

  ServiceCredentialPayload? servicePayload = getServicePayload(service);
  if (servicePayload != null) {
    OAuthCredential? credential =
        servicePayload.credential.platformCredential;
    if (credential == null) {
      throw RuntimeError(
          'OAuth Service is not correctly setup. Please check your configuration');
    }

    String codeVerifier = _generateCodeVerifier();
    String codeChallenge = _generateCodeChallenge(codeVerifier);
    String state = generateState();
    Uri uri = Uri.parse(servicePayload.authorizationURL);
    uri = uri.replace(queryParameters: {
      ...uri.queryParameters,
      ...{
        'response_type': 'code',
        'client_id': credential.clientId,
        'redirect_uri': credential.redirectUri,
        'scope': scope,
        'state': state,
        'code_challenge': codeChallenge,
        'code_challenge_method': 'S256'
      }
    });

    // authorize with the service
    final result = await FlutterWebAuth2.authenticate(
        url: uri.toString(), callbackUrlScheme: credential.redirectScheme);
    final resultUri = Uri.parse(result);
    String? code = resultUri.queryParameters['code'];
    if (code != null && state == resultUri.queryParameters['state']) {
      // code exchange can be on the client or server
      OAuthServiceToken? token;
      if (tokenExchangeAPI == null) {
        token = await _getTokenFromClient(
            code: code,
            codeVerifier: codeVerifier,
            tokenURL: servicePayload.tokenURL,
            service: service,
            oauthCredential: credential);
      } else {
        token = await _getTokenFromServer(context,
            code: code,
            codeVerifier: codeVerifier,
            tokenExchangeAPI: tokenExchangeAPI);
      }
      // only write to storage if accessToken is returned
      if (token != null && token.accessToken != null) {
        await storage.write(
            key: service.name + accessTokenKey, value: token.accessToken);
        if (token.refreshToken != null) {
          await storage.write(
              key: service.name + refreshTokenKey, value: token.refreshToken);
        }
      }
      return token;
    }
  }
  return null;
}