getAccessToken static method

Future<String> getAccessToken()

Fetches an OAuth access token using clientId and clientSecret.

Uses an in-memory caching strategy to avoid redundant network calls. Tokens usually expire in 24 hours.

Implementation

static Future<String> getAccessToken() async {
  // Return cached token if still valid (with 5-minute buffer)
  if (_accessToken != null &&
      _tokenExpiry != null &&
      DateTime.now().isBefore(
        _tokenExpiry!.subtract(const Duration(minutes: 5)),
      )) {
    return _accessToken!;
  }

  try {
    final response = await http.post(
      Uri.parse('$_baseUrl/oauth/token'),
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: {
        'client_id': clientId,
        'client_secret': clientSecret,
        'grant_type': 'client_credentials',
      },
    );

    if (response.statusCode != 200) {
      if (response.statusCode == 401 || response.statusCode == 403) {
        throw PowerMapException(
          code: PowerMapException.auth,
          message:
              'Authentication failed. Please check your Client ID and Secret.',
        );
      }
      throw PowerMapException(
        code: PowerMapException.serverError,
        message: 'Failed to fetch access token: ${response.statusCode}',
        details: response.body,
      );
    }

    final data = json.decode(response.body);
    _accessToken = data['access_token'];
    final expiresIn = data['expires_in'] as int;
    _tokenExpiry = DateTime.now().add(Duration(seconds: expiresIn));

    return _accessToken!;
  } catch (e) {
    if (e is PowerMapException) rethrow;
    throw PowerMapException(
      code: PowerMapException.network,
      message: 'Network error while authenticating.',
      details: e,
    );
  }
}