exchangeCodeForToken method

  1. @override
Future<Map<Object?, Object?>?> exchangeCodeForToken({
  1. required String tenantId,
  2. required String clientId,
  3. String? clientSecret,
  4. required String code,
  5. required String redirectUrl,
  6. String? scope,
})
override

Implementation

@override
Future<Map<Object?, Object?>?> exchangeCodeForToken({
  required String tenantId,
  required String clientId,
  String? clientSecret,
  required String code,
  required String redirectUrl,
  String? scope,
}) async {
  final urlString =
      'https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token';

  final params = <String, String>{
    'client_id': clientId,
    'code': code,
    'redirect_uri': redirectUrl,
    'grant_type': 'authorization_code',
  };

  if (clientSecret != null) {
    params['client_secret'] = clientSecret;
  }
  if (scope != null) {
    params['scope'] = scope;
  }

  final headers = web.Headers();
  headers.append('Content-Type', 'application/x-www-form-urlencoded');

  final bodyContent = params.entries
      .map(
        (e) =>
            '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}',
      )
      .join('&');

  final init = web.RequestInit(
    method: 'POST',
    headers: headers,
    body: bodyContent.toJS,
  );

  try {
    final response = await web.window.fetch(urlString.toJS, init).toDart;
    final textJs = await response.text().toDart;
    final text = textJs.toDart;

    if (response.ok) {
      final Map<String, dynamic> jsonObject = jsonDecode(text);
      return jsonObject;
    } else {
      throw Exception('Response code: ${response.status}, error: $text');
    }
  } catch (e) {
    throw Exception('NETWORK_ERROR: ${e.toString()}');
  }
}