1
0
forked from baron/baron-sso

feat(auth): lock affiliation type on frontend based on verified email domain (#500)

This commit is contained in:
2026-04-07 13:01:30 +09:00
parent 4e7f3e7235
commit b3a7f47cf7
3 changed files with 99 additions and 64 deletions

View File

@@ -44,6 +44,7 @@ class _SignupScreenState extends State<SignupScreen> {
bool _isEmailVerified = false;
bool _isPhoneVerified = false;
String _affiliationType = 'GENERAL';
bool _isAffiliateLocked = false;
String? _companyCode;
bool _termsAccepted = false;
bool _privacyAccepted = false;
@@ -72,15 +73,23 @@ class _SignupScreenState extends State<SignupScreen> {
void initState() {
super.initState();
_loadPolicy();
_fetchTenants();
// initState에서는 _fetchTenants() 호출 제외
}
Future<void> _fetchTenants() async {
if (!_isEmailVerified) return;
try {
final tenants = await AuthProxyService.getActiveTenants();
final tenants = await AuthProxyService.getActiveTenants(
email: _emailController.text.trim(),
);
if (mounted) {
setState(() {
_tenants = tenants;
if (_tenants.isNotEmpty && _affiliationType == 'AFFILIATE') {
// 목록이 있는데 아직 아무것도 선택되지 않았다면 자동 할당 가능
_companyCode ??= _tenants.first['slug'];
}
});
}
} catch (e) {
@@ -195,18 +204,32 @@ class _SignupScreenState extends State<SignupScreen> {
final code = _emailCodeController.text.trim();
if (code.length != 6) return;
try {
final success = await AuthProxyService.verifySignupCode(
final res = await AuthProxyService.verifySignupCode(
_emailController.text.trim(),
'email',
code,
);
if (success) {
if (res['success'] == true) {
setState(() {
_isEmailVerified = true;
_emailTimer?.cancel();
_emailSeconds = 0;
_emailError = null;
if (res['isAffiliate'] == true) {
_affiliationType = 'AFFILIATE';
_isAffiliateLocked = true;
} else {
_affiliationType = 'GENERAL';
_companyCode = null;
_isAffiliateLocked = true;
}
});
// Only fetch tenants if it's an affiliate domain
if (res['isAffiliate'] == true) {
_fetchTenants();
}
} else {
setState(
() => _emailError = tr('msg.userfront.signup.email.code_mismatch'),
@@ -248,12 +271,12 @@ class _SignupScreenState extends State<SignupScreen> {
final code = _phoneCodeController.text.trim();
if (code.length != 6) return;
try {
final success = await AuthProxyService.verifySignupCode(
final res = await AuthProxyService.verifySignupCode(
_phoneController.text.trim(),
'phone',
code,
);
if (success) {
if (res['success'] == true) {
setState(() {
_isPhoneVerified = true;
_phoneTimer?.cancel();
@@ -1445,17 +1468,19 @@ class _SignupScreenState extends State<SignupScreen> {
),
),
],
onChanged: (val) {
if (val == null) {
return;
}
setState(() {
_affiliationType = val;
if (_affiliationType == 'GENERAL') {
_companyCode = null;
}
});
},
onChanged: _isAffiliateLocked
? null
: (val) {
if (val == null) {
return;
}
setState(() {
_affiliationType = val;
if (_affiliationType == 'GENERAL') {
_companyCode = null;
}
});
},
),
AnimatedSize(
duration: const Duration(milliseconds: 180),