forked from baron/baron-sso
모바일 fallback 변경. .env유출 가능성 차단
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
const _compileTimeEnv = {
|
||||
'APP_ENV': String.fromEnvironment('APP_ENV'),
|
||||
'BACKEND_URL': String.fromEnvironment('BACKEND_URL'),
|
||||
'CLIENT_LOG_DEBUG': String.fromEnvironment('CLIENT_LOG_DEBUG'),
|
||||
'USERFRONT_DEBUG_LOG': String.fromEnvironment('USERFRONT_DEBUG_LOG'),
|
||||
'USERFRONT_URL': String.fromEnvironment('USERFRONT_URL'),
|
||||
};
|
||||
|
||||
String runtimeOriginFallback() {
|
||||
@@ -13,17 +13,10 @@ String runtimeOriginFallback() {
|
||||
return origin;
|
||||
}
|
||||
} catch (_) {}
|
||||
return 'https://sso-test.hmac.kr';
|
||||
return '';
|
||||
}
|
||||
|
||||
String envOrDefault(String key, String fallback) {
|
||||
if (dotenv.isInitialized) {
|
||||
final value = dotenv.env[key];
|
||||
if (value != null && value.trim().isNotEmpty) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
final compileTimeValue = _compileTimeEnv[key];
|
||||
if (compileTimeValue != null && compileTimeValue.trim().isNotEmpty) {
|
||||
return compileTimeValue;
|
||||
|
||||
@@ -150,14 +150,6 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_dotenv:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_dotenv
|
||||
sha256: d4130c4a43e0b13fefc593bc3961f2cb46e30cb79e253d4a526b1b5d24ae1ce4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_driver:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -276,14 +268,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -39,7 +39,6 @@ dependencies:
|
||||
flutter_riverpod: ^3.0.3
|
||||
go_router: ^17.0.1
|
||||
http: ^1.6.0
|
||||
flutter_dotenv: ^6.0.0
|
||||
flutter_svg: ^2.2.1
|
||||
url_launcher: ^6.3.2
|
||||
logging: ^1.2.0
|
||||
|
||||
@@ -10,8 +10,10 @@ set -- flutter run \
|
||||
--web-hostname 0.0.0.0 \
|
||||
--web-port "${USERFRONT_INTERNAL_PORT:-5000}" \
|
||||
--wasm \
|
||||
--dart-define=BACKEND_URL="${BACKEND_URL:-}" \
|
||||
--dart-define=CLIENT_LOG_DEBUG="${CLIENT_LOG_DEBUG:-false}" \
|
||||
--dart-define=APP_ENV="${APP_ENV:-dev}" \
|
||||
--dart-define=USERFRONT_URL="${USERFRONT_URL:-}" \
|
||||
${USERFRONT_FLUTTER_RUN_FLAGS:-} \
|
||||
--no-web-resources-cdn
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ void main() {
|
||||
widgetLoginChallenge: 'widget-challenge',
|
||||
uri: Uri.parse('/ko/login'),
|
||||
rawSearch: '?login_challenge=raw-search',
|
||||
rawHref: 'https://sso-test.hmac.kr/ko/login?login_challenge=raw-href',
|
||||
rawHref: 'https://sso.example.test/ko/login?login_challenge=raw-href',
|
||||
);
|
||||
|
||||
expect(resolved.value, 'widget-challenge');
|
||||
@@ -46,7 +46,7 @@ void main() {
|
||||
uri: Uri.parse('/ko/login'),
|
||||
rawSearch: '',
|
||||
rawHref:
|
||||
'https://sso-test.hmac.kr/ko/login?a=1&login_challenge=raw-href-value#fragment',
|
||||
'https://sso.example.test/ko/login?a=1&login_challenge=raw-href-value#fragment',
|
||||
);
|
||||
|
||||
expect(resolved.value, 'raw-href-value');
|
||||
@@ -59,7 +59,7 @@ void main() {
|
||||
widgetLoginChallenge: null,
|
||||
uri: Uri.parse('/ko/login'),
|
||||
rawSearch: '',
|
||||
rawHref: 'https://sso-test.hmac.kr/ko/login?x=1',
|
||||
rawHref: 'https://sso.example.test/ko/login?x=1',
|
||||
);
|
||||
|
||||
expect(resolved.value, isNull);
|
||||
|
||||
@@ -5,12 +5,12 @@ void main() {
|
||||
group('oidc_redirect_guard', () {
|
||||
test('http/https 절대 URL만 허용', () {
|
||||
final ok = validateOidcRedirectTarget(
|
||||
'https://sso-test.hmac.kr/oidc/oauth2/auth?client_id=devfront&login_verifier=abc&state=xyz&code_challenge=ccc&code_challenge_method=S256&response_type=code&scope=openid%20profile&redirect_uri=http%3A%2F%2Flocalhost%3A5174%2Fcallback',
|
||||
'https://sso.example.test/oidc/oauth2/auth?client_id=devfront&login_verifier=abc&state=xyz&code_challenge=ccc&code_challenge_method=S256&response_type=code&scope=openid%20profile&redirect_uri=http%3A%2F%2Flocalhost%3A5174%2Fcallback',
|
||||
);
|
||||
expect(ok.isValid, isTrue);
|
||||
expect(ok.reason, 'ok');
|
||||
expect(ok.scheme, 'https');
|
||||
expect(ok.host, 'sso-test.hmac.kr');
|
||||
expect(ok.host, 'sso.example.test');
|
||||
expect(ok.path, '/oidc/oauth2/auth');
|
||||
expect(ok.isOidcAuthPath, isTrue);
|
||||
expect(ok.queryParamCount, 8);
|
||||
|
||||
@@ -7,7 +7,7 @@ void main() {
|
||||
final action = decidePasswordLoginNextAction(
|
||||
hasLoginChallenge: true,
|
||||
redirectTo:
|
||||
'https://sso-test.hmac.kr/oidc/oauth2/auth?login_verifier=a',
|
||||
'https://sso.example.test/oidc/oauth2/auth?login_verifier=a',
|
||||
jwt: 'jwt-token',
|
||||
);
|
||||
|
||||
|
||||
43
userfront/test/runtime_env_compile_time_test.dart
Normal file
43
userfront/test/runtime_env_compile_time_test.dart
Normal file
@@ -0,0 +1,43 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:userfront/core/services/runtime_env.dart';
|
||||
|
||||
const _expectedBackendUrl = String.fromEnvironment('BACKEND_URL');
|
||||
const _expectedUserfrontUrl = String.fromEnvironment('USERFRONT_URL');
|
||||
|
||||
void main() {
|
||||
group('runtime env compile-time defines', () {
|
||||
test('runtime fallback is empty outside a browser origin', () {
|
||||
expect(runtimeOriginFallback(), isEmpty);
|
||||
});
|
||||
|
||||
test('BACKEND_URL dart-define overrides runtime origin fallback when set', () {
|
||||
if (_expectedBackendUrl.isEmpty) {
|
||||
expect(runtimeBackendUrl(), runtimeOriginFallback());
|
||||
return;
|
||||
}
|
||||
|
||||
expect(runtimeBackendUrl(), sanitizedUrl(_expectedBackendUrl));
|
||||
});
|
||||
|
||||
test(
|
||||
'USERFRONT_URL dart-define overrides runtime origin fallback when set',
|
||||
() {
|
||||
if (_expectedUserfrontUrl.isEmpty) {
|
||||
expect(runtimeUserfrontUrl(), runtimeOriginFallback());
|
||||
return;
|
||||
}
|
||||
|
||||
expect(runtimeUserfrontUrl(), sanitizedUrl(_expectedUserfrontUrl));
|
||||
},
|
||||
);
|
||||
|
||||
test('dart-define URLs are sanitized', () {
|
||||
if (_expectedBackendUrl.isEmpty || _expectedUserfrontUrl.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
expect(runtimeBackendUrl(), isNot(endsWith('/')));
|
||||
expect(runtimeUserfrontUrl(), isNot(endsWith('/')));
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user