- add AppLogger and replace scattered print logging\n- implement ad-gated recommendation flow with reminder handling and calendar link\n- complete Bluetooth share pipeline with ad gate and merge\n- integrate KMA weather API with caching and dart-define decoding\n- add NaverUrlProcessor refactor and restore restaurant repository tests
56 lines
1.6 KiB
Dart
56 lines
1.6 KiB
Dart
import 'dart:convert';
|
|
|
|
/// ApiKeys는 네이버 API 인증 정보를 환경 변수로 로드한다.
|
|
///
|
|
/// - `NAVER_CLIENT_ID`, `NAVER_CLIENT_SECRET`는 `flutter run`/`flutter test`
|
|
/// 실행 시 `--dart-define`으로 주입한다.
|
|
/// - 민감 정보는 base64(난독화) 형태로 전달하고, 런타임에서 복호화한다.
|
|
class ApiKeys {
|
|
static const String _encodedClientId = String.fromEnvironment(
|
|
'NAVER_CLIENT_ID',
|
|
defaultValue: '',
|
|
);
|
|
static const String _encodedClientSecret = String.fromEnvironment(
|
|
'NAVER_CLIENT_SECRET',
|
|
defaultValue: '',
|
|
);
|
|
|
|
static String get naverClientId => _decodeIfNeeded(_encodedClientId);
|
|
static String get naverClientSecret => _decodeIfNeeded(_encodedClientSecret);
|
|
|
|
static const String _encodedWeatherServiceKey = String.fromEnvironment(
|
|
'KMA_SERVICE_KEY',
|
|
defaultValue: '',
|
|
);
|
|
|
|
static String get weatherServiceKey =>
|
|
_decodeIfNeeded(_encodedWeatherServiceKey);
|
|
|
|
static const String naverLocalSearchEndpoint =
|
|
'https://openapi.naver.com/v1/search/local.json';
|
|
|
|
static bool areKeysConfigured() {
|
|
return naverClientId.isNotEmpty && naverClientSecret.isNotEmpty;
|
|
}
|
|
|
|
/// 배포 스크립트에서 사용할 수 있는 편의 메서드.
|
|
static String obfuscate(String value) {
|
|
if (value.isEmpty) {
|
|
return '';
|
|
}
|
|
return base64.encode(utf8.encode(value));
|
|
}
|
|
|
|
static String _decodeIfNeeded(String value) {
|
|
if (value.isEmpty) {
|
|
return '';
|
|
}
|
|
try {
|
|
return utf8.decode(base64.decode(value));
|
|
} on FormatException {
|
|
// base64가 아니면 일반 문자열로 간주 (로컬 개발 편의용)
|
|
return value;
|
|
}
|
|
}
|
|
}
|