mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
* feat: shell controller, TabStage, layout and theme plugins with repair view * feat: move the classic layout into its own bundled plugin * feat: move color themes into a bundled themes plugin * fix: plugin tests and type checks work with a linked sdk * fix: home tab, layout switch and missing layout fallbacks for looks * chore: add classic layout and themes to the readme * chore: drop example plugin links from the plugin guide * feat: plugin filters by type, paged browse, hide plugins needing newer termix * feat: move desktop, status, import, audit and branding features into plugins * feat: host lock api so a plugin can load hosts from a config file (#1581) * chore: add hosts config to the plugin table * feat: login policy hook for plugins and optional https redirect (#1584) * chore: add login security to the plugin table * feat: api key socket tickets so a master can open remote sessions (#1654) * feat: sync moves to a plugin, desktop gets multiple accounts (#1580, #1654) * chore: add sync to the plugin table * feat: move the sync screens and wizard out of core into the plugin (#1580) * fix: add a neutral linked desktop hook for plugins (#1580) * fix: show the linked account's name and admin flag in the app (#1580) * feat: ssh transport providers, core ssh relay and plugin folders api * feat: support FIDO2 security keys through ssh agent * feat: add companion panels beside host tabs * feat: mTLS client certificates for desktop server links * feat: native web view for plugins in the desktop app * fix: detect the desktop link window by Electron's default user agent Fixes #1675 * fix: changelog for desktop link fix * fix: keep text primary keys in the plugin data export * fix: ship sharp binaries for Windows arm64 builds * feat: client cert on the sync link types (sdk 1.0.18) * chore: update translations * feat: themed title bar for the desktop app (#1690) * chore: changelog for the themed title bar * fix: draw the title bar in the sidebar color * feat: per host layout for the terminal panel bar * chore: sdk 1.0.19 for the panel bar layout * chore: bundle all 43 plugins for 26.10.3 * chore: update translations --------- Co-authored-by: SirHephaistos <60616553+SirHephaistos@users.noreply.github.com> Co-authored-by: Giovanny Aranda <garanda21@gmail.com>
117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
/**
|
|
* What a plugin's code may do.
|
|
*
|
|
* A capability is declared in the manifest and checked by the SDK method that
|
|
* needs it. It is not a user permission: those stay in core RBAC and are dotted
|
|
* (hosts.view), while capabilities are colon-separated (hosts:read) so the two
|
|
* can never be confused in a grant table or a log line.
|
|
*
|
|
* Adding one means an entry here plus the SDK method that checks it. The i18n
|
|
* keys resolve against core's en.json under plugins.capabilities.<id>.
|
|
*
|
|
* The copy those keys carry describes the consequence to the person deciding,
|
|
* not the mechanism. "Run commands on your servers", not "grants ssh:connect".
|
|
*/
|
|
|
|
export type CapabilityRisk = "low" | "medium" | "high" | "critical";
|
|
|
|
export interface CapabilityInfo {
|
|
id: string;
|
|
risk: CapabilityRisk;
|
|
/** i18n key for the short consequence, e.g. "Run commands on your servers". */
|
|
titleKey: string;
|
|
/** i18n key for the qualifying sentence under the title. */
|
|
consequenceKey: string;
|
|
}
|
|
|
|
function entry(id: string, risk: CapabilityRisk): CapabilityInfo {
|
|
return {
|
|
id,
|
|
risk,
|
|
titleKey: `plugins.capabilities.${id}.title`,
|
|
consequenceKey: `plugins.capabilities.${id}.consequence`,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Ordered critical -> low. The install and review UI reads this order directly
|
|
* so the worst line is never folded into a summary row.
|
|
*/
|
|
export const CAPABILITY_CATALOG: readonly CapabilityInfo[] = [
|
|
entry("credentials:read", "critical"),
|
|
entry("system:tls", "critical"),
|
|
|
|
entry("ssh:connect", "high"),
|
|
entry("process:spawn", "high"),
|
|
entry("users:write", "high"),
|
|
entry("users:impersonate", "high"),
|
|
entry("db:core-refs", "high"),
|
|
entry("auth:provide", "high"),
|
|
entry("auth:policy", "high"),
|
|
entry("sync:provide", "high"),
|
|
entry("ssh:transport", "high"),
|
|
entry("device:serial", "high"),
|
|
entry("notify:hub", "high"),
|
|
entry("ui:layout", "high"),
|
|
|
|
entry("hosts:write", "medium"),
|
|
entry("hosts:export", "high"),
|
|
entry("credentials:use", "medium"),
|
|
entry("credentials:write", "medium"),
|
|
entry("network:outbound", "medium"),
|
|
entry("network:serve", "medium"),
|
|
entry("network:broadcast", "medium"),
|
|
entry("network:probe", "medium"),
|
|
entry("hosts:status-provide", "medium"),
|
|
entry("hosts:activity-provide", "medium"),
|
|
entry("hosts:lock", "medium"),
|
|
entry("users:read", "medium"),
|
|
entry("events:core", "medium"),
|
|
entry("notify:send", "medium"),
|
|
entry("audit:read", "medium"),
|
|
entry("desktop:window", "medium"),
|
|
entry("desktop:local", "high"),
|
|
|
|
entry("hosts:read", "low"),
|
|
entry("db:own", "low"),
|
|
entry("kv:own", "low"),
|
|
entry("files:own", "low"),
|
|
entry("secrets:own", "low"),
|
|
entry("settings:read-core", "low"),
|
|
entry("plugins:read", "low"),
|
|
entry("ui:surface", "low"),
|
|
entry("ui:theme", "low"),
|
|
] as const;
|
|
|
|
export const CAPABILITY_IDS: readonly string[] = CAPABILITY_CATALOG.map(
|
|
(capability) => capability.id,
|
|
);
|
|
|
|
/**
|
|
* Kept as a string rather than a union of the catalog ids: a capability is
|
|
* data the runtime checks at load time, and a union here would force every
|
|
* caller holding a manifest value to cast.
|
|
*/
|
|
export type Capability = string;
|
|
|
|
const BY_ID = new Map(
|
|
CAPABILITY_CATALOG.map((capability) => [capability.id, capability]),
|
|
);
|
|
|
|
export function isKnownCapability(capability: string): boolean {
|
|
return BY_ID.has(capability);
|
|
}
|
|
|
|
export function getCapabilityInfo(
|
|
capability: string,
|
|
): CapabilityInfo | undefined {
|
|
return BY_ID.get(capability);
|
|
}
|
|
|
|
export const CAPABILITY_RISK_ORDER: readonly CapabilityRisk[] = [
|
|
"critical",
|
|
"high",
|
|
"medium",
|
|
"low",
|
|
];
|