Files
NetMesh/domain/pluginImporter.test.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

823 lines
29 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
applyPluginImporterDestination,
buildPluginImporterSafePreview,
mergePluginImporterDrafts,
normalizePluginImporterRecords,
} from './pluginImporter.ts';
test('plugin importer drafts receive host-owned identities and reject malformed records', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'host', value: { id: 'plugin-id', label: 'Prod', hostname: 'prod.test', username: 'root', tags: [], os: 'linux' } } },
{ type: 'draft', draft: { kind: 'identity', value: { id: 'plugin-id', label: 'Deploy', username: 'deploy', authMethod: 'password', password: 'secret' } } },
{ type: 'draft', draft: { kind: 'group', value: { path: 'Imported/Prod' } } },
{ type: 'draft', draft: { kind: 'snippet', value: { label: 'Broken' } } },
{ type: 'warning', message: 'Provider warning' },
]);
assert.equal(result.hosts.length, 1);
assert.notEqual(result.hosts[0].id, 'plugin-id');
assert.equal(result.identities.length, 1);
assert.notEqual(result.identities[0].id, 'plugin-id');
assert.deepEqual(result.groups, ['Imported/Prod']);
assert.deepEqual(result.warnings, ['Provider warning']);
assert.deepEqual(result.errors, ['Importer returned an invalid snippet draft.']);
});
test('plugin importer uses canonical Unicode character limits without truncating valid secrets', () => {
const label = '😀'.repeat(512);
const password = '🔒'.repeat(65_536);
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
label, username: 'root', authMethod: 'password', password,
} } },
]);
assert.deepEqual(result.errors, []);
assert.equal(result.identities[0].label, label);
assert.equal(result.identities[0].password, password);
});
test('plugin importer host drafts preserve unavailable namespaced configuration', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Custom transport',
hostname: 'opaque-target',
username: '',
tags: [],
os: 'linux',
protocol: 'plugin:com.example.transport.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { endpoint: 'opaque-target' },
},
},
} }]);
assert.equal(result.hosts[0].protocol, 'plugin:com.example.transport.connection');
assert.deepEqual(result.hosts[0].pluginConnection?.configuration, { endpoint: 'opaque-target' });
});
test('plugin importer host drafts can use opaque provider configuration without an SSH hostname', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Opaque service',
protocol: 'plugin:com.example.transport.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { account: 'production' },
},
},
} }]);
assert.equal(result.hosts.length, 1);
assert.equal(result.hosts[0].hostname, 'com.example.transport.connection');
assert.deepEqual(result.hosts[0].pluginConnection?.configuration, { account: 'production' });
});
test('plugin importer rejects plugin host drafts whose protocol does not match the provider ID', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Mismatched service',
protocol: 'plugin:com.example.other.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { account: 'production' },
},
},
} }]);
assert.deepEqual(result.hosts, []);
assert.deepEqual(result.errors, ['Importer returned an invalid host draft.']);
});
test('plugin importer rejects unknown host protocols instead of persisting an unsafe cast', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Unsupported transport',
hostname: 'host.test',
protocol: 'rdp',
},
} }]);
assert.deepEqual(result.hosts, []);
assert.deepEqual(result.errors, ['Importer returned an invalid host draft.']);
});
test('plugin importer rejects overlong host protocols before draft spreading', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Overlong transport',
hostname: 'host.test',
protocol: 'plugin:'.concat('a'.repeat(193)),
},
} }]);
assert.deepEqual(result.hosts, []);
assert.deepEqual(result.errors, ['Importer returned an invalid host draft.']);
});
test('plugin importer validates supported host fields before sanitizing drafts', () => {
assert.doesNotThrow(() => normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Malformed host',
hostname: 'host.test',
notes: 5,
},
} }]));
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Malformed host',
hostname: 'host.test',
notes: 5,
},
} }]);
assert.deepEqual(result.hosts, []);
assert.deepEqual(result.errors, ['Importer returned an invalid host draft.']);
});
test('plugin importer preserves validated host fields without retaining arbitrary draft properties', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Imported host',
hostname: 'host.test',
username: 'alice',
group: 'Imported',
notes: ' visible notes ',
port: 2222,
deviceType: 'network',
sftpFileProtocol: 'scp',
pinned: true,
unsafeExtra: 'discarded',
},
} }]);
assert.equal(result.hosts.length, 1);
assert.equal(result.hosts[0].group, 'Imported');
assert.equal(result.hosts[0].notes, 'visible notes');
assert.equal(result.hosts[0].port, 2222);
assert.equal(result.hosts[0].deviceType, 'network');
assert.equal(result.hosts[0].sftpFileProtocol, 'scp');
assert.equal(result.hosts[0].pinned, true);
assert.equal(Object.hasOwn(result.hosts[0] as unknown as Record<string, unknown>, 'unsafeExtra'), false);
});
test('plugin importer drops startup commands from host drafts', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Imported host',
hostname: 'host.test',
startupCommand: 'rm -rf /tmp/example',
},
} }]);
assert.equal(result.hosts.length, 1);
assert.equal(result.hosts[0].startupCommand, undefined);
});
test('plugin importer drops hidden plaintext built-in credential fields from host drafts', () => {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Imported host',
hostname: 'host.test',
telnetUsername: 'admin',
telnetPassword: 'plaintext',
savePassword: true,
},
} }]);
assert.equal(result.hosts.length, 1);
assert.equal(result.hosts[0].telnetUsername, undefined);
assert.equal(result.hosts[0].telnetPassword, undefined);
assert.equal(result.hosts[0].savePassword, undefined);
});
test('plugin importer rejects malformed supported host enum fields', () => {
for (const [key, value] of [
['deviceType', 'router'],
['sftpFileProtocol', 'ftp'],
] as const) {
const result = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Malformed host',
hostname: 'host.test',
[key]: value,
},
} }]);
assert.deepEqual(result.hosts, []);
assert.deepEqual(result.errors, ['Importer returned an invalid host draft.']);
}
});
test('plugin importer remaps provider-local key and identity references into host-owned IDs', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'key', value: {
id: 'provider-key', label: 'Key', type: 'ED25519', privateKey: 'private',
} } },
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'provider-identity', label: 'Identity', username: 'root', authMethod: 'key', keyId: 'provider-key',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Host', hostname: 'host.test', identityId: 'provider-identity', identityFileId: 'provider-key',
} } },
]);
assert.equal(result.identities[0].keyId, result.keys[0].id);
assert.equal(result.hosts[0].identityId, result.identities[0].id);
assert.equal(result.hosts[0].identityFileId, result.keys[0].id);
});
test('plugin importer maps plugin credential references to imported host-owned credentials', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'provider-credential', label: 'Plugin password', username: 'root', authMethod: 'password', password: 'secret',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host',
protocol: 'plugin:com.example.transport.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: {},
credentialId: 'provider-credential',
},
} } },
]);
assert.equal(result.errors.length, 0);
assert.equal(result.hosts[0].pluginConnection?.credentialId, result.identities[0].id);
});
test('plugin importer rejects unresolved plugin credential references instead of silently dropping them', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host',
protocol: 'plugin:com.example.transport.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: {},
credentialId: 'missing-credential',
},
} } },
]);
assert.equal(result.hosts[0].pluginConnection?.credentialId, undefined);
assert.deepEqual(result.errors, ['Importer returned an unresolved plugin credential reference.']);
});
test('plugin importer rejects unresolved standard Vault references instead of committing incomplete drafts', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
label: 'Missing key identity', username: 'root', authMethod: 'key', keyId: 'missing-key',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Missing credentials host', hostname: 'host.test',
identityId: 'missing-identity',
telnetIdentityId: 'missing-telnet-identity',
identityFileId: 'missing-host-key',
} } },
]);
assert.equal(result.identities[0].keyId, undefined);
assert.equal(result.hosts[0].identityId, undefined);
assert.equal(result.hosts[0].telnetIdentityId, undefined);
assert.equal(result.hosts[0].identityFileId, undefined);
assert.deepEqual(result.errors, [
'Importer returned an unresolved identity key reference.',
'Importer returned an unresolved host identity reference.',
'Importer returned an unresolved host Telnet identity reference.',
'Importer returned an unresolved host key reference.',
]);
});
test('plugin importer rejects plugin credential references to duplicate identity source ids', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'duplicate-credential', label: 'First identity', username: 'first', authMethod: 'password', password: 'first',
} } },
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'duplicate-credential', label: 'Second identity', username: 'second', authMethod: 'password', password: 'second',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host', hostname: 'plugin.test', protocol: 'plugin:com.example.transport.connection',
identityId: 'duplicate-credential',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: {},
credentialId: 'duplicate-credential',
},
} } },
]);
assert.equal(result.hosts[0].pluginConnection?.credentialId, undefined);
assert.equal(result.hosts[0].identityId, undefined);
assert.deepEqual(result.errors, [
'Importer returned a duplicate identity source ID.',
'Importer returned an ambiguous plugin credential reference.',
]);
});
test('plugin importer rejects plugin credential references to duplicate key source ids', () => {
const result = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'key', value: {
id: 'duplicate-credential', label: 'First key', type: 'ED25519', privateKey: 'first',
} } },
{ type: 'draft', draft: { kind: 'key', value: {
id: 'duplicate-credential', label: 'Second key', type: 'RSA', privateKey: 'second',
} } },
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'dependent-identity', label: 'Dependent identity', username: 'root', authMethod: 'key',
keyId: 'duplicate-credential',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host', hostname: 'plugin.test', protocol: 'plugin:com.example.transport.connection',
identityFileId: 'duplicate-credential',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: {},
credentialId: 'duplicate-credential',
},
} } },
]);
assert.equal(result.hosts[0].pluginConnection?.credentialId, undefined);
assert.equal(result.hosts[0].identityFileId, undefined);
assert.equal(result.identities[0].keyId, undefined);
assert.deepEqual(result.errors, [
'Importer returned a duplicate key source ID.',
'Importer returned an ambiguous identity key reference.',
'Importer returned an ambiguous plugin credential reference.',
]);
});
test('plugin importer merge skips duplicates and remaps relationships to retained Vault records', () => {
const records = [
{ type: 'draft', draft: { kind: 'key', value: {
id: 'provider-key', label: 'Key', type: 'ED25519', privateKey: 'private',
} } },
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'provider-identity', label: 'Identity', username: 'root', authMethod: 'key', keyId: 'provider-key',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Host', hostname: 'host.test', username: 'root', identityId: 'provider-identity', identityFileId: 'provider-key',
} } },
{ type: 'draft', draft: { kind: 'snippet', value: {
label: 'Check', command: 'uptime',
} } },
] as const;
const existingDrafts = normalizePluginImporterRecords(records);
const duplicateDrafts = normalizePluginImporterRecords(records);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: existingDrafts.identities,
keys: existingDrafts.keys,
snippets: existingDrafts.snippets,
customGroups: [],
}, duplicateDrafts);
assert.equal(merged.duplicateCount, 4);
assert.equal(merged.addedCount, 0);
assert.equal(merged.keys.length, 1);
assert.equal(merged.identities.length, 1);
assert.equal(merged.hosts.length, 1);
assert.equal(merged.snippets.length, 1);
});
test('plugin importer keeps identical provider settings with different credentials', () => {
const drafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'credential-a', label: 'Credential A', username: 'root', authMethod: 'password', password: 'first',
} } },
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'credential-b', label: 'Credential B', username: 'root', authMethod: 'password', password: 'second',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host A',
protocol: 'plugin:com.example.transport.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { endpoint: 'shared' },
credentialId: 'credential-a',
},
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host B',
protocol: 'plugin:com.example.transport.connection',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { endpoint: 'shared' },
credentialId: 'credential-b',
},
} } },
]);
const merged = mergePluginImporterDrafts({
hosts: [], identities: [], keys: [], snippets: [], customGroups: [],
}, drafts);
assert.equal(merged.hosts.length, 2);
assert.equal(merged.identities.length, 2);
assert.notEqual(
merged.hosts[0].pluginConnection?.credentialId,
merged.hosts[1].pluginConnection?.credentialId,
);
});
test('plugin importer destination moves only newly imported hosts into the selected group', () => {
const existingDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: { label: 'Existing', hostname: 'existing.test', group: 'Original' },
} }]);
const importedDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: { label: 'Imported', hostname: 'imported.test', group: 'Source' },
} }]);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: [],
keys: [],
snippets: [],
customGroups: ['Original'],
}, importedDrafts);
const targeted = applyPluginImporterDestination(
merged,
existingDrafts.hosts.length,
{ mode: 'group', group: 'Chosen' },
['Original'],
);
assert.equal(targeted.hosts[0].group, 'Original');
assert.equal(targeted.hosts[1].group, 'Chosen');
assert.deepEqual(targeted.customGroups, ['Original', 'Chosen']);
assert.equal(targeted.addedCount, 2);
});
test('plugin importer destination re-dedupes same-endpoint hosts collapsed into one group', () => {
const existingDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: { label: 'Existing', hostname: 'existing.test', group: 'Original' },
} }]);
const importedDrafts = normalizePluginImporterRecords([
{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'direct',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan',
},
} },
{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'via-socks',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan-proxy',
},
} },
]);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: [],
keys: [],
snippets: [],
customGroups: ['Original'],
}, importedDrafts);
assert.equal(merged.hosts.length, 3);
assert.equal(merged.addedCount, 4); // 2 hosts + 2 new groups
const targeted = applyPluginImporterDestination(
merged,
existingDrafts.hosts.length,
{ mode: 'group', group: 'Chosen' },
['Original'],
);
assert.equal(targeted.hosts.length, 2);
assert.equal(targeted.hosts[1]?.group, 'Chosen');
assert.deepEqual(targeted.customGroups, ['Original', 'Chosen']);
assert.equal(targeted.duplicateCount, merged.duplicateCount + 1);
assert.equal(targeted.addedCount, 2); // 1 retained host + Chosen group
});
test('plugin importer destination keeps distinct plugin hosts that share an endpoint', () => {
const drafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'credential-a', label: 'Credential A', username: 'root', authMethod: 'password', password: 'first',
} } },
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'credential-b', label: 'Credential B', username: 'root', authMethod: 'password', password: 'second',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host A',
protocol: 'plugin:com.example.transport.connection',
group: 'lan',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { endpoint: 'shared', path: 'a' },
credentialId: 'credential-a',
},
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Plugin host B',
protocol: 'plugin:com.example.transport.connection',
group: 'lan-proxy',
pluginConnection: {
providerId: 'com.example.transport.connection',
configuration: { endpoint: 'shared', path: 'b' },
credentialId: 'credential-b',
},
} } },
]);
const merged = mergePluginImporterDrafts({
hosts: [], identities: [], keys: [], snippets: [], customGroups: [],
}, drafts);
assert.equal(merged.hosts.length, 2);
const targeted = applyPluginImporterDestination(
merged,
0,
{ mode: 'group', group: 'Chosen' },
);
assert.equal(targeted.hosts.length, 2);
assert.deepEqual(targeted.hosts.map((host) => host.group), ['Chosen', 'Chosen']);
assert.notEqual(
targeted.hosts[0].pluginConnection?.configuration,
targeted.hosts[1].pluginConnection?.configuration,
);
assert.equal(targeted.duplicateCount, merged.duplicateCount);
assert.equal(targeted.addedCount, merged.addedCount - 2 + 1); // replace 2 source groups with Chosen
});
test('plugin importer destination skips imports that collide with existing hosts after rewrite', () => {
const existingDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Existing',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'Chosen',
},
} }]);
const importedDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Imported copy',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan',
},
} }]);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: [],
keys: [],
snippets: [],
customGroups: ['Chosen'],
}, importedDrafts);
assert.equal(merged.hosts.length, 2);
const targeted = applyPluginImporterDestination(
merged,
existingDrafts.hosts.length,
{ mode: 'group', group: 'Chosen' },
['Chosen'],
);
assert.equal(targeted.hosts.length, 1);
assert.equal(targeted.hosts[0]?.label, 'Existing');
assert.equal(targeted.duplicateCount, merged.duplicateCount + 1);
assert.equal(targeted.addedCount, 0);
});
test('plugin importer destination prunes orphan credentials for skipped colliding hosts', () => {
const existingDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: {
label: 'Existing',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'Chosen',
},
} }]);
const importedDrafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'imported-identity',
label: 'Imported identity',
username: 'root',
authMethod: 'password',
password: 'secret',
} } },
{ type: 'draft', draft: { kind: 'key', value: {
id: 'imported-key',
label: 'Imported key',
type: 'ED25519',
privateKey: 'private-key-material',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Imported copy',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan',
identityId: 'imported-identity',
identityFileId: 'imported-key',
} } },
]);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: [],
keys: [],
snippets: [],
customGroups: ['Chosen'],
}, importedDrafts);
assert.equal(merged.hosts.length, 2);
assert.equal(merged.identities.length, 1);
assert.equal(merged.keys.length, 1);
const targeted = applyPluginImporterDestination(
merged,
existingDrafts.hosts.length,
{ mode: 'group', group: 'Chosen' },
['Chosen'],
{ identities: 0, keys: 0 },
);
assert.equal(targeted.hosts.length, 1);
assert.deepEqual(targeted.identities, []);
assert.deepEqual(targeted.keys, []);
assert.equal(targeted.addedCount, 0);
});
test('plugin importer destination keeps existing credentials remapped onto skipped hosts', () => {
const existingDrafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'existing-identity',
label: 'Existing identity',
username: 'root',
authMethod: 'password',
password: 'vault-secret',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Existing',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'Chosen',
identityId: 'existing-identity',
} } },
]);
const existingIdentityId = existingDrafts.identities[0]?.id;
assert.ok(existingIdentityId);
const importedDrafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'imported-identity',
label: 'Duplicate identity',
username: 'root',
authMethod: 'password',
password: 'vault-secret',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'Imported copy',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan',
identityId: 'imported-identity',
} } },
]);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: existingDrafts.identities,
keys: [],
snippets: [],
customGroups: ['Chosen'],
}, importedDrafts);
assert.equal(merged.identities.length, 1);
assert.equal(merged.identities[0]?.id, existingIdentityId);
assert.equal(merged.duplicateCount >= 1, true);
const targeted = applyPluginImporterDestination(
merged,
existingDrafts.hosts.length,
{ mode: 'group', group: 'Chosen' },
['Chosen'],
{ identities: existingDrafts.identities.length, keys: 0 },
);
assert.equal(targeted.hosts.length, 1);
assert.equal(targeted.identities.length, 1);
assert.equal(targeted.identities[0]?.id, existingIdentityId);
});
test('plugin importer destination merges referenced credentials when collapsing imports', () => {
const drafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
id: 'imported-identity',
label: 'Imported identity',
username: 'root',
authMethod: 'password',
password: 'secret',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'bare',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan',
} } },
{ type: 'draft', draft: { kind: 'host', value: {
label: 'with-identity',
hostname: '10.10.10.10',
port: 22,
username: 'root',
group: 'lan-proxy',
identityId: 'imported-identity',
} } },
]);
const merged = mergePluginImporterDrafts({
hosts: [], identities: [], keys: [], snippets: [], customGroups: [],
}, drafts);
assert.equal(merged.hosts.length, 2);
assert.equal(merged.identities.length, 1);
const targeted = applyPluginImporterDestination(
merged,
0,
{ mode: 'group', group: 'Chosen' },
[],
{ identities: 0, keys: 0 },
);
assert.equal(targeted.hosts.length, 1);
assert.equal(targeted.hosts[0]?.identityId, merged.identities[0]?.id);
assert.equal(targeted.identities.length, 1);
});
test('plugin importer does not count a host-owned destination group as newly added', () => {
const existingDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: { label: 'Existing', hostname: 'existing.test', group: 'Existing Group' },
} }]);
const importedDrafts = normalizePluginImporterRecords([{ type: 'draft', draft: {
kind: 'host',
value: { label: 'Imported', hostname: 'imported.test', group: 'Source' },
} }]);
const merged = mergePluginImporterDrafts({
hosts: existingDrafts.hosts,
identities: [],
keys: [],
snippets: [],
customGroups: [],
}, importedDrafts);
const targeted = applyPluginImporterDestination(
merged,
existingDrafts.hosts.length,
{ mode: 'group', group: 'Existing Group' },
);
assert.equal(targeted.hosts[1].group, 'Existing Group');
assert.deepEqual(targeted.customGroups, ['Existing Group']);
assert.equal(targeted.addedCount, 1);
});
test('plugin importer preview is bounded and never exposes secret or command payloads', () => {
const drafts = normalizePluginImporterRecords([
{ type: 'draft', draft: { kind: 'identity', value: {
label: 'Deploy\nidentity', username: 'root', authMethod: 'password', password: 'do-not-render',
} } },
{ type: 'draft', draft: { kind: 'key', value: {
label: 'Production key', type: 'ED25519', privateKey: 'private-key-material', passphrase: 'secret',
} } },
{ type: 'draft', draft: { kind: 'snippet', value: {
label: 'Restart service', command: 'contains-sensitive-command',
} } },
{ type: 'warning', message: 'Check\nsource' },
{ type: 'error', message: 'Invalid\tentry' },
]);
const preview = buildPluginImporterSafePreview(drafts, 2, 1);
assert.deepEqual(preview.items, [
{ kind: 'identity', label: 'Deploy identity', detail: 'root · password' },
{ kind: 'key', label: 'Production key', detail: 'ED25519 · imported' },
]);
assert.deepEqual(preview.warnings, ['Check source']);
assert.deepEqual(preview.errors, []);
assert.equal(preview.omittedItemCount, 1);
assert.equal(preview.omittedDiagnosticCount, 1);
assert.equal(JSON.stringify(preview).includes('do-not-render'), false);
assert.equal(JSON.stringify(preview).includes('private-key-material'), false);
assert.equal(JSON.stringify(preview).includes('contains-sensitive-command'), false);
});