@termix-ssh/plugin-sdk 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/PLUGIN-GUIDE.md +780 -0
- package/README.md +2 -1
- package/cli/commands/build.mjs +7 -7
- package/cli/commands/migrations.mjs +2 -2
- package/cli/commands/validate.mjs +5 -0
- package/cli/index.mjs +0 -0
- package/dist/changelog.d.ts +3 -1
- package/dist/changelog.js +12 -2
- package/dist/db.d.ts +1 -1
- package/dist/db.js +1 -1
- package/dist/ddl.js +4 -1
- package/dist/host/{chunk-RU4E5XLY.js → chunk-26DAYAKC.js} +323 -216
- package/dist/host/{chunk-O2OHNVFX.js → chunk-DIOJ3KW2.js} +1 -1
- package/dist/host/{chunk-F5RZH6HE.js → chunk-NZG6HNQH.js} +14 -13
- package/dist/host/core-classes.json +1 -1
- package/dist/host/{linked-server-4VWYYABP.js → linked-server-QAKKDBFM.js} +1 -1
- package/dist/host/{rbac-api-WIJVZH3M.js → rbac-api-5267EMX7.js} +1 -1
- package/dist/host/testing-host.js +3 -3
- package/dist/host/types/src/types/credential-sidebar-preferences.d.ts +1 -1
- package/dist/host/types/src/types/onboarding.d.ts +1 -0
- package/dist/host/types/src/ui/api/plugins-api.d.ts +51 -0
- package/dist/host/types/src/ui/components/panel-layout.d.ts +0 -4
- package/dist/host/types/src/ui/hooks/use-mobile.d.ts +1 -0
- package/dist/host/types/src/ui/i18n/i18n.d.ts +1 -36
- package/dist/host/types/src/ui/i18n/languages.d.ts +13 -0
- package/dist/host/types/src/ui/lib/error-message.d.ts +1 -1
- package/dist/host/types/src/ui/lib/host-key-fingerprint.d.ts +5 -0
- package/dist/host/types/src/ui/lib/server-time.d.ts +5 -0
- package/dist/host/types/src/ui/main-axios.d.ts +5 -2
- package/dist/host/types/src/ui/ssh/dialogs/HostKeyVerificationDialog.d.ts +1 -1
- package/dist/host/ui.js +439 -69
- package/dist/host/{use-permissions-KIQCJ35M.js → use-permissions-2P2TP6GY.js} +1 -1
- package/dist/host-commands.js +1 -1
- package/package.json +14 -1
package/dist/host/ui.js
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
GroupHeading,
|
|
33
33
|
InlineView,
|
|
34
34
|
KeyRound,
|
|
35
|
+
LANGUAGES,
|
|
35
36
|
List,
|
|
36
37
|
LoaderCircle,
|
|
37
38
|
Overlay2,
|
|
@@ -138,8 +139,8 @@ import {
|
|
|
138
139
|
useSurfaceKind,
|
|
139
140
|
useTheme,
|
|
140
141
|
verifySecondFactor
|
|
141
|
-
} from "./chunk-
|
|
142
|
-
import "./chunk-
|
|
142
|
+
} from "./chunk-26DAYAKC.js";
|
|
143
|
+
import "./chunk-DIOJ3KW2.js";
|
|
143
144
|
import {
|
|
144
145
|
TabProvider,
|
|
145
146
|
buildOriginWsUrl,
|
|
@@ -178,7 +179,7 @@ import {
|
|
|
178
179
|
useTabs,
|
|
179
180
|
useTabsSafe,
|
|
180
181
|
verifyPasswordResetCode
|
|
181
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-NZG6HNQH.js";
|
|
182
183
|
import "./chunk-YC2MAKSP.js";
|
|
183
184
|
|
|
184
185
|
// src/ui/components/alert.tsx
|
|
@@ -1501,7 +1502,7 @@ function Switch2({
|
|
|
1501
1502
|
{
|
|
1502
1503
|
"data-slot": "switch",
|
|
1503
1504
|
className: cn(
|
|
1504
|
-
"peer
|
|
1505
|
+
"peer relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center border-2 transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-accent-brand data-[state=checked]:border-accent-brand data-[state=unchecked]:bg-muted data-[state=unchecked]:border-border",
|
|
1505
1506
|
className
|
|
1506
1507
|
),
|
|
1507
1508
|
...props,
|
|
@@ -1509,9 +1510,7 @@ function Switch2({
|
|
|
1509
1510
|
SwitchThumb,
|
|
1510
1511
|
{
|
|
1511
1512
|
"data-slot": "switch-thumb",
|
|
1512
|
-
className:
|
|
1513
|
-
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
|
|
1514
|
-
)
|
|
1513
|
+
className: "pointer-events-none block h-3 w-3 bg-background shadow-sm transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0.5"
|
|
1515
1514
|
}
|
|
1516
1515
|
)
|
|
1517
1516
|
}
|
|
@@ -2050,16 +2049,21 @@ function MiniStat({
|
|
|
2050
2049
|
|
|
2051
2050
|
// src/ui/components/charts/LineChart.tsx
|
|
2052
2051
|
import { useRef, useState as useState4, useEffect as useEffect2, useCallback } from "react";
|
|
2052
|
+
|
|
2053
|
+
// src/ui/lib/server-time.ts
|
|
2054
|
+
function parseServerTime(ts) {
|
|
2055
|
+
const bare = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/.test(ts);
|
|
2056
|
+
return new Date(bare ? `${ts.replace(" ", "T")}Z` : ts);
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
// src/ui/components/charts/LineChart.tsx
|
|
2053
2060
|
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2054
2061
|
var Y_LABEL_W = 44;
|
|
2055
2062
|
var X_LABEL_H = 20;
|
|
2056
2063
|
var TOP_PAD = 6;
|
|
2057
2064
|
var TICK_COUNT = 5;
|
|
2058
|
-
function parseTs(ts) {
|
|
2059
|
-
return new Date(ts.includes("T") ? ts : ts.replace(" ", "T") + "Z");
|
|
2060
|
-
}
|
|
2061
2065
|
function formatTimestamp(ts, rangeMs) {
|
|
2062
|
-
const d =
|
|
2066
|
+
const d = parseServerTime(ts);
|
|
2063
2067
|
if (rangeMs <= 25 * 60 * 60 * 1e3) {
|
|
2064
2068
|
return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
2065
2069
|
}
|
|
@@ -2114,7 +2118,7 @@ function LineChart({
|
|
|
2114
2118
|
const chartW = Math.max(0, width - Y_LABEL_W);
|
|
2115
2119
|
const drawH = height - TOP_PAD;
|
|
2116
2120
|
const svgH = height + X_LABEL_H;
|
|
2117
|
-
const rangeMs = timestamps.length >= 2 ?
|
|
2121
|
+
const rangeMs = timestamps.length >= 2 ? parseServerTime(timestamps[timestamps.length - 1]).getTime() - parseServerTime(timestamps[0]).getTime() : 0;
|
|
2118
2122
|
const yTicks = (() => {
|
|
2119
2123
|
const [lo, hi] = domain;
|
|
2120
2124
|
const step = (hi - lo) / (TICK_COUNT - 1);
|
|
@@ -2323,6 +2327,10 @@ function useIsMobile() {
|
|
|
2323
2327
|
void 0
|
|
2324
2328
|
);
|
|
2325
2329
|
React5.useEffect(() => {
|
|
2330
|
+
if (isElectron()) {
|
|
2331
|
+
setIsMobile(false);
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2326
2334
|
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
2327
2335
|
const onChange = () => {
|
|
2328
2336
|
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
@@ -4348,12 +4356,15 @@ async function loadNamespaces(summaries) {
|
|
|
4348
4356
|
loadedNamespaceVersions.set(summary.id, namespaceVersion(summary));
|
|
4349
4357
|
}
|
|
4350
4358
|
}
|
|
4359
|
+
function serverServesAssets(summary) {
|
|
4360
|
+
return summary.enabled && (!summary.state || summary.state === "active");
|
|
4361
|
+
}
|
|
4351
4362
|
function namespaceVersion(summary) {
|
|
4352
4363
|
return `${summary.version}|${summary.assetVersion ?? ""}`;
|
|
4353
4364
|
}
|
|
4354
4365
|
async function reconcile(summaries) {
|
|
4355
4366
|
setPluginSummaries(summaries);
|
|
4356
|
-
await loadNamespaces(summaries);
|
|
4367
|
+
await loadNamespaces(summaries.filter(serverServesAssets));
|
|
4357
4368
|
const { order, blocked } = orderForActivation(summaries);
|
|
4358
4369
|
const wanted = new Map(order.map((summary) => [summary.id, summary]));
|
|
4359
4370
|
for (const id of [...active.keys()].reverse()) {
|
|
@@ -4428,6 +4439,13 @@ function syncPlugins(summaries) {
|
|
|
4428
4439
|
import.meta.hot?.on("termix:plugins-reloaded", () => {
|
|
4429
4440
|
if (started) void syncPlugins();
|
|
4430
4441
|
});
|
|
4442
|
+
function installLocaleResolver() {
|
|
4443
|
+
setPluginLocaleResolver((namespace, _language, file) => {
|
|
4444
|
+
const summary = getPluginRecord(namespace)?.summary;
|
|
4445
|
+
if (!summary) return Promise.resolve(null);
|
|
4446
|
+
return currentDeps().loadLocale(summary, file);
|
|
4447
|
+
});
|
|
4448
|
+
}
|
|
4431
4449
|
async function fetchPreLoginPlugins() {
|
|
4432
4450
|
const response = await fetch(getBackendUrl("/plugins/public-manifest"));
|
|
4433
4451
|
if (!response.ok) return [];
|
|
@@ -4443,11 +4461,7 @@ async function startPreLoginPlugins(options = {}) {
|
|
|
4443
4461
|
return;
|
|
4444
4462
|
}
|
|
4445
4463
|
if (list.length === 0 || started) return;
|
|
4446
|
-
|
|
4447
|
-
const summary = getPluginRecord(namespace)?.summary;
|
|
4448
|
-
if (!summary) return Promise.resolve(null);
|
|
4449
|
-
return currentDeps().loadLocale(summary, file);
|
|
4450
|
-
});
|
|
4464
|
+
installLocaleResolver();
|
|
4451
4465
|
await enqueue(async () => {
|
|
4452
4466
|
if (started) return;
|
|
4453
4467
|
if (options.retryFailed) {
|
|
@@ -4542,43 +4556,6 @@ function removeSilentSigninFromSearch(search) {
|
|
|
4542
4556
|
|
|
4543
4557
|
// src/ui/auth/Auth.tsx
|
|
4544
4558
|
import { Fragment as Fragment5, jsx as jsx40, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
4545
|
-
var LANGUAGES = [
|
|
4546
|
-
{ code: "en", label: "English" },
|
|
4547
|
-
{ code: "af", label: "Afrikaans" },
|
|
4548
|
-
{ code: "ar", label: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629" },
|
|
4549
|
-
{ code: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE" },
|
|
4550
|
-
{ code: "bg", label: "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438" },
|
|
4551
|
-
{ code: "ca", label: "Catal\xE0" },
|
|
4552
|
-
{ code: "zh-CN", label: "\u4E2D\u6587 (\u7B80\u4F53)" },
|
|
4553
|
-
{ code: "zh-TW", label: "\u4E2D\u6587 (\u7E41\u9AD4)" },
|
|
4554
|
-
{ code: "cs", label: "\u010Ce\u0161tina" },
|
|
4555
|
-
{ code: "da", label: "Dansk" },
|
|
4556
|
-
{ code: "nl", label: "Nederlands" },
|
|
4557
|
-
{ code: "fi", label: "Suomi" },
|
|
4558
|
-
{ code: "fr", label: "Fran\xE7ais" },
|
|
4559
|
-
{ code: "de", label: "Deutsch" },
|
|
4560
|
-
{ code: "el", label: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC" },
|
|
4561
|
-
{ code: "he", label: "\u05E2\u05D1\u05E8\u05D9\u05EA" },
|
|
4562
|
-
{ code: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940" },
|
|
4563
|
-
{ code: "hu", label: "Magyar" },
|
|
4564
|
-
{ code: "id", label: "Indonesia" },
|
|
4565
|
-
{ code: "it", label: "Italiano" },
|
|
4566
|
-
{ code: "ja", label: "\u65E5\u672C\u8A9E" },
|
|
4567
|
-
{ code: "ko", label: "\uD55C\uAD6D\uC5B4" },
|
|
4568
|
-
{ code: "no", label: "Norsk" },
|
|
4569
|
-
{ code: "pl", label: "Polski" },
|
|
4570
|
-
{ code: "pt-PT", label: "Portugu\xEAs (PT)" },
|
|
4571
|
-
{ code: "pt-BR", label: "Portugu\xEAs (BR)" },
|
|
4572
|
-
{ code: "ro", label: "Rom\xE2n\u0103" },
|
|
4573
|
-
{ code: "ru", label: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439" },
|
|
4574
|
-
{ code: "sr", label: "\u0421\u0440\u043F\u0441\u043A\u0438" },
|
|
4575
|
-
{ code: "es-ES", label: "Espa\xF1ol" },
|
|
4576
|
-
{ code: "sv-SE", label: "Svenska" },
|
|
4577
|
-
{ code: "th", label: "\u0E44\u0E17\u0E22" },
|
|
4578
|
-
{ code: "tr", label: "T\xFCrk\xE7e" },
|
|
4579
|
-
{ code: "uk", label: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430" },
|
|
4580
|
-
{ code: "vi", label: "Ti\u1EBFng Vi\u1EC7t" }
|
|
4581
|
-
];
|
|
4582
4559
|
function LanguageRow({
|
|
4583
4560
|
label,
|
|
4584
4561
|
value,
|
|
@@ -5028,6 +5005,10 @@ function Auth({ onLogin }) {
|
|
|
5028
5005
|
toast2.error(t2("auth.secondFactorUnavailable"));
|
|
5029
5006
|
return;
|
|
5030
5007
|
}
|
|
5008
|
+
if (error?.response?.data?.code === "external_login_required") {
|
|
5009
|
+
toast2.error(t2("auth.externalLoginRequired"));
|
|
5010
|
+
return;
|
|
5011
|
+
}
|
|
5031
5012
|
toast2.error(
|
|
5032
5013
|
error?.response?.data?.error || error?.message || t2(fallbackKey)
|
|
5033
5014
|
);
|
|
@@ -30167,8 +30148,396 @@ function PassphraseDialog({
|
|
|
30167
30148
|
// src/ui/ssh/dialogs/HostKeyVerificationDialog.tsx
|
|
30168
30149
|
import { useState as useState18 } from "react";
|
|
30169
30150
|
import { useTranslation as useTranslation18 } from "react-i18next";
|
|
30151
|
+
|
|
30152
|
+
// node_modules/@noble/hashes/_u64.js
|
|
30153
|
+
var fromNumH = (n) => n / 2 ** 32 | 0;
|
|
30154
|
+
var fromNumL = (n) => n >>> 0;
|
|
30155
|
+
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
30156
|
+
const h = fromNumH(n);
|
|
30157
|
+
const l = fromNumL(n);
|
|
30158
|
+
view.setUint32(byteOffset, isLE ? l : h, isLE);
|
|
30159
|
+
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
30160
|
+
}
|
|
30161
|
+
|
|
30162
|
+
// node_modules/@noble/hashes/utils.js
|
|
30163
|
+
function isBytes(a) {
|
|
30164
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
30165
|
+
}
|
|
30166
|
+
var atitle = (title) => title ? `"${title}" ` : "";
|
|
30167
|
+
function anumber(n, title = "") {
|
|
30168
|
+
if (typeof n !== "number")
|
|
30169
|
+
throw new TypeError(atitle(title) + "expected number, got " + typeof n);
|
|
30170
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
30171
|
+
throw new RangeError(atitle(title) + "expected integer >= 0, got " + n);
|
|
30172
|
+
return n;
|
|
30173
|
+
}
|
|
30174
|
+
function abytes(value, length, title = "") {
|
|
30175
|
+
if (isBytes(value) && (length === void 0 || value.length === length))
|
|
30176
|
+
return value;
|
|
30177
|
+
if (length !== void 0)
|
|
30178
|
+
anumber(length, "length");
|
|
30179
|
+
const bytes = isBytes(value);
|
|
30180
|
+
const ofLen = length !== void 0 ? ` of length ${length}` : "";
|
|
30181
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
30182
|
+
const message = atitle(title) + "expected Uint8Array" + ofLen + ", got " + got;
|
|
30183
|
+
if (!bytes)
|
|
30184
|
+
throw new TypeError(message);
|
|
30185
|
+
throw new RangeError(message);
|
|
30186
|
+
}
|
|
30187
|
+
var aobject = (value, label) => {
|
|
30188
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
30189
|
+
throw new TypeError((label === "object" ? "" : `"${label}" `) + "expected object, got type=" + typeof value);
|
|
30190
|
+
};
|
|
30191
|
+
var aopts = (value, label) => {
|
|
30192
|
+
aobject(value, label);
|
|
30193
|
+
const proto = Object.getPrototypeOf(value);
|
|
30194
|
+
if (proto !== Object.prototype && proto !== null)
|
|
30195
|
+
throw new TypeError(`"${label}" expected plain object`);
|
|
30196
|
+
if (Object.hasOwn(value, "__proto__"))
|
|
30197
|
+
throw new TypeError(`"${label}.__proto__" is not allowed`);
|
|
30198
|
+
};
|
|
30199
|
+
function aexists(instance, checkFinished = true) {
|
|
30200
|
+
if (instance.destroyed)
|
|
30201
|
+
throw new Error("hash was destroyed");
|
|
30202
|
+
if (checkFinished && instance.finished)
|
|
30203
|
+
throw new Error("digest() was already called");
|
|
30204
|
+
}
|
|
30205
|
+
function aoutput(out, instance) {
|
|
30206
|
+
abytes(out, void 0, "output");
|
|
30207
|
+
const min = instance.outputLen;
|
|
30208
|
+
if (!(out.length >= min)) {
|
|
30209
|
+
throw new RangeError('"output" expected length >= ' + min);
|
|
30210
|
+
}
|
|
30211
|
+
}
|
|
30212
|
+
function clean(...arrays) {
|
|
30213
|
+
for (let i2 = 0; i2 < arrays.length; i2++) {
|
|
30214
|
+
arrays[i2].fill(0);
|
|
30215
|
+
}
|
|
30216
|
+
}
|
|
30217
|
+
function createView(arr) {
|
|
30218
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
30219
|
+
}
|
|
30220
|
+
function rotr(word, shift2) {
|
|
30221
|
+
return word << 32 - shift2 | word >>> shift2;
|
|
30222
|
+
}
|
|
30223
|
+
function checkOpts(defaults3, opts, title = "opts") {
|
|
30224
|
+
aopts(defaults3, "defaults");
|
|
30225
|
+
if (opts !== void 0)
|
|
30226
|
+
aopts(opts, title);
|
|
30227
|
+
const merged = Object.assign(/* @__PURE__ */ Object.create(null), defaults3, opts);
|
|
30228
|
+
return merged;
|
|
30229
|
+
}
|
|
30230
|
+
function createHasher(hashCons, info = {}) {
|
|
30231
|
+
if (typeof hashCons !== "function")
|
|
30232
|
+
throw new TypeError('"hashCons" expected function, got type=' + typeof hashCons);
|
|
30233
|
+
info = checkOpts({}, info, "info");
|
|
30234
|
+
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
30235
|
+
const tmp = hashCons(void 0);
|
|
30236
|
+
hashC.outputLen = tmp.outputLen;
|
|
30237
|
+
hashC.blockLen = tmp.blockLen;
|
|
30238
|
+
hashC.canXOF = tmp.canXOF;
|
|
30239
|
+
hashC.create = (opts) => hashCons(opts);
|
|
30240
|
+
Object.assign(hashC, info);
|
|
30241
|
+
return Object.freeze(hashC);
|
|
30242
|
+
}
|
|
30243
|
+
var oidNist = (suffix) => ({
|
|
30244
|
+
// Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.
|
|
30245
|
+
// Larger suffix values would need base-128 OID encoding and a different length byte.
|
|
30246
|
+
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
30247
|
+
});
|
|
30248
|
+
|
|
30249
|
+
// node_modules/@noble/hashes/_md.js
|
|
30250
|
+
function Chi(a, b, c) {
|
|
30251
|
+
return a & b ^ ~a & c;
|
|
30252
|
+
}
|
|
30253
|
+
function Maj(a, b, c) {
|
|
30254
|
+
return a & b ^ a & c ^ b & c;
|
|
30255
|
+
}
|
|
30256
|
+
var HashMD = class {
|
|
30257
|
+
blockLen;
|
|
30258
|
+
outputLen;
|
|
30259
|
+
canXOF = false;
|
|
30260
|
+
padOffset;
|
|
30261
|
+
isLE;
|
|
30262
|
+
// For partial updates less than block size
|
|
30263
|
+
buffer;
|
|
30264
|
+
view;
|
|
30265
|
+
finished = false;
|
|
30266
|
+
length = 0;
|
|
30267
|
+
pos = 0;
|
|
30268
|
+
destroyed = false;
|
|
30269
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
30270
|
+
this.blockLen = blockLen;
|
|
30271
|
+
this.outputLen = outputLen;
|
|
30272
|
+
this.padOffset = padOffset;
|
|
30273
|
+
this.isLE = isLE;
|
|
30274
|
+
this.buffer = new Uint8Array(blockLen);
|
|
30275
|
+
this.view = createView(this.buffer);
|
|
30276
|
+
}
|
|
30277
|
+
update(data) {
|
|
30278
|
+
aexists(this);
|
|
30279
|
+
abytes(data);
|
|
30280
|
+
const { view, buffer, blockLen } = this;
|
|
30281
|
+
const len = data.length;
|
|
30282
|
+
let processed = false;
|
|
30283
|
+
for (let pos = 0; pos < len; ) {
|
|
30284
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
30285
|
+
if (take === blockLen) {
|
|
30286
|
+
const dataView = createView(data);
|
|
30287
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
30288
|
+
this.process(dataView, pos);
|
|
30289
|
+
processed = true;
|
|
30290
|
+
continue;
|
|
30291
|
+
}
|
|
30292
|
+
buffer.set(pos === 0 && take === len ? data : data.subarray(pos, pos + take), this.pos);
|
|
30293
|
+
this.pos += take;
|
|
30294
|
+
pos += take;
|
|
30295
|
+
if (this.pos === blockLen) {
|
|
30296
|
+
this.process(view, 0);
|
|
30297
|
+
this.pos = 0;
|
|
30298
|
+
processed = true;
|
|
30299
|
+
}
|
|
30300
|
+
}
|
|
30301
|
+
this.length += data.length;
|
|
30302
|
+
if (processed)
|
|
30303
|
+
this.roundClean();
|
|
30304
|
+
return this;
|
|
30305
|
+
}
|
|
30306
|
+
digestInto(out) {
|
|
30307
|
+
aexists(this);
|
|
30308
|
+
aoutput(out, this);
|
|
30309
|
+
this.finished = true;
|
|
30310
|
+
const { buffer, view, blockLen, isLE } = this;
|
|
30311
|
+
let { pos } = this;
|
|
30312
|
+
buffer[pos++] = 128;
|
|
30313
|
+
buffer.fill(0, pos);
|
|
30314
|
+
if (this.padOffset > blockLen - pos) {
|
|
30315
|
+
this.process(view, 0);
|
|
30316
|
+
buffer.fill(0);
|
|
30317
|
+
}
|
|
30318
|
+
setU64FromNum(view, blockLen - 8, this.length * 8, isLE);
|
|
30319
|
+
this.process(view, 0);
|
|
30320
|
+
this.roundClean();
|
|
30321
|
+
const oview = out === buffer ? view : createView(out);
|
|
30322
|
+
const len = this.outputLen;
|
|
30323
|
+
const outLen = len / 4;
|
|
30324
|
+
const state = this.get();
|
|
30325
|
+
if (len % 4 || outLen > state.length)
|
|
30326
|
+
throw new Error("invalid outputLen");
|
|
30327
|
+
for (let i2 = 0; i2 < outLen; i2++)
|
|
30328
|
+
oview.setUint32(4 * i2, state[i2], isLE);
|
|
30329
|
+
}
|
|
30330
|
+
digest() {
|
|
30331
|
+
const { buffer, outputLen } = this;
|
|
30332
|
+
this.digestInto(buffer);
|
|
30333
|
+
const res = buffer.slice(0, outputLen);
|
|
30334
|
+
this.destroy();
|
|
30335
|
+
return res;
|
|
30336
|
+
}
|
|
30337
|
+
_cloneIntoMeta(to) {
|
|
30338
|
+
const { buffer, length, finished, destroyed, pos } = this;
|
|
30339
|
+
to.destroyed = destroyed;
|
|
30340
|
+
to.finished = finished;
|
|
30341
|
+
to.length = length;
|
|
30342
|
+
to.pos = pos;
|
|
30343
|
+
if (pos)
|
|
30344
|
+
to.buffer.set(buffer);
|
|
30345
|
+
return to;
|
|
30346
|
+
}
|
|
30347
|
+
clone() {
|
|
30348
|
+
return this._cloneInto();
|
|
30349
|
+
}
|
|
30350
|
+
};
|
|
30351
|
+
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
30352
|
+
1779033703,
|
|
30353
|
+
3144134277,
|
|
30354
|
+
1013904242,
|
|
30355
|
+
2773480762,
|
|
30356
|
+
1359893119,
|
|
30357
|
+
2600822924,
|
|
30358
|
+
528734635,
|
|
30359
|
+
1541459225
|
|
30360
|
+
]);
|
|
30361
|
+
|
|
30362
|
+
// node_modules/@noble/hashes/sha2.js
|
|
30363
|
+
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
30364
|
+
1116352408,
|
|
30365
|
+
1899447441,
|
|
30366
|
+
3049323471,
|
|
30367
|
+
3921009573,
|
|
30368
|
+
961987163,
|
|
30369
|
+
1508970993,
|
|
30370
|
+
2453635748,
|
|
30371
|
+
2870763221,
|
|
30372
|
+
3624381080,
|
|
30373
|
+
310598401,
|
|
30374
|
+
607225278,
|
|
30375
|
+
1426881987,
|
|
30376
|
+
1925078388,
|
|
30377
|
+
2162078206,
|
|
30378
|
+
2614888103,
|
|
30379
|
+
3248222580,
|
|
30380
|
+
3835390401,
|
|
30381
|
+
4022224774,
|
|
30382
|
+
264347078,
|
|
30383
|
+
604807628,
|
|
30384
|
+
770255983,
|
|
30385
|
+
1249150122,
|
|
30386
|
+
1555081692,
|
|
30387
|
+
1996064986,
|
|
30388
|
+
2554220882,
|
|
30389
|
+
2821834349,
|
|
30390
|
+
2952996808,
|
|
30391
|
+
3210313671,
|
|
30392
|
+
3336571891,
|
|
30393
|
+
3584528711,
|
|
30394
|
+
113926993,
|
|
30395
|
+
338241895,
|
|
30396
|
+
666307205,
|
|
30397
|
+
773529912,
|
|
30398
|
+
1294757372,
|
|
30399
|
+
1396182291,
|
|
30400
|
+
1695183700,
|
|
30401
|
+
1986661051,
|
|
30402
|
+
2177026350,
|
|
30403
|
+
2456956037,
|
|
30404
|
+
2730485921,
|
|
30405
|
+
2820302411,
|
|
30406
|
+
3259730800,
|
|
30407
|
+
3345764771,
|
|
30408
|
+
3516065817,
|
|
30409
|
+
3600352804,
|
|
30410
|
+
4094571909,
|
|
30411
|
+
275423344,
|
|
30412
|
+
430227734,
|
|
30413
|
+
506948616,
|
|
30414
|
+
659060556,
|
|
30415
|
+
883997877,
|
|
30416
|
+
958139571,
|
|
30417
|
+
1322822218,
|
|
30418
|
+
1537002063,
|
|
30419
|
+
1747873779,
|
|
30420
|
+
1955562222,
|
|
30421
|
+
2024104815,
|
|
30422
|
+
2227730452,
|
|
30423
|
+
2361852424,
|
|
30424
|
+
2428436474,
|
|
30425
|
+
2756734187,
|
|
30426
|
+
3204031479,
|
|
30427
|
+
3329325298
|
|
30428
|
+
]);
|
|
30429
|
+
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
30430
|
+
var SHA2_32B = class extends HashMD {
|
|
30431
|
+
// We cannot use array here since array allows indexing by variable
|
|
30432
|
+
// which means optimizer/compiler cannot use registers.
|
|
30433
|
+
// Numeric initializers matter: starting the fields as `undefined` changes
|
|
30434
|
+
// V8's field representation and makes sha256 3x slower (measured).
|
|
30435
|
+
A = 0;
|
|
30436
|
+
B = 0;
|
|
30437
|
+
C = 0;
|
|
30438
|
+
D = 0;
|
|
30439
|
+
E = 0;
|
|
30440
|
+
F = 0;
|
|
30441
|
+
G = 0;
|
|
30442
|
+
H = 0;
|
|
30443
|
+
constructor(outputLen, IV) {
|
|
30444
|
+
super(64, outputLen, 8, false);
|
|
30445
|
+
this.A = IV[0] | 0;
|
|
30446
|
+
this.B = IV[1] | 0;
|
|
30447
|
+
this.C = IV[2] | 0;
|
|
30448
|
+
this.D = IV[3] | 0;
|
|
30449
|
+
this.E = IV[4] | 0;
|
|
30450
|
+
this.F = IV[5] | 0;
|
|
30451
|
+
this.G = IV[6] | 0;
|
|
30452
|
+
this.H = IV[7] | 0;
|
|
30453
|
+
}
|
|
30454
|
+
get() {
|
|
30455
|
+
const { A, B, C: C2, D, E, F, G, H } = this;
|
|
30456
|
+
return [A, B, C2, D, E, F, G, H];
|
|
30457
|
+
}
|
|
30458
|
+
// prettier-ignore
|
|
30459
|
+
set(A, B, C2, D, E, F, G, H) {
|
|
30460
|
+
this.A = A | 0;
|
|
30461
|
+
this.B = B | 0;
|
|
30462
|
+
this.C = C2 | 0;
|
|
30463
|
+
this.D = D | 0;
|
|
30464
|
+
this.E = E | 0;
|
|
30465
|
+
this.F = F | 0;
|
|
30466
|
+
this.G = G | 0;
|
|
30467
|
+
this.H = H | 0;
|
|
30468
|
+
}
|
|
30469
|
+
_cloneInto(to) {
|
|
30470
|
+
(to ||= new this.constructor()).set(...this.get());
|
|
30471
|
+
return this._cloneIntoMeta(to);
|
|
30472
|
+
}
|
|
30473
|
+
process(view, offset) {
|
|
30474
|
+
for (let i2 = 0; i2 < 16; i2++, offset += 4)
|
|
30475
|
+
SHA256_W[i2] = view.getUint32(offset, false);
|
|
30476
|
+
for (let i2 = 16; i2 < 64; i2++) {
|
|
30477
|
+
const W15 = SHA256_W[i2 - 15];
|
|
30478
|
+
const W2 = SHA256_W[i2 - 2];
|
|
30479
|
+
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
30480
|
+
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
30481
|
+
SHA256_W[i2] = s1 + SHA256_W[i2 - 7] + s0 + SHA256_W[i2 - 16] | 0;
|
|
30482
|
+
}
|
|
30483
|
+
let { A, B, C: C2, D, E, F, G, H } = this;
|
|
30484
|
+
for (let i2 = 0; i2 < 64; i2++) {
|
|
30485
|
+
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
30486
|
+
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i2] + SHA256_W[i2] | 0;
|
|
30487
|
+
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
30488
|
+
const T2 = sigma0 + Maj(A, B, C2) | 0;
|
|
30489
|
+
H = G;
|
|
30490
|
+
G = F;
|
|
30491
|
+
F = E;
|
|
30492
|
+
E = D + T1 | 0;
|
|
30493
|
+
D = C2;
|
|
30494
|
+
C2 = B;
|
|
30495
|
+
B = A;
|
|
30496
|
+
A = T1 + T2 | 0;
|
|
30497
|
+
}
|
|
30498
|
+
A = A + this.A | 0;
|
|
30499
|
+
B = B + this.B | 0;
|
|
30500
|
+
C2 = C2 + this.C | 0;
|
|
30501
|
+
D = D + this.D | 0;
|
|
30502
|
+
E = E + this.E | 0;
|
|
30503
|
+
F = F + this.F | 0;
|
|
30504
|
+
G = G + this.G | 0;
|
|
30505
|
+
H = H + this.H | 0;
|
|
30506
|
+
this.set(A, B, C2, D, E, F, G, H);
|
|
30507
|
+
}
|
|
30508
|
+
roundClean() {
|
|
30509
|
+
clean(SHA256_W);
|
|
30510
|
+
}
|
|
30511
|
+
destroy() {
|
|
30512
|
+
this.destroyed = true;
|
|
30513
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
30514
|
+
clean(this.buffer);
|
|
30515
|
+
}
|
|
30516
|
+
};
|
|
30517
|
+
var _SHA256 = class extends SHA2_32B {
|
|
30518
|
+
constructor() {
|
|
30519
|
+
super(32, SHA256_IV);
|
|
30520
|
+
}
|
|
30521
|
+
};
|
|
30522
|
+
var sha256 = /* @__PURE__ */ createHasher(
|
|
30523
|
+
() => new _SHA256(),
|
|
30524
|
+
/* @__PURE__ */ oidNist(1)
|
|
30525
|
+
);
|
|
30526
|
+
|
|
30527
|
+
// src/ui/lib/host-key-fingerprint.ts
|
|
30528
|
+
function hostKeyFingerprint(hex) {
|
|
30529
|
+
if (!hex || hex.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(hex)) return hex;
|
|
30530
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
30531
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
30532
|
+
bytes[i2] = parseInt(hex.slice(i2 * 2, i2 * 2 + 2), 16);
|
|
30533
|
+
}
|
|
30534
|
+
let binary = "";
|
|
30535
|
+
for (const byte of sha256(bytes)) binary += String.fromCharCode(byte);
|
|
30536
|
+
return `SHA256:${btoa(binary).replace(/=+$/, "")}`;
|
|
30537
|
+
}
|
|
30538
|
+
|
|
30539
|
+
// src/ui/ssh/dialogs/HostKeyVerificationDialog.tsx
|
|
30170
30540
|
import { Fragment as Fragment7, jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
30171
|
-
var formatFingerprint = (fp) => fp.match(/.{1,2}/g)?.join(":") || fp;
|
|
30172
30541
|
function FingerprintRow({
|
|
30173
30542
|
label,
|
|
30174
30543
|
value,
|
|
@@ -30178,8 +30547,8 @@ function FingerprintRow({
|
|
|
30178
30547
|
const { t: t2 } = useTranslation18();
|
|
30179
30548
|
return /* @__PURE__ */ jsxs35("div", { className: "flex flex-col gap-1.5", children: [
|
|
30180
30549
|
/* @__PURE__ */ jsx51("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: label }),
|
|
30181
|
-
/* @__PURE__ */ jsxs35("div", { className: "flex items-
|
|
30182
|
-
/* @__PURE__ */ jsx51("div", { className: "flex-1 bg-muted/50 border border-border p-3 font-mono text-xs break-all", children:
|
|
30550
|
+
/* @__PURE__ */ jsxs35("div", { className: "flex items-stretch gap-2", children: [
|
|
30551
|
+
/* @__PURE__ */ jsx51("div", { className: "flex-1 bg-muted/50 border border-border p-3 font-mono text-xs break-all", children: value }),
|
|
30183
30552
|
/* @__PURE__ */ jsx51(
|
|
30184
30553
|
"button",
|
|
30185
30554
|
{
|
|
@@ -30187,7 +30556,7 @@ function FingerprintRow({
|
|
|
30187
30556
|
onClick: onCopy,
|
|
30188
30557
|
title: t2("common.copy"),
|
|
30189
30558
|
"aria-label": t2("common.copy"),
|
|
30190
|
-
className:
|
|
30559
|
+
className: "flex w-11 shrink-0 items-center justify-center border border-border text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring",
|
|
30191
30560
|
children: copied ? /* @__PURE__ */ jsx51(Check, { className: "size-4 text-accent-brand" }) : /* @__PURE__ */ jsx51(Copy, { className: "size-4" })
|
|
30192
30561
|
}
|
|
30193
30562
|
)
|
|
@@ -30202,7 +30571,6 @@ function HostKeyVerificationDialog({
|
|
|
30202
30571
|
hostname,
|
|
30203
30572
|
fingerprint,
|
|
30204
30573
|
oldFingerprint,
|
|
30205
|
-
algorithm,
|
|
30206
30574
|
onAccept,
|
|
30207
30575
|
onReject,
|
|
30208
30576
|
backgroundColor
|
|
@@ -30222,6 +30590,8 @@ function HostKeyVerificationDialog({
|
|
|
30222
30590
|
}
|
|
30223
30591
|
};
|
|
30224
30592
|
const changed = scenario === "changed";
|
|
30593
|
+
const newPrint = hostKeyFingerprint(fingerprint);
|
|
30594
|
+
const oldPrint = hostKeyFingerprint(oldFingerprint || "");
|
|
30225
30595
|
return /* @__PURE__ */ jsx51(
|
|
30226
30596
|
PanePrompt,
|
|
30227
30597
|
{
|
|
@@ -30261,18 +30631,18 @@ function HostKeyVerificationDialog({
|
|
|
30261
30631
|
FingerprintRow,
|
|
30262
30632
|
{
|
|
30263
30633
|
label: t2("hostKey.previousKey"),
|
|
30264
|
-
value:
|
|
30634
|
+
value: oldPrint,
|
|
30265
30635
|
copied: copiedOldFingerprint,
|
|
30266
|
-
onCopy: () => copyFingerprint(
|
|
30636
|
+
onCopy: () => copyFingerprint(oldPrint, true)
|
|
30267
30637
|
}
|
|
30268
30638
|
),
|
|
30269
30639
|
/* @__PURE__ */ jsx51(
|
|
30270
30640
|
FingerprintRow,
|
|
30271
30641
|
{
|
|
30272
30642
|
label: t2("hostKey.newFingerprint"),
|
|
30273
|
-
value:
|
|
30643
|
+
value: newPrint,
|
|
30274
30644
|
copied: copiedFingerprint,
|
|
30275
|
-
onCopy: () => copyFingerprint(
|
|
30645
|
+
onCopy: () => copyFingerprint(newPrint)
|
|
30276
30646
|
}
|
|
30277
30647
|
)
|
|
30278
30648
|
] }) : /* @__PURE__ */ jsxs35(Fragment7, { children: [
|
|
@@ -30286,10 +30656,10 @@ function HostKeyVerificationDialog({
|
|
|
30286
30656
|
/* @__PURE__ */ jsx51(
|
|
30287
30657
|
FingerprintRow,
|
|
30288
30658
|
{
|
|
30289
|
-
label:
|
|
30290
|
-
value:
|
|
30659
|
+
label: t2("hostKey.fingerprint"),
|
|
30660
|
+
value: newPrint,
|
|
30291
30661
|
copied: copiedFingerprint,
|
|
30292
|
-
onCopy: () => copyFingerprint(
|
|
30662
|
+
onCopy: () => copyFingerprint(newPrint)
|
|
30293
30663
|
}
|
|
30294
30664
|
),
|
|
30295
30665
|
/* @__PURE__ */ jsx51("p", { className: "text-[10px] text-muted-foreground", children: t2("hostKey.verifyInstructions") })
|
|
@@ -31140,7 +31510,7 @@ function gridClass(columns) {
|
|
|
31140
31510
|
columns.xl && XL_COLS[columns.xl]
|
|
31141
31511
|
);
|
|
31142
31512
|
}
|
|
31143
|
-
function
|
|
31513
|
+
function DataView2({
|
|
31144
31514
|
items,
|
|
31145
31515
|
view,
|
|
31146
31516
|
density,
|
|
@@ -31899,7 +32269,7 @@ export {
|
|
|
31899
32269
|
ConnectionLogPanel,
|
|
31900
32270
|
ConnectionLogProvider,
|
|
31901
32271
|
ConnectionScreen,
|
|
31902
|
-
DataView,
|
|
32272
|
+
DataView2 as DataView,
|
|
31903
32273
|
Dialog,
|
|
31904
32274
|
DialogClose,
|
|
31905
32275
|
DialogContent,
|
package/dist/host-commands.js
CHANGED
|
@@ -17,7 +17,7 @@ export function execCommand(client, command, timeoutMs = 30000) {
|
|
|
17
17
|
if (!settled) {
|
|
18
18
|
settled = true;
|
|
19
19
|
cleanup();
|
|
20
|
-
reject(new Error(`Command timeout after ${timeoutMs}ms
|
|
20
|
+
reject(new Error(`Command timeout after ${timeoutMs}ms`));
|
|
21
21
|
}
|
|
22
22
|
}, timeoutMs);
|
|
23
23
|
const cleanup = () => {
|