1
0
forked from baron/baron-sso

feat(i18n): apply ORY bypass whitelist policy and add error-code tests

This commit is contained in:
Lectom C Han
2026-02-13 10:47:33 +09:00
parent c1645b2d4b
commit db71364e80
18 changed files with 636 additions and 45 deletions

View File

@@ -1,11 +1,27 @@
const Map<String, String> errorWhitelistMessages = {
const Map<String, String> internalErrorWhitelistMessages = {
'settings_disabled': '현재 계정 설정 화면은 준비 중입니다.',
'invalid_session': '세션이 만료되었습니다. 다시 로그인해 주세요.',
'verification_required': '추가 인증이 필요합니다. 안내에 따라 진행해 주세요.',
'recovery_expired': '재설정 링크가 만료되었습니다. 다시 요청해 주세요.',
'recovery_invalid': '재설정 링크가 유효하지 않습니다.',
'consent_required': '앱 접근 동의가 필요합니다.',
'rate_limited': '요청이 많습니다. 잠시 후 다시 시도해 주세요.',
'not_found': '요청한 페이지를 찾을 수 없습니다.',
'bad_request': '입력값을 확인해 주세요.',
'password_or_email_mismatch': '이메일 혹은 비밀번호가 일치하지 않습니다.',
};
const Set<String> oryBypassErrorCodes = {
'access_denied',
'consent_required',
'interaction_required',
'invalid_client',
'invalid_grant',
'invalid_request',
'invalid_scope',
'login_required',
'request_forbidden',
'server_error',
'temporarily_unavailable',
'unauthorized_client',
'unsupported_response_type',
};

View File

@@ -24,10 +24,13 @@ class ErrorScreen extends StatelessWidget {
final isProd = isProdOverride ?? AuthProxyService.isProdEnv;
final normalizedCode = (errorCode ?? '').trim();
final hasCode = normalizedCode.isNotEmpty;
final whitelistFallback = errorWhitelistMessages[normalizedCode];
final isWhitelisted = whitelistFallback != null;
final internalWhitelistFallback =
internalErrorWhitelistMessages[normalizedCode];
final isInternalWhitelisted = internalWhitelistFallback != null;
final isOryBypass = hasCode && oryBypassErrorCodes.contains(normalizedCode);
final isKnownProdCode = hasCode && (isInternalWhitelisted || isOryBypass);
final errorType = isProd
? (isWhitelisted && hasCode ? normalizedCode : 'unknown_error')
? (isKnownProdCode ? normalizedCode : 'unknown_error')
: (hasCode ? normalizedCode : 'unknown_error');
final title = isProd
? tr('msg.userfront.error.title')
@@ -40,14 +43,22 @@ class ErrorScreen extends StatelessWidget {
'msg.userfront.error.title_generic',
));
final detail = isProd
? (isWhitelisted
? (isInternalWhitelisted
? tr(
'msg.userfront.error.whitelist.$normalizedCode',
fallback: whitelistFallback,
fallback: internalWhitelistFallback,
)
: tr(
'msg.userfront.error.detail_contact',
))
: (isOryBypass
? tr(
'msg.userfront.error.ory.$normalizedCode',
fallback:
(description?.isNotEmpty == true)
? description
: tr('msg.userfront.error.detail_request'),
)
: tr(
'msg.userfront.error.detail_contact',
)))
: ((description?.isNotEmpty == true)
? description!
: (hasCode