huawei_health_oauth.dart 3.14 KB
import 'dart:convert';
import 'dart:math';

/// Huawei Health Kit OAuth scopes required by DoubleFeel.
abstract final class HuaweiHealthScopes {

  // 步数
  // static const stepRead = 'https://www.huawei.com/healthkit/step.read';

  // 活动小时数
  // static const activeHoursRead = 'https://www.huawei.com/healthkit/activehours.read';

  // 实时心率
  // static const realtimeHeartRead = 'https://www.huawei.com/healthkit/extend/realtimeheart.read';

  // 中高强度
  // static const strengthRead = 'https://www.huawei.com/healthkit/strength.read';

  //低血氧
  // static const oxygenSaturationRead = 'https://www.huawei.com/healthkit/oxygensaturation.read';

  // 日常活动数据
  static const dailyActivitySummaryRead = "https://www.huawei.com/healthkit/dailyactivitysummary.read";
  // Calories
  static const caloriesRead = 'https://www.huawei.com/healthkit/calories.read';
  // 运动目标
  static const goalsRead = "https://www.huawei.com/healthkit/goals.read";
  // 锻炼记录概要
  static const activityRecordRead = "https://www.huawei.com/healthkit/activityrecord.read";
  // 锻炼记录关联的原子采样明细数据权限
  static const activityRead = "https://www.huawei.com/healthkit/activity.read";
  // 心率
  static const heartRateRead = 'https://www.huawei.com/healthkit/heartrate.read';
  // 压力
  static const stressRead = 'https://www.huawei.com/healthkit/stress.read';
  // 睡眠
  static const sleepRead = 'https://www.huawei.com/healthkit/sleep.read';

  // 年数据
  static const historyDataOpenYear = 'https://www.huawei.com/healthkit/historydata.open.year';
  // 手动同步数据
  static const cloudsync = 'https://www.huawei.com/healthkit/huaweihealthdata.cloudsync';

  static const requested = <String>[
    dailyActivitySummaryRead,
    caloriesRead,
    goalsRead,
    activityRecordRead,
    activityRead,
    heartRateRead,
    stressRead,
    sleepRead,
    historyDataOpenYear,
    cloudsync,
    'openid',
    'profile',
  ];
}

/// Builds Huawei Health Kit OAuth authorization URLs in the Flutter layer.
abstract final class HuaweiHealthOAuth {
  static const _clientId = '6917602291754541850';
  static const _redirectUri =
      'https://h5hosting.dbankcdn.com/cch5/healthkit/oauth-h5/oauth-callback.html';
  static final Random _random = Random.secure();

  /// Generates an OAuth state value. Persist and validate it after redirect.
  static String createState() {
    final bytes = List<int>.generate(32, (_) => _random.nextInt(256));
    return base64UrlEncode(bytes).replaceAll('=', '');
  }

  /// Returns the Huawei authorization URL for the configured Health Kit scopes.
  ///
  /// Pass a persisted [state] so the callback can be verified against it.
  static String buildAuthorizationUrl({String? state}) {
    return Uri.https(
      'oauth-login.cloud.huawei.com',
      '/oauth2/v3/authorize',
      <String, String>{
        'client_id': _clientId,
        'response_type': 'code',
        'redirect_uri': _redirectUri,
        'scope': HuaweiHealthScopes.requested.join(' '),
        'state': state ?? createState(),
        'display': 'touch',
        'access_type': 'offline',
      },
    ).toString();
  }
}