Move external secrets behind auth broker
This commit is contained in:
@@ -33,6 +33,11 @@ Thumbs.db
|
|||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
secrets/
|
||||||
|
logs/
|
||||||
|
temp/
|
||||||
|
.tmp/
|
||||||
|
backups/
|
||||||
|
|
||||||
# Local Android/ADB state
|
# Local Android/ADB state
|
||||||
.android-adb/
|
.android-adb/
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ class AppEnvironment {
|
|||||||
required this.organizationApiBaseUrl,
|
required this.organizationApiBaseUrl,
|
||||||
required this.orgContextApiBaseUrl,
|
required this.orgContextApiBaseUrl,
|
||||||
required this.orgContextTenantSlug,
|
required this.orgContextTenantSlug,
|
||||||
required this.baronKeyId,
|
|
||||||
required this.baronKeySecret,
|
|
||||||
required this.appVersion,
|
required this.appVersion,
|
||||||
required this.buildTimestamp,
|
required this.buildTimestamp,
|
||||||
});
|
});
|
||||||
@@ -43,15 +41,6 @@ class AppEnvironment {
|
|||||||
'TDC114_ORG_CONTEXT_TENANT_SLUG',
|
'TDC114_ORG_CONTEXT_TENANT_SLUG',
|
||||||
defaultValue: 'hanmac-family',
|
defaultValue: 'hanmac-family',
|
||||||
);
|
);
|
||||||
const baronKeyId = String.fromEnvironment(
|
|
||||||
'TDC114_BARON_KEY_ID',
|
|
||||||
defaultValue: '',
|
|
||||||
);
|
|
||||||
const baronKeySecret = String.fromEnvironment(
|
|
||||||
'TDC114_BARON_KEY_SECRET',
|
|
||||||
defaultValue: '',
|
|
||||||
);
|
|
||||||
|
|
||||||
return AppEnvironment(
|
return AppEnvironment(
|
||||||
ssoBaseUrl: ssoBaseUrl,
|
ssoBaseUrl: ssoBaseUrl,
|
||||||
apiBaseUrl: sharedApiBaseUrl,
|
apiBaseUrl: sharedApiBaseUrl,
|
||||||
@@ -70,8 +59,6 @@ class AppEnvironment {
|
|||||||
: organizationApiBaseOverride)
|
: organizationApiBaseOverride)
|
||||||
: orgContextApiBaseOverride,
|
: orgContextApiBaseOverride,
|
||||||
orgContextTenantSlug: orgContextTenantSlug,
|
orgContextTenantSlug: orgContextTenantSlug,
|
||||||
baronKeyId: baronKeyId,
|
|
||||||
baronKeySecret: baronKeySecret,
|
|
||||||
appVersion: const String.fromEnvironment(
|
appVersion: const String.fromEnvironment(
|
||||||
'APP_VERSION',
|
'APP_VERSION',
|
||||||
defaultValue: '0.1.0',
|
defaultValue: '0.1.0',
|
||||||
@@ -90,8 +77,6 @@ class AppEnvironment {
|
|||||||
final String organizationApiBaseUrl;
|
final String organizationApiBaseUrl;
|
||||||
final String orgContextApiBaseUrl;
|
final String orgContextApiBaseUrl;
|
||||||
final String orgContextTenantSlug;
|
final String orgContextTenantSlug;
|
||||||
final String baronKeyId;
|
|
||||||
final String baronKeySecret;
|
|
||||||
final String appVersion;
|
final String appVersion;
|
||||||
final String buildTimestamp;
|
final String buildTimestamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ class AuthSessionStore {
|
|||||||
static const _tokenKey = 'tdc114plus.auth.token';
|
static const _tokenKey = 'tdc114plus.auth.token';
|
||||||
static const _expiresAtKey = 'tdc114plus.auth.expiresAt';
|
static const _expiresAtKey = 'tdc114plus.auth.expiresAt';
|
||||||
static const _userKey = 'tdc114plus.auth.user';
|
static const _userKey = 'tdc114plus.auth.user';
|
||||||
static const _orgContextCredentialKey =
|
|
||||||
'tdc114plus.auth.orgContextCredential';
|
|
||||||
static const _pendingRefKey = 'tdc114plus.auth.pending.ref';
|
static const _pendingRefKey = 'tdc114plus.auth.pending.ref';
|
||||||
static const _pendingExpiresAtKey = 'tdc114plus.auth.pending.expiresAt';
|
static const _pendingExpiresAtKey = 'tdc114plus.auth.pending.expiresAt';
|
||||||
static const _pendingResendAfterAtKey =
|
static const _pendingResendAfterAtKey =
|
||||||
@@ -30,17 +28,8 @@ class AuthSessionStore {
|
|||||||
response.expiresAt.toUtc().toIso8601String(),
|
response.expiresAt.toUtc().toIso8601String(),
|
||||||
);
|
);
|
||||||
await prefs.setString(_userKey, jsonEncode(response.user.toJson()));
|
await prefs.setString(_userKey, jsonEncode(response.user.toJson()));
|
||||||
final orgContextCredential = response.orgContextCredential;
|
|
||||||
if (orgContextCredential == null) {
|
|
||||||
await prefs.remove(_orgContextCredentialKey);
|
|
||||||
} else {
|
|
||||||
await prefs.setString(
|
|
||||||
_orgContextCredentialKey,
|
|
||||||
jsonEncode(orgContextCredential.toJson()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'AuthSessionStore.save token=${response.token} tokenLength=${response.token.length} expiresAt=${response.expiresAt.toUtc().toIso8601String()} orgContextCredential=${orgContextCredential != null}',
|
'AuthSessionStore.save token=${response.token} tokenLength=${response.token.length} expiresAt=${response.expiresAt.toUtc().toIso8601String()}',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +102,6 @@ class AuthSessionStore {
|
|||||||
final token = prefs.getString(_tokenKey);
|
final token = prefs.getString(_tokenKey);
|
||||||
final expiresAtValue = prefs.getString(_expiresAtKey);
|
final expiresAtValue = prefs.getString(_expiresAtKey);
|
||||||
final userValue = prefs.getString(_userKey);
|
final userValue = prefs.getString(_userKey);
|
||||||
final orgContextCredentialValue = prefs.getString(_orgContextCredentialKey);
|
|
||||||
if (token == null || expiresAtValue == null || userValue == null) {
|
if (token == null || expiresAtValue == null || userValue == null) {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'AuthSessionStore.load missing token=${token != null} expiresAt=${expiresAtValue != null} user=${userValue != null}',
|
'AuthSessionStore.load missing token=${token != null} expiresAt=${expiresAtValue != null} user=${userValue != null}',
|
||||||
@@ -124,12 +112,9 @@ class AuthSessionStore {
|
|||||||
token: token,
|
token: token,
|
||||||
expiresAt: DateTime.parse(expiresAtValue),
|
expiresAt: DateTime.parse(expiresAtValue),
|
||||||
user: LoginUser.fromJson(jsonDecode(userValue) as Map<String, dynamic>),
|
user: LoginUser.fromJson(jsonDecode(userValue) as Map<String, dynamic>),
|
||||||
orgContextCredential: _decodeOrgContextCredential(
|
|
||||||
orgContextCredentialValue,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'AuthSessionStore.load token=${session.token} tokenLength=${session.token.length} expiresAt=${session.expiresAt.toUtc().toIso8601String()} expired=${session.isExpired} orgContextCredential=${session.orgContextCredential != null}',
|
'AuthSessionStore.load token=${session.token} tokenLength=${session.token.length} expiresAt=${session.expiresAt.toUtc().toIso8601String()} expired=${session.isExpired}',
|
||||||
);
|
);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
@@ -139,22 +124,9 @@ class AuthSessionStore {
|
|||||||
await prefs.remove(_tokenKey);
|
await prefs.remove(_tokenKey);
|
||||||
await prefs.remove(_expiresAtKey);
|
await prefs.remove(_expiresAtKey);
|
||||||
await prefs.remove(_userKey);
|
await prefs.remove(_userKey);
|
||||||
await prefs.remove(_orgContextCredentialKey);
|
|
||||||
await clearPendingLink();
|
await clearPendingLink();
|
||||||
debugPrint('AuthSessionStore.clear');
|
debugPrint('AuthSessionStore.clear');
|
||||||
}
|
}
|
||||||
|
|
||||||
OrgContextCredential? _decodeOrgContextCredential(String? value) {
|
|
||||||
if (value == null || value.trim().isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return OrgContextCredential.fromJsonOrNull(jsonDecode(value));
|
|
||||||
} catch (_) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StoredAuthSession {
|
class StoredAuthSession {
|
||||||
@@ -162,13 +134,11 @@ class StoredAuthSession {
|
|||||||
required this.token,
|
required this.token,
|
||||||
required this.expiresAt,
|
required this.expiresAt,
|
||||||
required this.user,
|
required this.user,
|
||||||
this.orgContextCredential,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final String token;
|
final String token;
|
||||||
final DateTime expiresAt;
|
final DateTime expiresAt;
|
||||||
final LoginUser user;
|
final LoginUser user;
|
||||||
final OrgContextCredential? orgContextCredential;
|
|
||||||
|
|
||||||
bool get isExpired => !expiresAt.isAfter(DateTime.now().toUtc());
|
bool get isExpired => !expiresAt.isAfter(DateTime.now().toUtc());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,14 +101,12 @@ class PhoneLoginResponse {
|
|||||||
required this.token,
|
required this.token,
|
||||||
required this.expiresAt,
|
required this.expiresAt,
|
||||||
required this.user,
|
required this.user,
|
||||||
this.orgContextCredential,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final String status;
|
final String status;
|
||||||
final String token;
|
final String token;
|
||||||
final DateTime expiresAt;
|
final DateTime expiresAt;
|
||||||
final LoginUser user;
|
final LoginUser user;
|
||||||
final OrgContextCredential? orgContextCredential;
|
|
||||||
|
|
||||||
factory PhoneLoginResponse.fromJson(Map<String, dynamic> json) {
|
factory PhoneLoginResponse.fromJson(Map<String, dynamic> json) {
|
||||||
return PhoneLoginResponse(
|
return PhoneLoginResponse(
|
||||||
@@ -116,9 +114,6 @@ class PhoneLoginResponse {
|
|||||||
token: json['token'] as String? ?? json['accessToken'] as String? ?? '',
|
token: json['token'] as String? ?? json['accessToken'] as String? ?? '',
|
||||||
expiresAt: DateTime.parse(json['expiresAt'] as String),
|
expiresAt: DateTime.parse(json['expiresAt'] as String),
|
||||||
user: LoginUser.fromJson(json['user'] as Map<String, dynamic>? ?? {}),
|
user: LoginUser.fromJson(json['user'] as Map<String, dynamic>? ?? {}),
|
||||||
orgContextCredential: OrgContextCredential.fromJsonOrNull(
|
|
||||||
json['orgContextCredential'] ?? json['org_context'],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,83 +123,10 @@ class PhoneLoginResponse {
|
|||||||
'token': token,
|
'token': token,
|
||||||
'expiresAt': expiresAt.toUtc().toIso8601String(),
|
'expiresAt': expiresAt.toUtc().toIso8601String(),
|
||||||
'user': user.toJson(),
|
'user': user.toJson(),
|
||||||
if (orgContextCredential != null)
|
|
||||||
'orgContextCredential': orgContextCredential!.toJson(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OrgContextCredential {
|
|
||||||
const OrgContextCredential({
|
|
||||||
required this.baseUrl,
|
|
||||||
required this.tenantSlug,
|
|
||||||
required this.keyId,
|
|
||||||
required this.keySecret,
|
|
||||||
this.expiresAt,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String baseUrl;
|
|
||||||
final String tenantSlug;
|
|
||||||
final String keyId;
|
|
||||||
final String keySecret;
|
|
||||||
final DateTime? expiresAt;
|
|
||||||
|
|
||||||
bool get isUsable {
|
|
||||||
return baseUrl.trim().isNotEmpty &&
|
|
||||||
tenantSlug.trim().isNotEmpty &&
|
|
||||||
keyId.trim().isNotEmpty &&
|
|
||||||
keySecret.trim().isNotEmpty &&
|
|
||||||
(expiresAt == null || expiresAt!.isAfter(DateTime.now().toUtc()));
|
|
||||||
}
|
|
||||||
|
|
||||||
factory OrgContextCredential.fromJson(Map<String, dynamic> json) {
|
|
||||||
return OrgContextCredential(
|
|
||||||
baseUrl: _readString(json, const ['baseUrl', 'base_url']),
|
|
||||||
tenantSlug: _readString(json, const ['tenantSlug', 'tenant_slug']),
|
|
||||||
keyId: _readString(json, const ['keyId', 'key_id']),
|
|
||||||
keySecret: _readString(json, const ['keySecret', 'key_secret']),
|
|
||||||
expiresAt: _readDate(json['expiresAt'] ?? json['expires_at']),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static OrgContextCredential? fromJsonOrNull(Object? value) {
|
|
||||||
if (value is! Map) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final credential = OrgContextCredential.fromJson(
|
|
||||||
Map<String, dynamic>.from(value),
|
|
||||||
);
|
|
||||||
return credential.isUsable ? credential : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
'baseUrl': baseUrl,
|
|
||||||
'tenantSlug': tenantSlug,
|
|
||||||
'keyId': keyId,
|
|
||||||
'keySecret': keySecret,
|
|
||||||
if (expiresAt != null) 'expiresAt': expiresAt!.toUtc().toIso8601String(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _readString(Map<String, dynamic> json, List<String> keys) {
|
|
||||||
for (final key in keys) {
|
|
||||||
final value = json[key];
|
|
||||||
if (value is String && value.trim().isNotEmpty) {
|
|
||||||
return value.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
static DateTime? _readDate(Object? value) {
|
|
||||||
if (value is! String || value.trim().isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return DateTime.tryParse(value)?.toUtc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PhoneLoginLinkInitRequest {
|
class PhoneLoginLinkInitRequest {
|
||||||
const PhoneLoginLinkInitRequest({
|
const PhoneLoginLinkInitRequest({
|
||||||
required this.phoneNumber,
|
required this.phoneNumber,
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ class OrgContextApiClient {
|
|||||||
const OrgContextApiClient({
|
const OrgContextApiClient({
|
||||||
required this.httpClient,
|
required this.httpClient,
|
||||||
required this.baseUri,
|
required this.baseUri,
|
||||||
required this.keyId,
|
|
||||||
required this.keySecret,
|
|
||||||
required this.tenantSlug,
|
required this.tenantSlug,
|
||||||
this.sessionStore,
|
this.sessionStore,
|
||||||
this.timeout = const Duration(seconds: 15),
|
this.timeout = const Duration(seconds: 15),
|
||||||
@@ -28,8 +26,6 @@ class OrgContextApiClient {
|
|||||||
|
|
||||||
final http.Client httpClient;
|
final http.Client httpClient;
|
||||||
final Uri baseUri;
|
final Uri baseUri;
|
||||||
final String keyId;
|
|
||||||
final String keySecret;
|
|
||||||
final String tenantSlug;
|
final String tenantSlug;
|
||||||
final AuthSessionStore? sessionStore;
|
final AuthSessionStore? sessionStore;
|
||||||
final Duration timeout;
|
final Duration timeout;
|
||||||
@@ -91,27 +87,13 @@ class OrgContextApiClient {
|
|||||||
String? tenantSlug,
|
String? tenantSlug,
|
||||||
}) async {
|
}) async {
|
||||||
final session = await _session();
|
final session = await _session();
|
||||||
final sessionCredential = session?.orgContextCredential;
|
|
||||||
final requestedTenantSlug = tenantSlug?.trim();
|
final requestedTenantSlug = tenantSlug?.trim();
|
||||||
if (sessionCredential != null && sessionCredential.isUsable) {
|
|
||||||
return _OrgContextCredentialSnapshot(
|
|
||||||
baseUri: Uri.parse(sessionCredential.baseUrl),
|
|
||||||
tenantSlug: requestedTenantSlug == null || requestedTenantSlug.isEmpty
|
|
||||||
? sessionCredential.tenantSlug
|
|
||||||
: requestedTenantSlug,
|
|
||||||
keyId: sessionCredential.keyId,
|
|
||||||
keySecret: sessionCredential.keySecret,
|
|
||||||
appSessionToken: session?.token ?? '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _OrgContextCredentialSnapshot(
|
return _OrgContextCredentialSnapshot(
|
||||||
baseUri: baseUri,
|
baseUri: baseUri,
|
||||||
tenantSlug: requestedTenantSlug == null || requestedTenantSlug.isEmpty
|
tenantSlug: requestedTenantSlug == null || requestedTenantSlug.isEmpty
|
||||||
? this.tenantSlug
|
? this.tenantSlug
|
||||||
: requestedTenantSlug,
|
: requestedTenantSlug,
|
||||||
keyId: keyId,
|
|
||||||
keySecret: keySecret,
|
|
||||||
appSessionToken: session?.token ?? '',
|
appSessionToken: session?.token ?? '',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -141,10 +123,6 @@ class OrgContextApiClient {
|
|||||||
'accept': 'application/json',
|
'accept': 'application/json',
|
||||||
if (appSessionToken.isNotEmpty) 'Authorization': 'Bearer $appSessionToken',
|
if (appSessionToken.isNotEmpty) 'Authorization': 'Bearer $appSessionToken',
|
||||||
if (appSessionToken.isNotEmpty) 'X-App-Session': appSessionToken,
|
if (appSessionToken.isNotEmpty) 'X-App-Session': appSessionToken,
|
||||||
if (credential.keyId.trim().isNotEmpty)
|
|
||||||
'X-Baron-Key-ID': credential.keyId.trim(),
|
|
||||||
if (credential.keySecret.trim().isNotEmpty)
|
|
||||||
'X-Baron-Key-Secret': credential.keySecret.trim(),
|
|
||||||
};
|
};
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'OrgContextApiClient._headers headers=$headers tenantSlug=${credential.tenantSlug} base=${credential.baseUri}',
|
'OrgContextApiClient._headers headers=$headers tenantSlug=${credential.tenantSlug} base=${credential.baseUri}',
|
||||||
@@ -458,8 +436,6 @@ final orgContextApiClientProvider = Provider<OrgContextApiClient>((ref) {
|
|||||||
return OrgContextApiClient(
|
return OrgContextApiClient(
|
||||||
httpClient: ref.watch(httpClientProvider),
|
httpClient: ref.watch(httpClientProvider),
|
||||||
baseUri: Uri.parse(environment.orgContextApiBaseUrl),
|
baseUri: Uri.parse(environment.orgContextApiBaseUrl),
|
||||||
keyId: environment.baronKeyId,
|
|
||||||
keySecret: environment.baronKeySecret,
|
|
||||||
tenantSlug: environment.orgContextTenantSlug,
|
tenantSlug: environment.orgContextTenantSlug,
|
||||||
sessionStore: ref.watch(authSessionStoreProvider),
|
sessionStore: ref.watch(authSessionStoreProvider),
|
||||||
);
|
);
|
||||||
@@ -475,22 +451,18 @@ class _OrgContextCredentialSnapshot {
|
|||||||
const _OrgContextCredentialSnapshot({
|
const _OrgContextCredentialSnapshot({
|
||||||
required this.baseUri,
|
required this.baseUri,
|
||||||
required this.tenantSlug,
|
required this.tenantSlug,
|
||||||
required this.keyId,
|
|
||||||
required this.keySecret,
|
|
||||||
required this.appSessionToken,
|
required this.appSessionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Uri baseUri;
|
final Uri baseUri;
|
||||||
final String tenantSlug;
|
final String tenantSlug;
|
||||||
final String keyId;
|
|
||||||
final String keySecret;
|
|
||||||
final String appSessionToken;
|
final String appSessionToken;
|
||||||
|
|
||||||
String get cacheKey {
|
String get cacheKey {
|
||||||
return [
|
return [
|
||||||
baseUri.toString(),
|
baseUri.toString(),
|
||||||
tenantSlug,
|
tenantSlug,
|
||||||
appSessionToken.isEmpty ? keyId : appSessionToken,
|
appSessionToken,
|
||||||
].join('|');
|
].join('|');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,6 @@ void main() {
|
|||||||
tenantName: 'Hanmac',
|
tenantName: 'Hanmac',
|
||||||
tenantSlug: 'hanmac',
|
tenantSlug: 'hanmac',
|
||||||
),
|
),
|
||||||
orgContextCredential: OrgContextCredential(
|
|
||||||
baseUrl: 'https://sadmin.hmac.kr',
|
|
||||||
tenantSlug: 'hanmac-family',
|
|
||||||
keyId: 'session-key-id',
|
|
||||||
keySecret: 'session-key-secret',
|
|
||||||
expiresAt: DateTime.parse('2099-07-02T13:00:00Z'),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await store.save(response);
|
await store.save(response);
|
||||||
@@ -36,8 +29,6 @@ void main() {
|
|||||||
|
|
||||||
expect(loaded?.token, 'session-token');
|
expect(loaded?.token, 'session-token');
|
||||||
expect(loaded?.user.name, 'User One');
|
expect(loaded?.user.name, 'User One');
|
||||||
expect(loaded?.orgContextCredential?.keyId, 'session-key-id');
|
|
||||||
expect(loaded?.orgContextCredential?.keySecret, 'session-key-secret');
|
|
||||||
|
|
||||||
await store.clear();
|
await store.clear();
|
||||||
expect(await store.load(), isNull);
|
expect(await store.load(), isNull);
|
||||||
|
|||||||
@@ -22,14 +22,12 @@ void main() {
|
|||||||
expect(request.url.queryParameters['tenantSlug'], 'hanmac-family');
|
expect(request.url.queryParameters['tenantSlug'], 'hanmac-family');
|
||||||
expect(request.url.queryParameters['includeUsers'], 'true');
|
expect(request.url.queryParameters['includeUsers'], 'true');
|
||||||
expect(request.url.queryParameters['includeUserIds'], 'true');
|
expect(request.url.queryParameters['includeUserIds'], 'true');
|
||||||
expect(request.headers['X-Baron-Key-ID'], 'key-id');
|
expect(request.headers.containsKey('X-Baron-Key-ID'), isFalse);
|
||||||
expect(request.headers['X-Baron-Key-Secret'], 'key-secret');
|
expect(request.headers.containsKey('X-Baron-Key-Secret'), isFalse);
|
||||||
|
|
||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
||||||
keyId: 'key-id',
|
|
||||||
keySecret: 'key-secret',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -49,7 +47,7 @@ void main() {
|
|||||||
expect(is3.totalMemberCount, 2);
|
expect(is3.totalMemberCount, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('uses session org-context credential before env fallback', () async {
|
test('does not persist or send session org-context credentials', () async {
|
||||||
const store = AuthSessionStore();
|
const store = AuthSessionStore();
|
||||||
await store.save(
|
await store.save(
|
||||||
PhoneLoginResponse(
|
PhoneLoginResponse(
|
||||||
@@ -64,27 +62,19 @@ void main() {
|
|||||||
tenantName: '',
|
tenantName: '',
|
||||||
tenantSlug: '',
|
tenantSlug: '',
|
||||||
),
|
),
|
||||||
orgContextCredential: const OrgContextCredential(
|
|
||||||
baseUrl: 'https://session.example.test',
|
|
||||||
tenantSlug: 'session-family',
|
|
||||||
keyId: 'session-key-id',
|
|
||||||
keySecret: 'session-key-secret',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final client = OrgContextApiClient(
|
final client = OrgContextApiClient(
|
||||||
httpClient: MockClient((request) async {
|
httpClient: MockClient((request) async {
|
||||||
expect(request.url.host, 'session.example.test');
|
expect(request.url.host, 'env.example.test');
|
||||||
expect(request.url.queryParameters['tenantSlug'], 'session-family');
|
expect(request.url.queryParameters['tenantSlug'], 'env-family');
|
||||||
expect(request.headers['Authorization'], 'Bearer session-token');
|
expect(request.headers['Authorization'], 'Bearer session-token');
|
||||||
expect(request.headers['X-Baron-Key-ID'], 'session-key-id');
|
expect(request.headers.containsKey('X-Baron-Key-ID'), isFalse);
|
||||||
expect(request.headers['X-Baron-Key-Secret'], 'session-key-secret');
|
expect(request.headers.containsKey('X-Baron-Key-Secret'), isFalse);
|
||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://env.example.test'),
|
baseUri: Uri.parse('https://env.example.test'),
|
||||||
keyId: 'env-key-id',
|
|
||||||
keySecret: 'env-key-secret',
|
|
||||||
tenantSlug: 'env-family',
|
tenantSlug: 'env-family',
|
||||||
sessionStore: store,
|
sessionStore: store,
|
||||||
);
|
);
|
||||||
@@ -99,8 +89,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
||||||
keyId: 'key-id',
|
|
||||||
keySecret: 'key-secret',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -115,8 +103,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://114-auth.hmac.kr'),
|
baseUri: Uri.parse('https://114-auth.hmac.kr'),
|
||||||
keyId: '',
|
|
||||||
keySecret: '',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -155,8 +141,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://114-auth.hmac.kr'),
|
baseUri: Uri.parse('https://114-auth.hmac.kr'),
|
||||||
keyId: '',
|
|
||||||
keySecret: '',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
sessionStore: store,
|
sessionStore: store,
|
||||||
);
|
);
|
||||||
@@ -173,8 +157,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://114-auth.hmac.kr'),
|
baseUri: Uri.parse('https://114-auth.hmac.kr'),
|
||||||
keyId: '',
|
|
||||||
keySecret: '',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -184,27 +166,22 @@ void main() {
|
|||||||
expect(requestCount, 1);
|
expect(requestCount, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test('uses configured auth-server org-context endpoint without Baron key headers', () async {
|
||||||
'falls back to env org-context credential without session credential',
|
|
||||||
() async {
|
|
||||||
final client = OrgContextApiClient(
|
final client = OrgContextApiClient(
|
||||||
httpClient: MockClient((request) async {
|
httpClient: MockClient((request) async {
|
||||||
expect(request.url.host, 'env.example.test');
|
expect(request.url.host, 'env.example.test');
|
||||||
expect(request.url.queryParameters['tenantSlug'], 'env-family');
|
expect(request.url.queryParameters['tenantSlug'], 'env-family');
|
||||||
expect(request.headers['X-Baron-Key-ID'], 'env-key-id');
|
expect(request.headers.containsKey('X-Baron-Key-ID'), isFalse);
|
||||||
expect(request.headers['X-Baron-Key-Secret'], 'env-key-secret');
|
expect(request.headers.containsKey('X-Baron-Key-Secret'), isFalse);
|
||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://env.example.test'),
|
baseUri: Uri.parse('https://env.example.test'),
|
||||||
keyId: 'env-key-id',
|
|
||||||
keySecret: 'env-key-secret',
|
|
||||||
tenantSlug: 'env-family',
|
tenantSlug: 'env-family',
|
||||||
sessionStore: const AuthSessionStore(),
|
sessionStore: const AuthSessionStore(),
|
||||||
);
|
);
|
||||||
|
|
||||||
await client.fetchOrgContext();
|
await client.fetchOrgContext();
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'remote directory repository filters org-context employees locally',
|
'remote directory repository filters org-context employees locally',
|
||||||
@@ -215,8 +192,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
||||||
keyId: 'key-id',
|
|
||||||
keySecret: 'key-secret',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
final repository = RemoteDirectoryRepository(orgContextApiClient: client);
|
final repository = RemoteDirectoryRepository(orgContextApiClient: client);
|
||||||
@@ -238,8 +213,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
||||||
keyId: 'key-id',
|
|
||||||
keySecret: 'key-secret',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
final repository = RemoteDirectoryRepository(orgContextApiClient: client);
|
final repository = RemoteDirectoryRepository(orgContextApiClient: client);
|
||||||
@@ -264,8 +237,6 @@ void main() {
|
|||||||
return _jsonResponse(_orgContextResponse());
|
return _jsonResponse(_orgContextResponse());
|
||||||
}),
|
}),
|
||||||
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
baseUri: Uri.parse('https://sadmin.hmac.kr'),
|
||||||
keyId: 'key-id',
|
|
||||||
keySecret: 'key-secret',
|
|
||||||
tenantSlug: 'hanmac-family',
|
tenantSlug: 'hanmac-family',
|
||||||
);
|
);
|
||||||
final repository = RemoteDirectoryRepository(orgContextApiClient: client);
|
final repository = RemoteDirectoryRepository(orgContextApiClient: client);
|
||||||
|
|||||||
@@ -154,6 +154,7 @@
|
|||||||
- 공기계 USB 연결 기준으로는 실데이터 화면까지 확인했지만, 현재 실행 모드는 `adb reverse + http://127.0.0.1:5000` 기반 로컬 Baron API 연결이므로 USB 분리 후 독립 동작은 아직 보장하지 않는다
|
- 공기계 USB 연결 기준으로는 실데이터 화면까지 확인했지만, 현재 실행 모드는 `adb reverse + http://127.0.0.1:5000` 기반 로컬 Baron API 연결이므로 USB 분리 후 독립 동작은 아직 보장하지 않는다
|
||||||
- USB 없이 동작하는 실서버 APK 테스트로 가려면 `TDC114_API_BASE`를 staging 또는 production 공개 URL로 전환하고, headless 승인 로그인과 HTTPS 경로를 그 환경에서 다시 검증해야 한다
|
- USB 없이 동작하는 실서버 APK 테스트로 가려면 `TDC114_API_BASE`를 staging 또는 production 공개 URL로 전환하고, headless 승인 로그인과 HTTPS 경로를 그 환경에서 다시 검증해야 한다
|
||||||
- 2026-07-08 기준 앱/스크립트는 `TDC114_AUTH_API_BASE`, `TDC114_DIRECTORY_API_BASE`, `TDC114_ORGANIZATION_API_BASE` 분리 주입을 지원하므로 `로그인은 staging`, `직원/조직 데이터는 production` 조합까지 실행 준비가 되어 있다
|
- 2026-07-08 기준 앱/스크립트는 `TDC114_AUTH_API_BASE`, `TDC114_DIRECTORY_API_BASE`, `TDC114_ORGANIZATION_API_BASE` 분리 주입을 지원하므로 `로그인은 staging`, `직원/조직 데이터는 production` 조합까지 실행 준비가 되어 있다
|
||||||
|
- 2026-07-20 기준 앱에는 Baron org-context key와 NAVER WORKS secret을 주입하지 않는다. 해당 값은 `tdc114plus-auth` 서버 env에서만 관리하고, 앱은 중계서버 URL과 앱 세션 token만 사용한다
|
||||||
- 2026-07-10 기준 조직/직원 원본 참고 host는 staging `https://sadmin.hmac.kr`로 되돌린다. `admin.brsw.kr` production host는 현재 앱 개발 기준에서 우선 사용하지 않는다
|
- 2026-07-10 기준 조직/직원 원본 참고 host는 staging `https://sadmin.hmac.kr`로 되돌린다. `admin.brsw.kr` production host는 현재 앱 개발 기준에서 우선 사용하지 않는다
|
||||||
- 2026-07-10 기준 Baron SSO 로그인 성공 시 조직도 API 호출용 ID/Secret을 함께 내려주는 기능은 아직 미개발로 보고, 앱은 해당 값을 받을 준비만 먼저 한다
|
- 2026-07-10 기준 Baron SSO 로그인 성공 시 조직도 API 호출용 ID/Secret을 함께 내려주는 기능은 아직 미개발로 보고, 앱은 해당 값을 받을 준비만 먼저 한다
|
||||||
- 해당 기능이 완성되기 전까지 조직/직원 데이터는 staging `org-context` endpoint와 로컬 비추적 env/Dart define의 고정 키 fallback으로 검증한다
|
- 해당 기능이 완성되기 전까지 조직/직원 데이터는 staging `org-context` endpoint와 로컬 비추적 env/Dart define의 고정 키 fallback으로 검증한다
|
||||||
|
|||||||
+2
-1
@@ -8,7 +8,7 @@
|
|||||||
- `smoke.env.example`: authenticated smoke용 로컬 env 예시 파일이다. `scripts/.env.smoke.local`로 복사해 `TDC114_API_BASE`, `TDC114_SMOKE_PHONE`을 넣어 사용할 수 있다.
|
- `smoke.env.example`: authenticated smoke용 로컬 env 예시 파일이다. `scripts/.env.smoke.local`로 복사해 `TDC114_API_BASE`, `TDC114_SMOKE_PHONE`을 넣어 사용할 수 있다.
|
||||||
- `smoke.staging.env.example`: staging Baron SSO 검증용 env 예시 파일이다. `scripts/.env.staging.local`로 복사해 `TDC114_API_BASE`, `TDC114_SMOKE_PHONE`과 optional expected label 값을 넣어 사용할 수 있다.
|
- `smoke.staging.env.example`: staging Baron SSO 검증용 env 예시 파일이다. `scripts/.env.staging.local`로 복사해 `TDC114_API_BASE`, `TDC114_SMOKE_PHONE`과 optional expected label 값을 넣어 사용할 수 있다.
|
||||||
- `android-device.env.example`: Android 공기계 USB 테스트용 env 예시 파일이다. `scripts/.env.android-device.local`로 복사해 `adb reverse` 기준 `TDC114_API_BASE=http://127.0.0.1:5000`, `TDC114_AUTH_API_BASE=http://127.0.0.1:5001`을 사용한다.
|
- `android-device.env.example`: Android 공기계 USB 테스트용 env 예시 파일이다. `scripts/.env.android-device.local`로 복사해 `adb reverse` 기준 `TDC114_API_BASE=http://127.0.0.1:5000`, `TDC114_AUTH_API_BASE=http://127.0.0.1:5001`을 사용한다.
|
||||||
- `android-device.staging.env.example`: Android 공기계/실폰의 USB 없는 staging 직접 로그인 테스트용 env 예시 파일이다. `scripts/.env.android-device.staging.local`로 복사해 공개 staging HTTPS base URL을 넣어 사용한다.
|
- `android-device.staging.env.example`: Android 공기계/실폰의 USB 없는 staging 직접 로그인 테스트용 env 예시 파일이다. `scripts/.env.android-device.staging.local`로 복사해 공개 staging HTTPS base URL을 넣어 사용한다. Baron org-context key는 앱 env가 아니라 `tdc114plus-auth` 서버 env에만 둔다.
|
||||||
- `android-device.production.env.example`: Android 공기계/실폰의 USB 없는 production 직접 로그인 테스트용 env 예시 파일이다. `scripts/.env.android-device.production.local`로 복사해 공개 production HTTPS base URL을 넣어 사용한다.
|
- `android-device.production.env.example`: Android 공기계/실폰의 USB 없는 production 직접 로그인 테스트용 env 예시 파일이다. `scripts/.env.android-device.production.local`로 복사해 공개 production HTTPS base URL을 넣어 사용한다.
|
||||||
- `bootstrap-baron-api-env.sh`: Baron SSO API worktree의 `.env.sample`을 바탕으로 로컬 smoke용 `.env`를 생성하고 localhost/알림 비활성 override를 덧붙인다.
|
- `bootstrap-baron-api-env.sh`: Baron SSO API worktree의 `.env.sample`을 바탕으로 로컬 smoke용 `.env`를 생성하고 localhost/알림 비활성 override를 덧붙인다.
|
||||||
- `check-baron-api-env.sh`: Baron SSO API worktree의 `.env`, compose, config, Docker runtime 준비 상태를 점검해 실제 API smoke 가능 여부를 빠르게 확인한다.
|
- `check-baron-api-env.sh`: Baron SSO API worktree의 `.env`, compose, config, Docker runtime 준비 상태를 점검해 실제 API smoke 가능 여부를 빠르게 확인한다.
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
- ADB 로그 조회, `devices`, `reverse --list`, `screencap` 등 Flutter가 필요 없는 ADB 작업은 `flutter-docker.sh adb` 대신 `ADB_SERVER_SOCKET=tcp:172.21.128.1:5037 ./scripts/host-adb.sh ...`를 우선 사용한다.
|
- ADB 로그 조회, `devices`, `reverse --list`, `screencap` 등 Flutter가 필요 없는 ADB 작업은 `flutter-docker.sh adb` 대신 `ADB_SERVER_SOCKET=tcp:172.21.128.1:5037 ./scripts/host-adb.sh ...`를 우선 사용한다.
|
||||||
- USB 없는 staging 직접 로그인 검증 시에는 `TDC114_SMOKE_ENV_FILE=scripts/.env.android-device.staging.local`과 `TDC114_FLUTTER_DEVICE_ID=<PHYSICAL_DEVICE_ID>`를 명시한다.
|
- USB 없는 staging 직접 로그인 검증 시에는 `TDC114_SMOKE_ENV_FILE=scripts/.env.android-device.staging.local`과 `TDC114_FLUTTER_DEVICE_ID=<PHYSICAL_DEVICE_ID>`를 명시한다.
|
||||||
- 로그인만 staging, 직원/조직 정보만 production으로 분리해야 할 경우 `TDC114_AUTH_API_BASE`, `TDC114_DIRECTORY_API_BASE`, `TDC114_ORGANIZATION_API_BASE`를 추가로 지정한다. 값을 비우면 모두 `TDC114_API_BASE`를 따른다.
|
- 로그인만 staging, 직원/조직 정보만 production으로 분리해야 할 경우 `TDC114_AUTH_API_BASE`, `TDC114_DIRECTORY_API_BASE`, `TDC114_ORGANIZATION_API_BASE`를 추가로 지정한다. 값을 비우면 모두 `TDC114_API_BASE`를 따른다.
|
||||||
|
- 앱 실행 env에는 `TDC114_BARON_KEY_ID`, `TDC114_BARON_KEY_SECRET`, NAVER WORKS secret을 넣지 않는다. 조직도 key와 네이버웍스 key는 `tdc114plus-auth` 서버 환경변수에서만 관리한다.
|
||||||
- `startup.sh`, `shutdown.sh`는 테스트나 다른 worktree 재사용을 위해 `BARON_SSO_WORKTREE`, `TDC114_LOG_BASE`, `DOCKER_BIN` 같은 환경 변수 override를 지원한다.
|
- `startup.sh`, `shutdown.sh`는 테스트나 다른 worktree 재사용을 위해 `BARON_SSO_WORKTREE`, `TDC114_LOG_BASE`, `DOCKER_BIN` 같은 환경 변수 override를 지원한다.
|
||||||
- 업무 시작 절차에서는 앱 직접 App Link callback 테스트 서버를 더 이상 기동하지 않는다. 현재 로그인은 `tdc114plus-auth`의 `/api/v1/auth/link/init`, `/api/v1/auth/link/poll` 경로를 사용한다.
|
- 업무 시작 절차에서는 앱 직접 App Link callback 테스트 서버를 더 이상 기동하지 않는다. 현재 로그인은 `tdc114plus-auth`의 `/api/v1/auth/link/init`, `/api/v1/auth/link/poll` 경로를 사용한다.
|
||||||
- Windows Android Studio emulator + WSL/Docker Flutter 운영 기준은 `docs/policy_android_studio_wsl_adb_2026-07-03.md`를 따른다.
|
- Windows Android Studio emulator + WSL/Docker Flutter 운영 기준은 `docs/policy_android_studio_wsl_adb_2026-07-03.md`를 따른다.
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
# The app talks directly to the public Baron staging API over HTTPS.
|
# The app talks directly to the public Baron staging API over HTTPS.
|
||||||
# No adb reverse is required in this mode.
|
# No adb reverse is required in this mode.
|
||||||
TDC114_API_BASE=https://sso.hmac.kr
|
TDC114_API_BASE=https://sso.hmac.kr
|
||||||
TDC114_ORG_CONTEXT_API_BASE=https://sadmin.hmac.kr
|
TDC114_AUTH_API_BASE=https://114-auth.hmac.kr
|
||||||
|
TDC114_ORG_CONTEXT_API_BASE=https://114-auth.hmac.kr
|
||||||
TDC114_ORG_CONTEXT_TENANT_SLUG=hanmac-family
|
TDC114_ORG_CONTEXT_TENANT_SLUG=hanmac-family
|
||||||
TDC114_BARON_KEY_ID=replace-with-staging-key-id
|
|
||||||
TDC114_BARON_KEY_SECRET=replace-with-staging-key-secret
|
|
||||||
|
|
||||||
# Skip local phone-login bootstrap and open the normal in-app login flow.
|
# Skip local phone-login bootstrap and open the normal in-app login flow.
|
||||||
TDC114_SKIP_SESSION_BOOTSTRAP=true
|
TDC114_SKIP_SESSION_BOOTSTRAP=true
|
||||||
@@ -18,7 +17,6 @@ TDC114_SMOKE_PHONE=010xxxxxxxx
|
|||||||
# TDC114_SMOKE_EXPECTED_TENANT_LABEL=IS3
|
# TDC114_SMOKE_EXPECTED_TENANT_LABEL=IS3
|
||||||
|
|
||||||
# Optional split mode:
|
# Optional split mode:
|
||||||
# Login and org-context stay on staging by default.
|
# Login and org-context should normally go through tdc114plus-auth.
|
||||||
# TDC114_AUTH_API_BASE=https://sso.hmac.kr
|
# TDC114_DIRECTORY_API_BASE=https://114-auth.hmac.kr
|
||||||
# TDC114_DIRECTORY_API_BASE=https://sadmin.hmac.kr
|
# TDC114_ORGANIZATION_API_BASE=https://114-auth.hmac.kr
|
||||||
# TDC114_ORGANIZATION_API_BASE=https://sadmin.hmac.kr
|
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ append_optional_define "TDC114_DIRECTORY_API_BASE"
|
|||||||
append_optional_define "TDC114_ORGANIZATION_API_BASE"
|
append_optional_define "TDC114_ORGANIZATION_API_BASE"
|
||||||
append_optional_define "TDC114_ORG_CONTEXT_API_BASE"
|
append_optional_define "TDC114_ORG_CONTEXT_API_BASE"
|
||||||
append_optional_define "TDC114_ORG_CONTEXT_TENANT_SLUG"
|
append_optional_define "TDC114_ORG_CONTEXT_TENANT_SLUG"
|
||||||
append_optional_define "TDC114_BARON_KEY_ID"
|
|
||||||
append_optional_define "TDC114_BARON_KEY_SECRET"
|
|
||||||
|
|
||||||
TEST_DEVICE_ID="${TDC114_FLUTTER_DEVICE_ID:-${TDC114_ADB_CONNECT_ADDRESS:-}}"
|
TEST_DEVICE_ID="${TDC114_FLUTTER_DEVICE_ID:-${TDC114_ADB_CONNECT_ADDRESS:-}}"
|
||||||
if [ -n "$TEST_DEVICE_ID" ]; then
|
if [ -n "$TEST_DEVICE_ID" ]; then
|
||||||
|
|||||||
@@ -56,8 +56,6 @@ append_optional_define "TDC114_DIRECTORY_API_BASE"
|
|||||||
append_optional_define "TDC114_ORGANIZATION_API_BASE"
|
append_optional_define "TDC114_ORGANIZATION_API_BASE"
|
||||||
append_optional_define "TDC114_ORG_CONTEXT_API_BASE"
|
append_optional_define "TDC114_ORG_CONTEXT_API_BASE"
|
||||||
append_optional_define "TDC114_ORG_CONTEXT_TENANT_SLUG"
|
append_optional_define "TDC114_ORG_CONTEXT_TENANT_SLUG"
|
||||||
append_optional_define "TDC114_BARON_KEY_ID"
|
|
||||||
append_optional_define "TDC114_BARON_KEY_SECRET"
|
|
||||||
|
|
||||||
if [ "$SKIP_SESSION_BOOTSTRAP" = "1" ] || [ "$SKIP_SESSION_BOOTSTRAP" = "true" ]; then
|
if [ "$SKIP_SESSION_BOOTSTRAP" = "1" ] || [ "$SKIP_SESSION_BOOTSTRAP" = "true" ]; then
|
||||||
echo "Skipping session bootstrap; app will open its normal login flow." >&2
|
echo "Skipping session bootstrap; app will open its normal login flow." >&2
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
TDC114_API_BASE=https://sso.hmac.kr
|
TDC114_API_BASE=https://sso.hmac.kr
|
||||||
TDC114_ORG_CONTEXT_API_BASE=https://sadmin.hmac.kr
|
TDC114_AUTH_API_BASE=https://114-auth.hmac.kr
|
||||||
|
TDC114_ORG_CONTEXT_API_BASE=https://114-auth.hmac.kr
|
||||||
TDC114_ORG_CONTEXT_TENANT_SLUG=hanmac-family
|
TDC114_ORG_CONTEXT_TENANT_SLUG=hanmac-family
|
||||||
TDC114_BARON_KEY_ID=replace-with-staging-key-id
|
|
||||||
TDC114_BARON_KEY_SECRET=replace-with-staging-key-secret
|
|
||||||
TDC114_SMOKE_PHONE=010xxxxxxxx
|
TDC114_SMOKE_PHONE=010xxxxxxxx
|
||||||
TDC114_SMOKE_AUTH_FLOW=link
|
TDC114_SMOKE_AUTH_FLOW=link
|
||||||
|
|
||||||
@@ -11,6 +10,5 @@ TDC114_SMOKE_AUTH_FLOW=link
|
|||||||
# TDC114_SMOKE_EXPECTED_TENANT_LABEL=IS3
|
# TDC114_SMOKE_EXPECTED_TENANT_LABEL=IS3
|
||||||
|
|
||||||
# Optional split mode:
|
# Optional split mode:
|
||||||
# TDC114_AUTH_API_BASE=https://sso.hmac.kr
|
# TDC114_DIRECTORY_API_BASE=https://114-auth.hmac.kr
|
||||||
# TDC114_DIRECTORY_API_BASE=https://sadmin.hmac.kr
|
# TDC114_ORGANIZATION_API_BASE=https://114-auth.hmac.kr
|
||||||
# TDC114_ORGANIZATION_API_BASE=https://sadmin.hmac.kr
|
|
||||||
|
|||||||
@@ -107,14 +107,19 @@ if [ -f "$NAVER_WORKS_ENV_FILE" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
: "${TDC114_ORG_CONTEXT_API_BASE:?TDC114_ORG_CONTEXT_API_BASE is required in $ENV_FILE}"
|
ORG_CONTEXT_BASE="${BARON_ORG_CONTEXT_BASE_URL:-${TDC114_ORG_CONTEXT_API_BASE:-}}"
|
||||||
: "${TDC114_ORG_CONTEXT_TENANT_SLUG:?TDC114_ORG_CONTEXT_TENANT_SLUG is required in $ENV_FILE}"
|
ORG_CONTEXT_TENANT_SLUG="${BARON_ORG_CONTEXT_TENANT_SLUG:-${TDC114_ORG_CONTEXT_TENANT_SLUG:-}}"
|
||||||
: "${TDC114_BARON_KEY_ID:?TDC114_BARON_KEY_ID is required in $ENV_FILE}"
|
ORG_CONTEXT_KEY_ID="${BARON_ORG_CONTEXT_KEY_ID:-${TDC114_BARON_KEY_ID:-}}"
|
||||||
: "${TDC114_BARON_KEY_SECRET:?TDC114_BARON_KEY_SECRET is required in $ENV_FILE}"
|
ORG_CONTEXT_KEY_SECRET="${BARON_ORG_CONTEXT_KEY_SECRET:-${TDC114_BARON_KEY_SECRET:-}}"
|
||||||
|
|
||||||
|
: "${ORG_CONTEXT_BASE:?BARON_ORG_CONTEXT_BASE_URL is required in $ENV_FILE}"
|
||||||
|
: "${ORG_CONTEXT_TENANT_SLUG:?BARON_ORG_CONTEXT_TENANT_SLUG is required in $ENV_FILE}"
|
||||||
|
: "${ORG_CONTEXT_KEY_ID:?BARON_ORG_CONTEXT_KEY_ID is required in $ENV_FILE}"
|
||||||
|
: "${ORG_CONTEXT_KEY_SECRET:?BARON_ORG_CONTEXT_KEY_SECRET is required in $ENV_FILE}"
|
||||||
|
|
||||||
UPSTREAM_ORG_CONTEXT_BASE="${TDC114_AUTH_UPSTREAM_ORG_CONTEXT_API_BASE:-}"
|
UPSTREAM_ORG_CONTEXT_BASE="${TDC114_AUTH_UPSTREAM_ORG_CONTEXT_API_BASE:-}"
|
||||||
if [ -z "$UPSTREAM_ORG_CONTEXT_BASE" ]; then
|
if [ -z "$UPSTREAM_ORG_CONTEXT_BASE" ]; then
|
||||||
UPSTREAM_ORG_CONTEXT_BASE="$TDC114_ORG_CONTEXT_API_BASE"
|
UPSTREAM_ORG_CONTEXT_BASE="$ORG_CONTEXT_BASE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "Starting tdc114plus-auth on :$PORT"
|
log "Starting tdc114plus-auth on :$PORT"
|
||||||
@@ -138,9 +143,9 @@ log "Log file: $LOG_FILE"
|
|||||||
BARON_JWKS_KID="${BARON_JWKS_KID:-tdc114plus-auth-key-1}" \
|
BARON_JWKS_KID="${BARON_JWKS_KID:-tdc114plus-auth-key-1}" \
|
||||||
BARON_LINK_RETURN_URI="${BARON_LINK_RETURN_URI:-}" \
|
BARON_LINK_RETURN_URI="${BARON_LINK_RETURN_URI:-}" \
|
||||||
BARON_ORG_CONTEXT_BASE_URL="$UPSTREAM_ORG_CONTEXT_BASE" \
|
BARON_ORG_CONTEXT_BASE_URL="$UPSTREAM_ORG_CONTEXT_BASE" \
|
||||||
BARON_ORG_CONTEXT_TENANT_SLUG="$TDC114_ORG_CONTEXT_TENANT_SLUG" \
|
BARON_ORG_CONTEXT_TENANT_SLUG="$ORG_CONTEXT_TENANT_SLUG" \
|
||||||
BARON_ORG_CONTEXT_KEY_ID="$TDC114_BARON_KEY_ID" \
|
BARON_ORG_CONTEXT_KEY_ID="$ORG_CONTEXT_KEY_ID" \
|
||||||
BARON_ORG_CONTEXT_KEY_SECRET="$TDC114_BARON_KEY_SECRET" \
|
BARON_ORG_CONTEXT_KEY_SECRET="$ORG_CONTEXT_KEY_SECRET" \
|
||||||
go run ./cmd/server >>"$LOG_FILE" 2>&1 < /dev/null &
|
go run ./cmd/server >>"$LOG_FILE" 2>&1 < /dev/null &
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user