mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
feat: redesign user host defaults system
This commit is contained in:
1 parent
3028ab1176
commit
a4a4d4f27b
144 files changed
+24609
-2555
No files matched your search
@@ -65,6 +65,9 @@ vi.mock("../../utils/permission-manager.js", () => ({
|
||||
},
|
||||
}));
|
||||
vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentHostDefaultsRepository: () => ({
|
||||
listHosts: async () => [],
|
||||
}),
|
||||
createCurrentHostResolutionRepository: () => ({
|
||||
findHostsByUserId: async () => h.ownedHosts,
|
||||
listHostRowsForAccessList: async () => h.sharedRows,
|
||||
@@ -185,6 +188,14 @@ vi.mock("../../utils/shared-host-secrets-manager.js", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("../../hosts/defaults/index.js", () => ({
|
||||
applyHostDefaultsToWrite: async () => ({ core: [] }),
|
||||
applyDefaultsAfterHostWrite: async () => {},
|
||||
}));
|
||||
vi.mock("../../hosts/defaults/overrides.js", () => ({
|
||||
changeHostOverrides: async () => {},
|
||||
}));
|
||||
|
||||
vi.mock("../../hosts/delete-host.js", () => ({
|
||||
deleteOwnedHost: async (userId: string, hostId: number) => {
|
||||
h.deleted.push({ userId, hostId });
|
||||
|
||||
@@ -77,7 +77,14 @@ vi.mock("../../../utils/permission-manager.js", () => ({
|
||||
}),
|
||||
},
|
||||
}));
|
||||
vi.mock("../../../hosts/defaults/index.js", () => ({
|
||||
applyHostDefaultsToWrite: async () => ({ core: [] }),
|
||||
applyDefaultsAfterHostWrite: async () => {},
|
||||
}));
|
||||
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||
createCurrentHostDefaultsRepository: () => ({
|
||||
listHosts: async () => [],
|
||||
}),
|
||||
createCurrentHostRepository: () => ({
|
||||
createEncryptedForUser: async () => secretHost(1),
|
||||
updateEncryptedForUser: async () => secretHost(1),
|
||||
|
||||
@@ -58,6 +58,10 @@ const UNGATED: Record<string, string> = {
|
||||
"settings.getUser": "the plugin's own user settings",
|
||||
"settings.setUser": "the plugin's own user settings",
|
||||
"settings.getHost": "the plugin's own host settings",
|
||||
"settings.getHostFor":
|
||||
"the plugin's own host settings, as one user sees them",
|
||||
"settings.getHostDefault":
|
||||
"the plugin's own host settings, as a user's defaults",
|
||||
"settings.setHost": "the plugin's own host settings",
|
||||
"settings.getAll": "the plugin's own settings",
|
||||
"settings.onChange": "the plugin's own settings",
|
||||
|
||||
@@ -418,14 +418,62 @@ describe("host field options", () => {
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("rejects a defaultFrom that names a secret or unknown admin field", () => {
|
||||
for (const defaultFrom of ["token", "missing"]) {
|
||||
expect(
|
||||
validateManifest(
|
||||
host([{ key: "mode", type: "boolean", labelKey: "k", defaultFrom }]),
|
||||
).join(),
|
||||
).toMatch(/defaultFrom/);
|
||||
}
|
||||
it("still accepts an old defaultFrom, but only as a string", () => {
|
||||
expect(
|
||||
validateManifest(
|
||||
host([
|
||||
{
|
||||
key: "mode",
|
||||
type: "boolean",
|
||||
labelKey: "k",
|
||||
defaultFrom: "missing",
|
||||
},
|
||||
]),
|
||||
),
|
||||
).toEqual([]);
|
||||
expect(
|
||||
validateManifest(
|
||||
host([{ key: "mode", type: "boolean", labelKey: "k", defaultFrom: 1 }]),
|
||||
).join(),
|
||||
).toMatch(/defaultFrom/);
|
||||
});
|
||||
|
||||
it("accepts defaultable, defaultLevels and personal on host fields", () => {
|
||||
expect(
|
||||
validateManifest(
|
||||
host([
|
||||
{
|
||||
key: "mode",
|
||||
type: "boolean",
|
||||
labelKey: "k",
|
||||
defaultable: false,
|
||||
defaultLevels: ["user", "folder"],
|
||||
personal: true,
|
||||
},
|
||||
]),
|
||||
),
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("rejects bad default options and a defaultable secret", () => {
|
||||
const errors = (field: Record<string, unknown>) =>
|
||||
validateManifest(
|
||||
host([{ key: "mode", type: "boolean", labelKey: "k", ...field }]),
|
||||
).join();
|
||||
expect(errors({ defaultable: "yes" })).toMatch(/defaultable/);
|
||||
expect(errors({ personal: 1 })).toMatch(/personal/);
|
||||
expect(errors({ defaultLevels: [] })).toMatch(/defaultLevels/);
|
||||
expect(errors({ defaultLevels: ["host"] })).toMatch(/defaultLevels/);
|
||||
expect(errors({ type: "secret", defaultable: true })).toMatch(
|
||||
/cannot be defaultable/,
|
||||
);
|
||||
expect(
|
||||
validateManifest(
|
||||
withSettings({
|
||||
user: [{ key: "a", type: "boolean", labelKey: "k", personal: true }],
|
||||
}),
|
||||
).join(),
|
||||
).toMatch(/only valid on host fields/);
|
||||
});
|
||||
|
||||
it("rejects an unknown shareRead level and host options on admin fields", () => {
|
||||
|
||||
@@ -24,6 +24,9 @@ vi.mock("../../utils/crypto-migration/raw-rows.js", () => ({
|
||||
runStatement: vi.fn(async () => {}),
|
||||
}));
|
||||
|
||||
vi.mock("../../hosts/defaults/overrides.js", () => ({
|
||||
changeHostOverrides: async () => {},
|
||||
}));
|
||||
vi.mock("../../utils/logger.js", () => {
|
||||
const logger = {
|
||||
debug: vi.fn(),
|
||||
|
||||
@@ -127,11 +127,13 @@ describe("core sync entities", () => {
|
||||
it("registers what core syncs, under the wire names 2.8 used", () => {
|
||||
expect(listEntityTypes()).toEqual([
|
||||
"accountProfile",
|
||||
"hostDefaultsAdmin",
|
||||
"sshCredentials",
|
||||
"sharedCredentials",
|
||||
"sshFolders",
|
||||
"hosts",
|
||||
"sharedHosts",
|
||||
"hostDefaults",
|
||||
"userPreferences",
|
||||
"pluginUserSettings",
|
||||
]);
|
||||
@@ -168,7 +170,11 @@ describe("core sync entities", () => {
|
||||
.filter((entity) => entity.singleton)
|
||||
.map((entity) => entity.type);
|
||||
|
||||
expect(singletons.sort()).toEqual(["accountProfile", "userPreferences"]);
|
||||
expect(singletons.sort()).toEqual([
|
||||
"accountProfile",
|
||||
"hostDefaultsAdmin",
|
||||
"userPreferences",
|
||||
]);
|
||||
});
|
||||
|
||||
it("only sends shared copies and the account one way", () => {
|
||||
@@ -178,6 +184,7 @@ describe("core sync entities", () => {
|
||||
|
||||
expect(readOnly.sort()).toEqual([
|
||||
"accountProfile",
|
||||
"hostDefaultsAdmin",
|
||||
"sharedCredentials",
|
||||
"sharedHosts",
|
||||
]);
|
||||
|
||||
Reference in new issue
Block a user