forked from baron/baron-sso
feat: implement multi-identifier architecture (Issue #496)
- Database: Add user_login_ids table for 1:N identifier mapping and remove legacy login_id column - Kratos: Update identity schema to use custom_login_ids array instead of a single id trait - Backend: Implement syncCustomLoginIDs to collect isLoginId fields across tenant schemas - Backend: Add backtracking logic to auto-assign session tenant based on used login identifier - Backend: Add 409 Conflict exception handling for Create/Update operations - AdminFront: Refactor UserDetailPage to a tabbed grid layout (Info, Tenants, Security) - AdminFront: Show '로그인 ID' badge on tenant schema fields used for authentication - UserFront: Remove legacy optional 'Login ID' input from signup flow - Tests: Add multi-identifier repository tests and update handler tests
This commit is contained in:
@@ -31,6 +31,7 @@ type UserSchemaField = {
|
||||
required?: boolean;
|
||||
adminOnly?: boolean;
|
||||
validation?: string;
|
||||
isLoginId?: boolean;
|
||||
};
|
||||
|
||||
type UserFormValues = UserCreateRequest & { metadata: Record<string, unknown> };
|
||||
@@ -65,7 +66,6 @@ function UserCreatePage() {
|
||||
} = useForm<UserFormValues>({
|
||||
defaultValues: {
|
||||
email: "",
|
||||
loginId: "",
|
||||
password: "",
|
||||
name: "",
|
||||
phone: "",
|
||||
@@ -274,26 +274,6 @@ function UserCreatePage() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="loginId">
|
||||
{t("ui.admin.users.create.form.login_id", "로그인 ID (선택)")}
|
||||
</Label>
|
||||
<Input
|
||||
id="loginId"
|
||||
placeholder={t(
|
||||
"ui.admin.users.create.form.login_id_placeholder",
|
||||
"사번 또는 아이디",
|
||||
)}
|
||||
{...register("loginId")}
|
||||
/>
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
{t(
|
||||
"msg.admin.users.create.form.login_id_help",
|
||||
"이메일/전화번호 외에 별도의 식별자로 로그인할 때 사용합니다.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="password">
|
||||
@@ -470,6 +450,11 @@ function UserCreatePage() {
|
||||
Admin Only
|
||||
</span>
|
||||
)}
|
||||
{field.isLoginId && (
|
||||
<span className="ml-2 text-[10px] bg-green-500/10 text-green-600 px-1.5 py-0.5 rounded uppercase font-bold">
|
||||
{t("ui.admin.users.create.form.is_login_id", "로그인 ID")}
|
||||
</span>
|
||||
)}
|
||||
</Label>
|
||||
|
||||
<Input
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -430,9 +430,6 @@ function UserListPage() {
|
||||
"NAME / EMAIL",
|
||||
)}
|
||||
</TableHead>
|
||||
<TableHead>
|
||||
{t("ui.admin.users.list.table.login_id", "LOGIN ID")}
|
||||
</TableHead>
|
||||
<TableHead>
|
||||
{t("ui.admin.users.list.table.role", "ROLE")}
|
||||
</TableHead>
|
||||
@@ -514,11 +511,6 @@ function UserListPage() {
|
||||
</div>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="text-sm font-mono">
|
||||
{user.loginId || "-"}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant="outline">
|
||||
{t(`ui.admin.role.${user.role}`, user.role)}
|
||||
|
||||
Reference in New Issue
Block a user