@termix-ssh/plugin-sdk 1.0.13 → 1.0.17

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/PLUGIN-GUIDE.md +104 -69
  3. package/dist/backend.d.ts +500 -1
  4. package/dist/backend.js +7 -0
  5. package/dist/capabilities.js +4 -0
  6. package/dist/frontend.d.ts +45 -0
  7. package/dist/host/{PluginsTab-OXQQ7M4I.js → PluginsTab-YAGYRBIE.js} +3 -3
  8. package/dist/host/{chunk-T2PZWXFJ.js → chunk-2MU6WNSX.js} +1 -1
  9. package/dist/host/{chunk-54KCK6IZ.js → chunk-446UEDSK.js} +6 -2
  10. package/dist/host/{chunk-CN5UBTBP.js → chunk-7LEJ3HYF.js} +49 -3
  11. package/dist/host/{chunk-CALNJCHN.js → chunk-J2AILBXM.js} +561 -400
  12. package/dist/host/{chunk-ERGN4YW6.js → chunk-LQKK2JJA.js} +5 -1
  13. package/dist/host/core-classes.json +1 -1
  14. package/dist/host/{linked-server-5VFO4XQB.js → linked-server-OUF3POT7.js} +5 -3
  15. package/dist/host/{rbac-api-5YMBJAO5.js → rbac-api-LZVENREG.js} +1 -1
  16. package/dist/host/testing-host.js +4 -4
  17. package/dist/host/types/src/types/index.d.ts +10 -0
  18. package/dist/host/types/src/types/onboarding.d.ts +0 -1
  19. package/dist/host/types/src/types/ui-types.d.ts +3 -1
  20. package/dist/host/types/src/ui/api/auth-methods-api.d.ts +2 -0
  21. package/dist/host/types/src/ui/api/settings-api.d.ts +6 -0
  22. package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +6 -0
  23. package/dist/host/types/src/ui/auth/Auth.d.ts +1 -0
  24. package/dist/host/types/src/ui/lib/linked-server.d.ts +2 -0
  25. package/dist/host/types/src/ui/main-axios.d.ts +2 -2
  26. package/dist/host/types/src/ui/plugin-host/NativeView.d.ts +19 -0
  27. package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +4 -8
  28. package/dist/host/types/src/ui/shell/CompanionFrame.d.ts +11 -0
  29. package/dist/host/types/src/ui/shell/companions.d.ts +63 -0
  30. package/dist/host/types/src/ui/sidebar/AuthEnrollmentSections.d.ts +4 -1
  31. package/dist/host/ui.js +171 -820
  32. package/dist/host/{use-permissions-ISEDRY3J.js → use-permissions-BYCDS5PD.js} +1 -1
  33. package/dist/manifest.d.ts +1 -1
  34. package/dist/manifest.js +1 -1
  35. package/dist/testing.d.ts +26 -2
  36. package/dist/testing.js +89 -1
  37. package/dist/vitest-preset.js +23 -0
  38. package/package.json +1 -1
  39. package/schema/manifest.schema.json +4 -0
  40. package/dist/host/types/src/ui/api/sync-api.d.ts +0 -93
  41. package/dist/host/types/src/ui/auth/ElectronLoginForm.d.ts +0 -9
  42. package/dist/host/types/src/ui/hooks/use-sync-status.d.ts +0 -4
  43. package/dist/host/types/src/ui/lib/sync-status.d.ts +0 -6
  44. package/dist/host/types/src/ui/settings/sync/LinkServerDialog.d.ts +0 -12
  45. package/dist/host/types/src/ui/settings/sync/ProxySettingsFields.d.ts +0 -15
  46. package/dist/host/types/src/ui/settings/sync/saved-servers.d.ts +0 -3
@@ -7,7 +7,7 @@ import {
7
7
  resetPermissionsCache,
8
8
  setPermissionsForTesting,
9
9
  usePermissions
10
- } from "./chunk-T2PZWXFJ.js";
10
+ } from "./chunk-2MU6WNSX.js";
11
11
  import "./chunk-YGYBM7SQ.js";
