mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-31 07:35:24 +00:00
feat: drop the 2.8 columns, moves and aliases kept for a downgrade
This commit is contained in:
1 parent
d3d8269cb7
commit
61f46d2517
196 files changed
+29909
-10511
No files matched your search
@@ -33,7 +33,7 @@ export type AdminUser = {
|
||||
id: string;
|
||||
username: string;
|
||||
isAdmin: boolean;
|
||||
isOidc: boolean;
|
||||
isExternal: boolean;
|
||||
passwordHash?: string;
|
||||
dataUnlocked?: boolean;
|
||||
secondFactorEnabled?: boolean;
|
||||
@@ -74,7 +74,7 @@ type UsersSectionProps = {
|
||||
setEditUserTarget: Dispatch<SetStateAction<AdminUser | null>>;
|
||||
setEditUserOpen: Dispatch<SetStateAction<boolean>>;
|
||||
setLinkAccountTarget: Dispatch<
|
||||
SetStateAction<{ id: string; username: string; isOidc: boolean } | null>
|
||||
SetStateAction<{ id: string; username: string; isExternal: boolean } | null>
|
||||
>;
|
||||
setLinkAccountOpen: Dispatch<SetStateAction<boolean>>;
|
||||
setUnlinkAccountTarget: Dispatch<
|
||||
@@ -158,10 +158,10 @@ export function AdminUsersSection({
|
||||
</div>
|
||||
{users.map((user) => {
|
||||
const authLabel =
|
||||
user.isOidc && user.passwordHash
|
||||
user.isExternal && user.passwordHash
|
||||
? t("admin.authTypeDual")
|
||||
: user.isOidc
|
||||
? t("admin.authTypeOidc")
|
||||
: user.isExternal
|
||||
? t("admin.authTypeExternal")
|
||||
: t("admin.authTypeLocal");
|
||||
return (
|
||||
<div
|
||||
@@ -209,7 +209,7 @@ export function AdminUsersSection({
|
||||
>
|
||||
<Pencil className="size-3" />
|
||||
</Button>
|
||||
{user.isOidc && user.passwordHash ? (
|
||||
{user.isExternal && user.passwordHash ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
@@ -235,7 +235,7 @@ export function AdminUsersSection({
|
||||
setLinkAccountTarget({
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
isOidc: user.isOidc,
|
||||
isExternal: user.isExternal,
|
||||
});
|
||||
setLinkAccountOpen(true);
|
||||
}}
|
||||
|
||||
@@ -151,7 +151,7 @@ export function AdminSettingsPanel({
|
||||
const [linkAccountTarget, setLinkAccountTarget] = useState<{
|
||||
id: string;
|
||||
username: string;
|
||||
isOidc: boolean;
|
||||
isExternal: boolean;
|
||||
} | null>(null);
|
||||
|
||||
// Unlink account dialog
|
||||
@@ -242,7 +242,7 @@ export function AdminSettingsPanel({
|
||||
id: user.userId,
|
||||
username: user.username,
|
||||
isAdmin: user.is_admin,
|
||||
isOidc: user.is_external ?? user.is_oidc,
|
||||
isExternal: user.is_external ?? false,
|
||||
passwordHash: user.password_hash,
|
||||
dataUnlocked: user.data_unlocked,
|
||||
secondFactorEnabled: user.second_factor_enabled,
|
||||
@@ -954,7 +954,7 @@ export function AdminSettingsPanel({
|
||||
setUsers((prev) =>
|
||||
prev.map((u) =>
|
||||
u.id === userId
|
||||
? { ...u, isOidc: false, passwordHash: undefined }
|
||||
? { ...u, isExternal: false, passwordHash: undefined }
|
||||
: u,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -116,8 +116,8 @@ export function AdminGeneralSettingsSection({
|
||||
</p>
|
||||
)}
|
||||
<SettingRow
|
||||
label={t("admin.oidcAutoProvision")}
|
||||
description={t("admin.oidcAutoProvisionDesc")}
|
||||
label={t("admin.externalAutoProvision")}
|
||||
description={t("admin.externalAutoProvisionDesc")}
|
||||
>
|
||||
<AdminToggle
|
||||
on={externalAutoProvision}
|
||||
|
||||
@@ -199,10 +199,10 @@ export function AdminEditUserDialog({
|
||||
{t("admin.editUserAuthType")}
|
||||
</span>
|
||||
<span className="text-sm font-semibold">
|
||||
{editUserTarget.isOidc && editUserTarget.passwordHash
|
||||
{editUserTarget.isExternal && editUserTarget.passwordHash
|
||||
? t("admin.authTypeDual")
|
||||
: editUserTarget.isOidc
|
||||
? t("admin.authTypeOidc")
|
||||
: editUserTarget.isExternal
|
||||
? t("admin.authTypeExternal")
|
||||
: t("admin.authTypeLocal")}
|
||||
</span>
|
||||
</div>
|
||||
@@ -469,7 +469,11 @@ export function AdminUnlinkAccountDialog({
|
||||
type LinkAccountDialogProps = {
|
||||
open: boolean;
|
||||
onOpenChange: Dispatch<SetStateAction<boolean>>;
|
||||
linkAccountTarget: { id: string; username: string; isOidc: boolean } | null;
|
||||
linkAccountTarget: {
|
||||
id: string;
|
||||
username: string;
|
||||
isExternal: boolean;
|
||||
} | null;
|
||||
setUsers: Dispatch<SetStateAction<AdminUser[]>>;
|
||||
users: AdminUser[];
|
||||
};
|
||||
@@ -489,7 +493,7 @@ export function AdminLinkAccountDialog({
|
||||
if (open) setOtherUsername("");
|
||||
}, [open, linkAccountTarget]);
|
||||
|
||||
const isOidcInitiator = linkAccountTarget?.isOidc ?? true;
|
||||
const isExternalInitiator = linkAccountTarget?.isExternal ?? true;
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const trimmed = otherUsername.trim();
|
||||
@@ -497,15 +501,15 @@ export function AdminLinkAccountDialog({
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
if (isOidcInitiator) {
|
||||
if (isExternalInitiator) {
|
||||
await linkExternalToPasswordAccount(linkAccountTarget.id, trimmed);
|
||||
setUsers((prev) => prev.filter((u) => u.id !== linkAccountTarget.id));
|
||||
} else {
|
||||
const oidcUser = users.find(
|
||||
(u) => u.username === trimmed && u.isOidc && !u.passwordHash,
|
||||
(u) => u.username === trimmed && u.isExternal && !u.passwordHash,
|
||||
);
|
||||
if (!oidcUser) {
|
||||
toast.error(t("admin.linkAccountOidcNotFound"));
|
||||
toast.error(t("admin.linkAccountExternalNotFound"));
|
||||
return;
|
||||
}
|
||||
await linkExternalToPasswordAccount(
|
||||
@@ -532,7 +536,7 @@ export function AdminLinkAccountDialog({
|
||||
{t("admin.linkAccountTitle")}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-xs text-muted-foreground">
|
||||
{isOidcInitiator
|
||||
{isExternalInitiator
|
||||
? t("admin.linkAccountDesc", {
|
||||
username: linkAccountTarget?.username,
|
||||
})
|
||||
@@ -555,18 +559,18 @@ export function AdminLinkAccountDialog({
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<label className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">
|
||||
{isOidcInitiator
|
||||
{isExternalInitiator
|
||||
? t("admin.linkAccountTargetUsername")
|
||||
: t("admin.linkAccountOidcUsername")}{" "}
|
||||
: t("admin.linkAccountExternalUsername")}{" "}
|
||||
<span className="text-accent-brand">*</span>
|
||||
</label>
|
||||
<Input
|
||||
value={otherUsername}
|
||||
onChange={(e) => setOtherUsername(e.target.value)}
|
||||
placeholder={
|
||||
isOidcInitiator
|
||||
isExternalInitiator
|
||||
? t("admin.linkAccountTargetPlaceholder")
|
||||
: t("admin.linkAccountOidcPlaceholder")
|
||||
: t("admin.linkAccountExternalPlaceholder")
|
||||
}
|
||||
autoFocus
|
||||
disabled={submitting}
|
||||
|
||||
@@ -450,9 +450,9 @@ export function AdminUserManagePanel({
|
||||
{/* Password reset */}
|
||||
<div className="flex flex-col gap-2">
|
||||
{sectionHeading(t("admin.resetPasswordTitle"))}
|
||||
{user.isOidc && !user.passwordHash ? (
|
||||
{user.isExternal && !user.passwordHash ? (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{t("admin.resetPasswordOidcOnly")}
|
||||
{t("admin.resetPasswordExternalOnly")}
|
||||
</span>
|
||||
) : (
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
@@ -182,7 +182,7 @@ export function HostEditor({
|
||||
};
|
||||
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [isOidcUser, setIsOidcUser] = useState(false);
|
||||
const [isExternalUser, setIsExternalUser] = useState(false);
|
||||
const [showSecretSources, setShowSecretSources] = useState(false);
|
||||
const [quickCredentialName, setQuickCredentialName] = useState("");
|
||||
const [creatingQuickCredential, setCreatingQuickCredential] = useState(false);
|
||||
@@ -192,7 +192,7 @@ export function HostEditor({
|
||||
useState<CredentialOption | null>(null);
|
||||
useEffect(() => {
|
||||
getUserInfo()
|
||||
.then((info) => setIsOidcUser(info.is_external ?? info.is_oidc))
|
||||
.then((info) => setIsExternalUser(info.is_external))
|
||||
.catch(() => {});
|
||||
}, []);
|
||||
|
||||
@@ -908,9 +908,9 @@ export function HostEditor({
|
||||
}}
|
||||
onChange={(e) => setField("username", e.target.value)}
|
||||
/>
|
||||
{isOidcUser && (
|
||||
{isExternalUser && (
|
||||
<p className="text-[10px] text-muted-foreground/60">
|
||||
{t("hosts.oidcUsernameHint")}
|
||||
{t("hosts.externalUsernameHint")}
|
||||
</p>
|
||||
)}
|
||||
{activeAuthEditor?.hintKey && (
|
||||
|
||||
@@ -537,7 +537,7 @@ export function UserProfilePanel({
|
||||
"up_to_date" | "requires_update" | "beta" | "unknown"
|
||||
>("up_to_date");
|
||||
const [releaseUrl, setReleaseUrl] = useState("");
|
||||
const [isOidc, setIsOidc] = useState(false);
|
||||
const [isExternal, setIsExternal] = useState(false);
|
||||
const [isDualAuth, setIsDualAuth] = useState(false);
|
||||
|
||||
// Delete account
|
||||
@@ -647,7 +647,7 @@ export function UserProfilePanel({
|
||||
getUserInfo()
|
||||
.then((info) => {
|
||||
setUserId(info.userId);
|
||||
setIsOidc(info.is_external ?? info.is_oidc ?? false);
|
||||
setIsExternal(info.is_external ?? false);
|
||||
setIsDualAuth(info.is_dual_auth ?? false);
|
||||
const linked = info.linked ?? null;
|
||||
setLinkedAccount(linked);
|
||||
@@ -661,8 +661,8 @@ export function UserProfilePanel({
|
||||
);
|
||||
if (info.is_dual_auth) {
|
||||
setAuthMethod(t("newUi.sidebar.userProfile.authMethodDual"));
|
||||
} else if (info.is_external ?? info.is_oidc) {
|
||||
setAuthMethod(t("newUi.sidebar.userProfile.authMethodOidc"));
|
||||
} else if (info.is_external) {
|
||||
setAuthMethod(t("newUi.sidebar.userProfile.authMethodExternal"));
|
||||
} else {
|
||||
setAuthMethod(t("newUi.sidebar.userProfile.authMethodLocal"));
|
||||
}
|
||||
@@ -1181,7 +1181,7 @@ export function UserProfilePanel({
|
||||
}
|
||||
}
|
||||
|
||||
const canChangePasword = !isOidc || isDualAuth;
|
||||
const canChangePasword = !isExternal || isDualAuth;
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex w-full max-w-5xl flex-col gap-2 p-3">
|
||||
|
||||
Reference in new issue
Block a user