mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
feat: move totp and passkeys into plugins (C1)
This commit is contained in:
1 parent
f4f26a9b8b
commit
5c18435105
235 files changed
+22545
-5610
No files matched your search
@@ -350,6 +350,9 @@ export function createPluginApp(
|
||||
titleKey: key(method.titleKey),
|
||||
pluginId,
|
||||
component: scoped(method.component) as never,
|
||||
enrollment: method.enrollment
|
||||
? (scoped(method.enrollment) as never)
|
||||
: undefined,
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -11,9 +11,9 @@ import { createRegistry } from "@/lib/registry";
|
||||
* SSH auth editors render in the host and credential editors when their auth
|
||||
* type is picked. Login methods render on the login screen for methods the
|
||||
* server reports as enabled; second factors render in the step after a first
|
||||
* login and, when they bring one, in Settings > Security for enrolment.
|
||||
* Core's own (OIDC, LDAP, passkeys, TOTP) register from
|
||||
* src/ui/auth/legacy-auth-ui.tsx until they move into plugins.
|
||||
* login. Either kind may bring an enrolment section for Settings > Security.
|
||||
* Core's own (OIDC, LDAP) register from src/ui/auth/legacy-auth-ui.tsx until
|
||||
* they move into plugins.
|
||||
*/
|
||||
export interface SshAuthEditorDef {
|
||||
/** The authType value stored on the host. */
|
||||
@@ -34,6 +34,9 @@ export interface LoginMethodDef {
|
||||
titleKey: string;
|
||||
icon?: ComponentType<{ className?: string }>;
|
||||
component: ComponentType<LoginMethodUIProps>;
|
||||
/** Also drawn under the password form. */
|
||||
placement?: "inline";
|
||||
enrollment?: ComponentType<Record<string, unknown>>;
|
||||
}
|
||||
|
||||
export interface SecondFactorDef {
|
||||
@@ -55,10 +58,12 @@ export const useSshAuthEditors = sshAuthEditors.useList;
|
||||
export const registerLoginMethod = loginMethods.register;
|
||||
export const getLoginMethodUI = loginMethods.get;
|
||||
export const useLoginMethods = loginMethods.useList;
|
||||
export const listLoginMethodUIs = loginMethods.list;
|
||||
|
||||
export const registerSecondFactor = secondFactors.register;
|
||||
export const getSecondFactorUI = secondFactors.get;
|
||||
export const useSecondFactors = secondFactors.useList;
|
||||
export const listSecondFactorUIs = secondFactors.list;
|
||||
|
||||
export function resetAuthRegistries(): void {
|
||||
sshAuthEditors.reset();
|
||||
|
||||
@@ -42,6 +42,12 @@ import {
|
||||
listSettingsComponents,
|
||||
} from "@/settings/settings-components";
|
||||
import { getSlotContributions, listActions } from "@/shell/action-registry";
|
||||
import {
|
||||
getLoginMethodUI,
|
||||
getSecondFactorUI,
|
||||
listLoginMethodUIs,
|
||||
listSecondFactorUIs,
|
||||
} from "./auth-registry";
|
||||
import { ActionSlot, ComponentSlot } from "@/shell/ActionSlot";
|
||||
import type { Host, Tab } from "@/types/ui-types";
|
||||
import { createPluginApp } from "./app";
|
||||
@@ -223,6 +229,9 @@ export async function renderPlugin(
|
||||
(contribution) => contribution.actionId,
|
||||
),
|
||||
actions: () => mine(listActions()).map((action) => action.id),
|
||||
loginMethods: () => mine(listLoginMethodUIs()).map((method) => method.id),
|
||||
secondFactors: () =>
|
||||
mine(listSecondFactorUIs()).map((factor) => factor.id),
|
||||
},
|
||||
|
||||
renderTab(type, props = {}) {
|
||||
@@ -315,6 +324,46 @@ export async function renderPlugin(
|
||||
);
|
||||
},
|
||||
|
||||
renderLoginMethod(id, props = {}) {
|
||||
const method = getLoginMethodUI(id) ?? missing("a login method", id);
|
||||
const Component = method.component;
|
||||
return wrap(
|
||||
<Component
|
||||
methodId={id}
|
||||
instances={[]}
|
||||
rememberMe={false}
|
||||
disabled={false}
|
||||
submit={async () => {}}
|
||||
startRedirect={async () => {}}
|
||||
complete={async () => {}}
|
||||
{...props}
|
||||
/>,
|
||||
);
|
||||
},
|
||||
|
||||
renderSecondFactor(id, props = {}) {
|
||||
const factor = getSecondFactorUI(id) ?? missing("a second factor", id);
|
||||
const Component = factor.component;
|
||||
return wrap(
|
||||
<Component
|
||||
factorId={id}
|
||||
rememberMe={false}
|
||||
disabled={false}
|
||||
verify={async () => {}}
|
||||
challenge={async () => null}
|
||||
cancel={() => {}}
|
||||
{...props}
|
||||
/>,
|
||||
);
|
||||
},
|
||||
|
||||
renderEnrollment(id) {
|
||||
const entry = getSecondFactorUI(id) ?? getLoginMethodUI(id);
|
||||
const Component =
|
||||
entry?.enrollment ?? missing("an enrolment section", id);
|
||||
return wrap(<Component />);
|
||||
},
|
||||
|
||||
renderSlot(slotId, props = {}) {
|
||||
return wrap(
|
||||
<>
|
||||
|
||||
Reference in new issue
Block a user