12
12
  export {
13
13
  hasPermission,
@@ -20,7 +20,7 @@ export { ENV_NAME_PATTERN, MAX_ENV_DESCRIPTION_LENGTH, pluginDocsPage, pluginDoc
20
20
  * "^1.2" needs 1.2 or later). engine.termix is checked against the core
21
21
  * version by the server.
22
22
  */
23
- export declare const PLUGIN_API_VERSION = "1.5.0";
23
+ export declare const PLUGIN_API_VERSION = "1.9.0";
24
24
  /** The API major, the default engine.api for a new plugin. */
25
25
  export declare const SUPPORTED_PLUGIN_API_VERSION: string;
26
26
  /** Whether this build's plugin API satisfies a manifest's engine.api. */
package/dist/manifest.js CHANGED
@@ -22,7 +22,7 @@ export { ENV_NAME_PATTERN, MAX_ENV_DESCRIPTION_LENGTH, pluginDocsPage, pluginDoc
22
22
  * "^1.2" needs 1.2 or later). engine.termix is checked against the core
23
23
  * version by the server.
24
24
  */
25
- export const PLUGIN_API_VERSION = "1.5.0";
25
+ export const PLUGIN_API_VERSION = "1.9.0";
26
26
  /** The API major, the default engine.api for a new plugin. */
27
27
  export const SUPPORTED_PLUGIN_API_VERSION = String(semver.major(PLUGIN_API_VERSION));
28
28
  /** Whether this build's plugin API satisfies a manifest's engine.api. */
package/dist/testing.d.ts CHANGED
@@ -23,9 +23,9 @@ export interface FakeWsRoute {
23
23
  options?: PluginWebSocketOptions;
24
24
  }
25
25
  import type { PluginLoginMethod, PluginVerifiedIdentity, PluginSecondFactor, PluginSshAuthProvider, PluginSshConnectOptions, PluginSshHost, PluginHostSummary, PluginShareableUser, PluginShareableRole, PluginSshKeyCredential, PluginSshKeyCredentialInput } from "./backend.js";
26
- import type { SyncEntityRegistration } from "./backend.js";
26
+ import type { PluginSyncHost, SyncEntityRegistration } from "./backend.js";
27
27
  import type { PluginDatabase } from "./backend.js";
28
- import type { PluginExternalClientRequest, PluginProtocolTarget, PluginHostProbeTarget, PluginHostStatusEntry, PluginActivityProvider, PluginHostStatusProvider, PluginNotification, PluginNotificationChannel, PluginNotifyHub, PluginFetchInit, PluginBinarySpec, PluginTlsCertificateInfo, PluginTlsStatus, PluginSummary, PluginKeyboardInteractiveHandler, PluginProcessHandle, PluginProcessOptions } from "./backend.js";
28
+ import type { PluginExternalClientRequest, PluginProtocolTarget, PluginHostProbeTarget, PluginHostStatusEntry, PluginActivityProvider, PluginHostLockProvider, PluginAuthPolicyProvider, PluginCredentialSummary, PluginHostShareGrant, PluginHostStatusProvider, PluginNotification, PluginNotificationChannel, PluginNotifyHub, PluginFetchInit, PluginBinarySpec, PluginTlsCertificateInfo, PluginTlsStatus, PluginSummary, PluginKeyboardInteractiveHandler, PluginProcessHandle, PluginProcessOptions } from "./backend.js";
29
29
  /** A timer registered through ctx.schedule, run by hand with runScheduled. */
30
30
  export interface FakeScheduledJob {
31
31
  kind: "every" | "after";
@@ -35,6 +35,8 @@ export interface FakeScheduledJob {
35
35
  }
36
36
  export interface FakeContextOptions {
37
37
  pluginId?: string;
38
+ /** What ctx.sync.host answers, for a sync provider's tests. */
39
+ syncHost?: Partial<PluginSyncHost>;
38
40
  manifest?: Partial<PluginManifest>;
39
41
  /** Acting user returned by currentActor and used by asUser. */
40
42
  actor?: string;
@@ -75,6 +77,8 @@ export interface FakeContextOptions {
75
77
  protocolTargets?: Record<string, PluginProtocolTarget>;
76
78
  /** What ctx.credentials.listSshKeys answers. */
77
79
  sshKeyCredentials?: PluginSshKeyCredential[];
80
+ /** What ctx.credentials.list answers. */
81
+ credentialSummaries?: PluginCredentialSummary[];
78
82
  /** What ctx.desktop.available() answers. Defaults to false. */
79
83
  desktopAvailable?: boolean;
80
84
  /** What ctx.desktop.local is. Calls throw when this is not given. */
@@ -122,6 +126,11 @@ export interface FakeContextOptions {
122
126
  baseUrl?: string;
123
127
  /** What ctx.auth.countLinkedUsers answers, by provider. Defaults to 0. */
124
128
  linkedUsers?: Record<string, number>;
129
+ /** Second factors from other plugins that ctx.auth.listSecondFactors adds. */
130
+ secondFactors?: {
131
+ id: string;
132
+ pluginId: string;
133
+ }[];
125
134
  /** Failures before ctx.auth.loginRateLimit locks a key. Defaults to 5. */
126
135
  loginAttemptLimit?: number;
127
136
  /** What ctx.users.getLocale answers, by user id. A missing user answers null. */
@@ -167,6 +176,8 @@ export interface FakeAuthRegistrations {
167
176
  purpose: string;
168
177
  ttlSeconds?: number;
169
178
  }>;
179
+ /** Providers passed to ctx.auth.policy.provide that are still registered. */
180
+ policies: PluginAuthPolicyProvider[];
170
181
  }
171
182
  export interface FakePluginContext {
172
183
  ctx: PluginContext;
@@ -180,6 +191,8 @@ export interface FakePluginContext {
180
191
  hostStatusProviders: PluginHostStatusProvider[];
181
192
  /** Every provider passed to ctx.hosts.activity.provide that is still registered. */
182
193
  activityProviders: PluginActivityProvider[];
194
+ /** Every provider passed to ctx.hosts.locks.provide that is still registered. */
195
+ hostLockProviders: PluginHostLockProvider[];
183
196
  /** Topics emitted through ctx.events.emit, in order. */
184
197
  emitted: Array<{
185
198
  topic: string;
@@ -215,6 +228,11 @@ export interface FakePluginContext {
215
228
  permissionLevel: string;
216
229
  durationHours?: number;
217
230
  }>;
231
+ /** Every ctx.hosts.setShares call, in order. */
232
+ hostShareSets: Array<{
233
+ hostId: number;
234
+ grants: PluginHostShareGrant[];
235
+ }>;
218
236
  /** Everything registered through ctx.auth. */
219
237
  auth: FakeAuthRegistrations;
220
238
  /** Every ctx.desktop.openIsolatedWindow call, in order. */
@@ -330,6 +348,8 @@ export interface FakePluginContext {
330
348
  export declare function createFakeContext(options?: FakeContextOptions): FakePluginContext;
331
349
  export interface MockContextOptions {
332
350
  pluginId?: string;
351
+ /** What ctx.sync.host answers, for a sync provider's tests. */
352
+ syncHost?: Partial<PluginSyncHost>;
333
353
  manifest?: Partial<PluginManifest>;
334
354
  /** Capabilities the plugin is granted. Anything else throws. */
335
355
  capabilities?: string[];
@@ -364,6 +384,8 @@ export interface MockContextOptions {
364
384
  protocolTargets?: Record<string, PluginProtocolTarget>;
365
385
  /** What ctx.credentials.listSshKeys serves. */
366
386
  sshKeyCredentials?: PluginSshKeyCredential[];
387
+ /** What ctx.credentials.list serves. */
388
+ credentialSummaries?: PluginCredentialSummary[];
367
389
  /** What ctx.desktop.available() answers. */
368
390
  desktopAvailable?: boolean;
369
391
  /** What ctx.desktop.local is. See FakeContextOptions. */
@@ -402,6 +424,8 @@ export interface MockContextOptions {
402
424
  /** See FakeContextOptions. */
403
425
  loginAttemptLimit?: number;
404
426
  /** See FakeContextOptions. */
427
+ secondFactors?: FakeContextOptions["secondFactors"];
428
+ /** See FakeContextOptions. */
405
429
  locales?: Record<string, string>;
406
430
  }
407
431
  export interface MockPluginContext extends FakePluginContext {
package/dist/testing.js CHANGED
@@ -100,7 +100,7 @@ function emptyHostRecord(id, userId) {
100
100
  };
101
101
  }
102
102
  function applyHostInput(record, input) {
103
- const { tags, pluginSettings: _settings, forceKeyboardInteractive: _fki, ...rest } = input;
103
+ const { tags, pluginSettings: _settings, pluginEnable: _pluginEnable, forceKeyboardInteractive: _fki, password: _password, key: _key, keyPassword: _keyPassword, keyType: _keyType, sudoPassword: _sudoPassword, protocolAuth: _protocolAuth, ...rest } = input;
104
104
  const next = { ...record };
105
105
  for (const [key, value] of Object.entries(rest)) {
106
106
  if (value !== undefined)
@@ -126,6 +126,7 @@ export function createFakeContext(options = {}) {
126
126
  const emitted = [];
127
127
  const hostStatusProviders = [];
128
128
  const activityProviders = [];
129
+ const hostLockProviders = [];
129
130
  const kv = new Map();
130
131
  const tables = [];
131
132
  const syncEntities = [];
@@ -138,6 +139,7 @@ export function createFakeContext(options = {}) {
138
139
  const settingsValidators = new Set();
139
140
  const sshConnections = [];
140
141
  const hostShares = [];
142
+ const hostShareSets = [];
141
143
  const desktopWindows = [];
142
144
  const externalClientLaunches = [];
143
145
  const credentialReads = [];
@@ -198,6 +200,7 @@ export function createFakeContext(options = {}) {
198
200
  revokedSessions: [],
199
201
  loginFailures: new Map(),
200
202
  userTokens: [],
203
+ policies: [],
201
204
  };
202
205
  const sshClient = options.sshClient ?? {};
203
206
  let actor = options.actor;
@@ -298,6 +301,12 @@ export function createFakeContext(options = {}) {
298
301
  registerEntity: (entity) => {
299
302
  syncEntities.push(entity);
300
303
  },
304
+ provide: () => () => { },
305
+ get host() {
306
+ if (!options.syncHost)
307
+ throw new Error("Pass syncHost to use ctx.sync.host");
308
+ return options.syncHost;
309
+ },
301
310
  },
302
311
  registry: {
303
312
  provide: (key, value) => {
@@ -526,6 +535,10 @@ export function createFakeContext(options = {}) {
526
535
  hostShares.push({ hostId, targets, permissionLevel, durationHours });
527
536
  return { hostId, shared: true };
528
537
  },
538
+ setShares: async (hostId, grants) => {
539
+ hostShareSets.push({ hostId, grants: [...grants] });
540
+ return { hostId, shared: true };
541
+ },
529
542
  listUsers: async () => options.shareableUsers ?? [],
530
543
  listRoles: async () => options.shareableRoles ?? [],
531
544
  trackSession: (hostId) => {
@@ -555,6 +568,20 @@ export function createFakeContext(options = {}) {
555
568
  };
556
569
  },
557
570
  },
571
+ folders: {
572
+ ensure: async () => { },
573
+ removeEmpty: async () => true,
574
+ },
575
+ locks: {
576
+ provide: (provider) => {
577
+ hostLockProviders.push(provider);
578
+ return () => {
579
+ const at = hostLockProviders.indexOf(provider);
580
+ if (at >= 0)
581
+ hostLockProviders.splice(at, 1);
582
+ };
583
+ },
584
+ },
558
585
  status: {
559
586
  provide: (provider) => {
560
587
  hostStatusProviders.push(provider);
@@ -616,6 +643,7 @@ export function createFakeContext(options = {}) {
616
643
  tcpProbe: async (host, port) => options.reachable?.(host, port) ?? false,
617
644
  },
618
645
  ssh: {
646
+ transports: { provide: () => () => { } },
619
647
  probe: async (hostId, probeOptions) => options.reachable?.(hostId, probeOptions?.port) ?? false,
620
648
  connect: async (host, connectOptions) => {
621
649
  sshConnections.push({ host, options: connectOptions });
@@ -761,6 +789,23 @@ export function createFakeContext(options = {}) {
761
789
  expiresAt: new Date(Date.now() + ttl * 1000).toISOString(),
762
790
  };
763
791
  },
792
+ policy: {
793
+ provide: (provider) => {
794
+ auth.policies.push(provider);
795
+ return () => {
796
+ const at = auth.policies.indexOf(provider);
797
+ if (at >= 0)
798
+ auth.policies.splice(at, 1);
799
+ };
800
+ },
801
+ },
802
+ listSecondFactors: () => [
803
+ ...auth.secondFactors.map((factor) => ({
804
+ id: factor.id,
805
+ pluginId,
806
+ })),
807
+ ...(options.secondFactors ?? []),
808
+ ],
764
809
  },
765
810
  users: {
766
811
  getLocale: async (userId) => options.locales?.[userId] ?? null,
@@ -778,6 +823,7 @@ export function createFakeContext(options = {}) {
778
823
  local: options.desktopLocal ?? unavailableDesktopLocal(),
779
824
  },
780
825
  credentials: {
826
+ list: async () => [...(options.credentialSummaries ?? [])],
781
827
  listSshKeys: async () => [
782
828
  ...(options.sshKeyCredentials ?? []),
783
829
  ...createdSshKeys.map((key) => ({
@@ -951,6 +997,7 @@ export function createFakeContext(options = {}) {
951
997
  disposals,
952
998
  hostStatusProviders,
953
999
  activityProviders,
1000
+ hostLockProviders,
954
1001
  emitted,
955
1002
  kv,
956
1003
  tables,
@@ -961,6 +1008,7 @@ export function createFakeContext(options = {}) {
961
1008
  coreSettings,
962
1009
  sshConnections,
963
1010
  hostShares,
1011
+ hostShareSets,
964
1012
  auth,
965
1013
  desktopWindows,
966
1014
  externalClientLaunches,
@@ -1070,6 +1118,7 @@ export function createMockCtx(options = {}) {
1070
1118
  const checked = [];
1071
1119
  const base = createFakeContext({
1072
1120
  pluginId: options.pluginId,
1121
+ syncHost: options.syncHost,
1073
1122
  actor: options.actor,
1074
1123
  settings: options.settings,
1075
1124
  coreSettings: options.coreSettings,
@@ -1085,6 +1134,7 @@ export function createMockCtx(options = {}) {
1085
1134
  services: options.services,
1086
1135
  protocolTargets: options.protocolTargets,
1087
1136
  sshKeyCredentials: options.sshKeyCredentials,
1137
+ credentialSummaries: options.credentialSummaries,
1088
1138
  desktopAvailable: options.desktopAvailable,
1089
1139
  desktopLocal: options.desktopLocal,
1090
1140
  auditEntries: options.auditEntries,
@@ -1102,6 +1152,7 @@ export function createMockCtx(options = {}) {
1102
1152
  baseUrl: options.baseUrl,
1103
1153
  linkedUsers: options.linkedUsers,
1104
1154
  loginAttemptLimit: options.loginAttemptLimit,
1155
+ secondFactors: options.secondFactors,
1105
1156
  locales: options.locales,
1106
1157
  manifest: {
1107
1158
  capabilities: options.capabilities ?? [],
@@ -1268,6 +1319,10 @@ export function createMockCtx(options = {}) {
1268
1319
  require("hosts:write");
1269
1320
  return ctx.hosts.share(hostId, targets, permissionLevel, durationHours);
1270
1321
  },
1322
+ setShares: async (hostId, grants) => {
1323
+ require("hosts:write");
1324
+ return ctx.hosts.setShares(hostId, grants);
1325
+ },
1271
1326
  listUsers: async () => {
1272
1327
  require("hosts:write");
1273
1328
  return ctx.hosts.listUsers();
@@ -1298,6 +1353,22 @@ export function createMockCtx(options = {}) {
1298
1353
  return ctx.hosts.activity.provide(provider);
1299
1354
  },
1300
1355
  },
1356
+ folders: {
1357
+ ensure: async (name, style) => {
1358
+ require("hosts:write");
1359
+ return ctx.hosts.folders.ensure(name, style);
1360
+ },
1361
+ removeEmpty: async (name) => {
1362
+ require("hosts:write");
1363
+ return ctx.hosts.folders.removeEmpty(name);
1364
+ },
1365
+ },
1366
+ locks: {
1367
+ provide: (provider) => {
1368
+ require("hosts:lock");
1369
+ return ctx.hosts.locks.provide(provider);
1370
+ },
1371
+ },
1301
1372
  status: {
1302
1373
  provide: (provider) => {
1303
1374
  require("hosts:read");
@@ -1324,6 +1395,12 @@ export function createMockCtx(options = {}) {
1324
1395
  },
1325
1396
  ssh: {
1326
1397
  ...ctx.ssh,
1398
+ transports: {
1399
+ provide: (provider) => {
1400
+ require("ssh:transport");
1401
+ return ctx.ssh.transports.provide(provider);
1402
+ },
1403
+ },
1327
1404
  probe: async (hostId, probeOptions) => {
1328
1405
  require("ssh:connect");
1329
1406
  return ctx.ssh.probe(hostId, probeOptions);
@@ -1423,6 +1500,13 @@ export function createMockCtx(options = {}) {
1423
1500
  require("users:impersonate");
1424
1501
  return ctx.auth.issueUserToken(userId, tokenOptions);
1425
1502
  },
1503
+ policy: {
1504
+ provide: (provider) => {
1505
+ require("auth:policy");
1506
+ return ctx.auth.policy.provide(provider);
1507
+ },
1508
+ },
1509
+ listSecondFactors: () => ctx.auth.listSecondFactors(),
1426
1510
  },
1427
1511
  users: {
1428
1512
  getLocale: async (userId) => {
@@ -1458,6 +1542,10 @@ export function createMockCtx(options = {}) {
1458
1542
  local: gateDesktopLocal(ctx.desktop.local, () => require("desktop:local")),
1459
1543
  },
1460
1544
  credentials: {
1545
+ list: async () => {
1546
+ require("credentials:use");
1547
+ return ctx.credentials.list();
1548
+ },
1461
1549
  listSshKeys: async () => {
1462
1550
  require("credentials:use");
1463
1551
  return ctx.credentials.listSshKeys();
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * Two projects: tests/backend runs in node, tests/frontend in jsdom.
10
10
  */
11
+ import { createRequire } from "node:module";
11
12
  import fs from "node:fs";
12
13
  import path from "node:path";
13
14
  import { fileURLToPath } from "node:url";
@@ -84,6 +85,28 @@ export function pluginVitestConfig(configUrl, options = {}) {
84
85
  // Vite must be allowed to read it, and React must come from the plugin.
85
86
  const sdkDir = fs.realpathSync(fileURLToPath(new URL("..", import.meta.url)));
86
87
  const server = { fs: { allow: [pluginDir, sdkDir] } };
88
+ // dedupe alone is not enough: react-dom or the testing library loaded from
89
+ // the linked SDK's own node_modules pull in a second React, and hooks then
90
+ // see no renderer.
91
+ if (!sdkDir.startsWith(pluginDir)) {
92
+ const pluginRequire = createRequire(path.join(pluginDir, "package.json"));
93
+ for (const name of [
94
+ "react",
95
+ "react-dom",
96
+ "@testing-library/react",
97
+ "react-i18next",
98
+ "i18next",
99
+ ]) {
100
+ if (alias[name])
101
+ continue;
102
+ try {
103
+ alias[name] = path.dirname(pluginRequire.resolve(`${name}/package.json`));
104
+ }
105
+ catch {
106
+ // Not installed in the plugin: leave it to normal resolution.
107
+ }
108
+ }
109
+ }
87
110
  const resolve = {
88
111
  alias,
89
112
  dedupe: ["react", "react-dom", "react-i18next", "i18next"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@termix-ssh/plugin-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.17",
4
4
  "description": "The contract between Termix core and a plugin: types, the capability catalog and the manifest schema.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -151,6 +151,9 @@
151
151
  "process:spawn",
152
152
  "users:write",
153
153
  "auth:provide",
154
+ "auth:policy",
155
+ "sync:provide",
156
+ "ssh:transport",
154
157
  "system:tls",
155
158
  "device:serial",
156
159
  "hosts:write",
@@ -167,6 +170,7 @@
167
170
  "network:probe",
168
171
  "hosts:status-provide",
169
172
  "hosts:activity-provide",
173
+ "hosts:lock",
170
174
  "desktop:window",
171
175
  "desktop:local",
172
176
  "users:impersonate",
@@ -1,93 +0,0 @@
1
- export type SyncState = "idle" | "syncing" | "offline" | "error" | "signed_out";
2
- export interface SyncProxyHeader {
3
- name: string;
4
- value: string;
5
- /** A saved header whose value is not sent back. */
6
- set?: boolean;
7
- }
8
- export interface SyncBasicAuth {
9
- username: string;
10
- password: string;
11
- set?: boolean;
12
- }
13
- export interface SyncEntityInfo {
14
- type: string;
15
- owner: string;
16
- ownerName: string | null;
17
- readOnly: boolean;
18
- onServer: boolean;
19
- onDevice: boolean;
20
- enabled: boolean;
21
- }
22
- export interface SyncStatus {
23
- linked: boolean;
24
- serverUrl?: string;
25
- serverName?: string | null;
26
- serverVersion?: string | null;
27
- account?: {
28
- username?: string;
29
- isAdmin?: boolean;
30
- roles?: string[];
31
- permissions?: string[];
32
- };
33
- status?: SyncState;
34
- lastError?: string | null;
35
- linkedAt?: string;
36
- lastSyncAt?: string | null;
37
- pending?: number;
38
- conflicts?: number;
39
- errors?: number;
40
- firstSyncDone?: boolean;
41
- allowInvalidCertificate?: boolean;
42
- customHeaders?: SyncProxyHeader[];
43
- basicAuth?: SyncBasicAuth | null;
44
- entities: SyncEntityInfo[];
45
- }
46
- export type ProbeProblem = "invalid_url" | "unreachable" | "tls_untrusted" | "basic_auth_required" | "proxy_login" | "not_termix" | "version_mismatch" | "different_account";
47
- export interface ProbeResult {
48
- ok: boolean;
49
- serverUrl?: string;
50
- name?: string;
51
- version?: string | null;
52
- problem?: ProbeProblem;
53
- message?: string;
54
- }
55
- export interface ServerTarget {
56
- serverUrl: string;
57
- customHeaders?: SyncProxyHeader[];
58
- basicAuth?: SyncBasicAuth | null;
59
- allowInvalidCertificate?: boolean;
60
- }
61
- export interface SyncConflictItem {
62
- id: number;
63
- entityType: string;
64
- syncId: string;
65
- name: string;
66
- createdAt: string;
67
- }
68
- export interface SyncErrorItem {
69
- entityType: string;
70
- syncId: string;
71
- reason: string | null;
72
- }
73
- export declare function getSyncStatus(): Promise<SyncStatus>;
74
- export declare function probeServer(target: ServerTarget): Promise<ProbeResult>;
75
- export declare function getLinkPreview(): Promise<Record<string, number>>;
76
- export declare function completeLink(input: ServerTarget & {
77
- token: string;
78
- mode: "merge" | "replace";
79
- serverName?: string;
80
- }): Promise<SyncStatus>;
81
- export declare function reloginLink(token: string): Promise<SyncStatus>;
82
- export declare function unlinkServer(keepData: boolean): Promise<SyncStatus>;
83
- export declare function syncNow(): Promise<SyncStatus>;
84
- export declare function updateSyncSettings(settings: {
85
- disabledTypes?: string[];
86
- customHeaders?: SyncProxyHeader[];
87
- basicAuth?: SyncBasicAuth | null;
88
- allowInvalidCertificate?: boolean;
89
- }): Promise<SyncStatus>;
90
- export declare function getSyncConflicts(): Promise<SyncConflictItem[]>;
91
- export declare function settleSyncConflict(id: number, keep: "mine" | "server"): Promise<void>;
92
- export declare function getSyncErrors(): Promise<SyncErrorItem[]>;
93
- export declare function retrySyncErrors(): Promise<SyncStatus>;
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- interface ElectronLoginFormProps {
3
- serverUrl: string;
4
- onAuthSuccess: (token: string | null) => void | Promise<void>;
5
- onChangeServer: () => void;
6
- targetPurpose?: "local" | "link";
7
- }
8
- export declare function ElectronLoginForm({ serverUrl, onAuthSuccess, onChangeServer, targetPurpose, }: ElectronLoginFormProps): React.JSX.Element;
9
- export {};
@@ -1,4 +0,0 @@
1
- /** The desktop's sync status, kept current while the component is mounted. */
2
- export declare function useSyncStatus(): any;
3
- /** What needs the user's attention in Sync, for the rail badge. */
4
- export declare function useSyncAttentionCount(): number | null;
@@ -1,6 +0,0 @@
1
- import { type SyncStatus } from "../api/sync-api";
2
- export declare function subscribeSyncStatus(listener: () => void): () => void;
3
- export declare function getSyncStatusSnapshot(): SyncStatus | null;
4
- /** Takes a status a request already returned, and checks again soon. */
5
- export declare function setSyncStatus(next: SyncStatus): void;
6
- export declare function refreshSyncStatus(): void;
@@ -1,12 +0,0 @@
1
- import { type SyncStatus } from "../../api/sync-api";
2
- interface LinkServerDialogProps {
3
- open: boolean;
4
- onOpenChange: (open: boolean) => void;
5
- onLinked: (status: SyncStatus) => void;
6
- /** Sign back in to the server this desktop is already linked to. */
7
- relogin?: {
8
- serverUrl: string;
9
- };
10
- }
11
- export declare function LinkServerDialog({ open, onOpenChange, onLinked, relogin, }: LinkServerDialogProps): import("react").JSX.Element;
12
- export {};
@@ -1,15 +0,0 @@
1
- import type { SyncBasicAuth, SyncProxyHeader } from "../../api/sync-api";
2
- interface ProxySettingsFieldsProps {
3
- customHeaders: SyncProxyHeader[];
4
- basicAuth: SyncBasicAuth | null;
5
- onChange: (next: {
6
- customHeaders?: SyncProxyHeader[];
7
- basicAuth?: SyncBasicAuth | null;
8
- }) => void;
9
- }
10
- /**
11
- * What a reverse proxy in front of the server wants: extra headers (a
12
- * Cloudflare Access service token, a gateway key) and basic auth.
13
- */
14
- export declare function ProxySettingsFields({ customHeaders, basicAuth, onChange, }: ProxySettingsFieldsProps): import("react").JSX.Element;
15
- export {};
@@ -1,3 +0,0 @@
1
- export declare function getSavedServerUrls(): string[];
2
- export declare function rememberServerUrl(url: string): string[];
3
- export declare function forgetServerUrl(url: string): string[];