forked from baron/baron-sso
Implement tenant import and RP auto login policies
This commit is contained in:
@@ -17,7 +17,7 @@ import { toast } from "../../../components/ui/use-toast";
|
||||
import { fetchMe, fetchTenant, updateTenant } from "../../../lib/adminApi";
|
||||
import { t } from "../../../lib/i18n";
|
||||
|
||||
type SchemaFieldType =
|
||||
export type SchemaFieldType =
|
||||
| "text"
|
||||
| "number"
|
||||
| "boolean"
|
||||
@@ -25,7 +25,7 @@ type SchemaFieldType =
|
||||
| "float"
|
||||
| "datetime";
|
||||
|
||||
type SchemaField = {
|
||||
export type SchemaField = {
|
||||
id: string;
|
||||
key: string;
|
||||
label: string;
|
||||
@@ -35,6 +35,7 @@ type SchemaField = {
|
||||
validation?: string;
|
||||
unsigned?: boolean;
|
||||
isLoginId?: boolean;
|
||||
indexed?: boolean;
|
||||
};
|
||||
|
||||
function createFieldId() {
|
||||
@@ -44,6 +45,54 @@ function createFieldId() {
|
||||
return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
||||
}
|
||||
|
||||
function isSchemaFieldType(value: unknown): value is SchemaFieldType {
|
||||
return (
|
||||
value === "text" ||
|
||||
value === "number" ||
|
||||
value === "boolean" ||
|
||||
value === "date" ||
|
||||
value === "float" ||
|
||||
value === "datetime"
|
||||
);
|
||||
}
|
||||
|
||||
export function normalizeSchemaField(field: unknown): SchemaField {
|
||||
const source =
|
||||
typeof field === "object" && field !== null
|
||||
? (field as Record<string, unknown>)
|
||||
: {};
|
||||
const type = isSchemaFieldType(source.type) ? source.type : "text";
|
||||
const isLoginId = Boolean(source.isLoginId);
|
||||
|
||||
return {
|
||||
id: typeof source.id === "string" ? source.id : createFieldId(),
|
||||
key: typeof source.key === "string" ? source.key : "",
|
||||
label: typeof source.label === "string" ? source.label : "",
|
||||
type,
|
||||
required: Boolean(source.required),
|
||||
adminOnly: Boolean(source.adminOnly),
|
||||
validation:
|
||||
typeof source.validation === "string" ? source.validation : "",
|
||||
unsigned: Boolean(source.unsigned),
|
||||
isLoginId,
|
||||
indexed: isLoginId || Boolean(source.indexed),
|
||||
};
|
||||
}
|
||||
|
||||
export function createSchemaField(): SchemaField {
|
||||
return {
|
||||
id: createFieldId(),
|
||||
key: "",
|
||||
label: "",
|
||||
type: "text",
|
||||
required: false,
|
||||
adminOnly: false,
|
||||
validation: "",
|
||||
unsigned: false,
|
||||
indexed: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function TenantSchemaPage() {
|
||||
const { tenantId } = useParams<{ tenantId: string }>();
|
||||
const queryClient = useQueryClient();
|
||||
@@ -71,27 +120,7 @@ export function TenantSchemaPage() {
|
||||
const rawSchema = tenantQuery.data?.config?.userSchema;
|
||||
|
||||
if (Array.isArray(rawSchema)) {
|
||||
setFields(
|
||||
rawSchema.map((field) => ({
|
||||
id: typeof field?.id === "string" ? field.id : createFieldId(),
|
||||
key: typeof field?.key === "string" ? field.key : "",
|
||||
label: typeof field?.label === "string" ? field.label : "",
|
||||
type:
|
||||
field?.type === "number" ||
|
||||
field?.type === "boolean" ||
|
||||
field?.type === "date" ||
|
||||
field?.type === "float" ||
|
||||
field?.type === "datetime"
|
||||
? field.type
|
||||
: "text",
|
||||
required: Boolean(field?.required),
|
||||
adminOnly: Boolean(field?.adminOnly),
|
||||
validation:
|
||||
typeof field?.validation === "string" ? field.validation : "",
|
||||
unsigned: Boolean(field?.unsigned),
|
||||
isLoginId: Boolean(field?.isLoginId),
|
||||
})),
|
||||
);
|
||||
setFields(rawSchema.map(normalizeSchemaField));
|
||||
}
|
||||
}, [tenantQuery.data]);
|
||||
|
||||
@@ -158,19 +187,7 @@ export function TenantSchemaPage() {
|
||||
}
|
||||
|
||||
const addField = () => {
|
||||
setFields([
|
||||
...fields,
|
||||
{
|
||||
id: createFieldId(),
|
||||
key: "",
|
||||
label: "",
|
||||
type: "text",
|
||||
required: false,
|
||||
adminOnly: false,
|
||||
validation: "",
|
||||
unsigned: false,
|
||||
},
|
||||
]);
|
||||
setFields([...fields, createSchemaField()]);
|
||||
};
|
||||
|
||||
const removeField = (index: number) => {
|
||||
@@ -261,16 +278,15 @@ export function TenantSchemaPage() {
|
||||
value={field.type}
|
||||
onChange={(e) => {
|
||||
const nextType = e.target.value;
|
||||
if (
|
||||
nextType === "text" ||
|
||||
nextType === "number" ||
|
||||
nextType === "boolean" ||
|
||||
nextType === "date" ||
|
||||
nextType === "float" ||
|
||||
nextType === "datetime"
|
||||
) {
|
||||
if (isSchemaFieldType(nextType)) {
|
||||
updateField(index, {
|
||||
type: nextType as SchemaFieldType,
|
||||
type: nextType,
|
||||
isLoginId:
|
||||
nextType === "text" ? field.isLoginId : false,
|
||||
indexed:
|
||||
nextType === "text"
|
||||
? field.indexed || field.isLoginId || false
|
||||
: field.indexed,
|
||||
});
|
||||
}
|
||||
}}
|
||||
@@ -351,7 +367,11 @@ export function TenantSchemaPage() {
|
||||
type="checkbox"
|
||||
checked={field.isLoginId || false}
|
||||
onChange={(e) =>
|
||||
updateField(index, { isLoginId: e.target.checked })
|
||||
updateField(index, {
|
||||
isLoginId: e.target.checked,
|
||||
indexed: e.target.checked ? true : field.indexed,
|
||||
type: e.target.checked ? "text" : field.type,
|
||||
})
|
||||
}
|
||||
className="w-4 h-4 rounded border-gray-300 text-primary focus:ring-primary"
|
||||
/>
|
||||
@@ -362,6 +382,23 @@ export function TenantSchemaPage() {
|
||||
)}
|
||||
</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={field.indexed || field.isLoginId || false}
|
||||
disabled={field.isLoginId}
|
||||
onChange={(e) =>
|
||||
updateField(index, { indexed: e.target.checked })
|
||||
}
|
||||
className="w-4 h-4 rounded border-gray-300 text-primary focus:ring-primary disabled:opacity-60"
|
||||
/>
|
||||
<span className="text-sm font-medium">
|
||||
{t(
|
||||
"ui.admin.tenants.schema.field.indexed",
|
||||
"검색 인덱스 필요",
|
||||
)}
|
||||
</span>
|
||||
</label>
|
||||
{(field.type === "number" || field.type === "float") && (
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user