fix: split up proxmox secrets are incorrectly migrated (#2124)
This commit is contained in:
@@ -44,17 +44,75 @@ export const mapAndDecryptIntegrations = (
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return preparedIntegrations.map(({ type, name, url, properties }) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const kind = mapIntegrationType(type!);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: createId(),
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
kind,
|
||||||
|
secrets: mapSecrets(properties, encryptionToken, kind),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapSecrets = (properties: PreparedIntegration["properties"], encryptionToken: string, kind: IntegrationKind) => {
|
||||||
const key = Buffer.from(encryptionToken, "hex");
|
const key = Buffer.from(encryptionToken, "hex");
|
||||||
|
|
||||||
return preparedIntegrations.map(({ type, name, url, properties }) => ({
|
const decryptedProperties = properties.map((property) => ({
|
||||||
id: createId(),
|
...property,
|
||||||
name,
|
value: property.value ? decryptSecretWithKey(property.value as `${string}.${string}`, key) : null,
|
||||||
url,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
kind: mapIntegrationType(type!),
|
|
||||||
secrets: properties.map((property) => ({
|
|
||||||
...property,
|
|
||||||
value: property.value ? decryptSecretWithKey(property.value as `${string}.${string}`, key) : null,
|
|
||||||
})),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
return kind === "proxmox" ? mapProxmoxSecrets(decryptedProperties) : decryptedProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxmox secrets have bee split up from format `user@realm!tokenId=secret` to separate fields
|
||||||
|
*/
|
||||||
|
const mapProxmoxSecrets = (decryptedProperties: PreparedIntegration["properties"]) => {
|
||||||
|
const apiToken = decryptedProperties.find((property) => property.field === "apiKey");
|
||||||
|
|
||||||
|
if (!apiToken?.value) return [];
|
||||||
|
|
||||||
|
let splitValues = apiToken.value.split("@");
|
||||||
|
|
||||||
|
if (splitValues.length <= 1) return [];
|
||||||
|
|
||||||
|
const [user, ...rest] = splitValues;
|
||||||
|
|
||||||
|
splitValues = rest.join("@").split("!");
|
||||||
|
|
||||||
|
if (splitValues.length <= 1) return [];
|
||||||
|
|
||||||
|
const [realm, ...rest2] = splitValues;
|
||||||
|
|
||||||
|
splitValues = rest2.join("!").split("=");
|
||||||
|
|
||||||
|
if (splitValues.length <= 1) return [];
|
||||||
|
|
||||||
|
const [tokenId, ...rest3] = splitValues;
|
||||||
|
|
||||||
|
const secret = rest3.join("=");
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field: "username" as const,
|
||||||
|
value: user,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "realm" as const,
|
||||||
|
value: realm,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "tokenId" as const,
|
||||||
|
value: tokenId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "apiKey" as const,
|
||||||
|
value: secret,
|
||||||
|
},
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
46
packages/old-import/src/mappers/test/map-integration.spec.ts
Normal file
46
packages/old-import/src/mappers/test/map-integration.spec.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
|
||||||
|
import * as commonServer from "@homarr/common/server";
|
||||||
|
|
||||||
|
import type { PreparedIntegration } from "../../prepare/prepare-integrations";
|
||||||
|
import { mapAndDecryptIntegrations } from "../map-integration";
|
||||||
|
|
||||||
|
describe("Map Integrations", () => {
|
||||||
|
test("should map proxmox integration", () => {
|
||||||
|
vi.spyOn(commonServer, "decryptSecretWithKey").mockReturnValue("user@realm!tokenId=secret");
|
||||||
|
|
||||||
|
const proxmoxIntegration: PreparedIntegration = {
|
||||||
|
type: "proxmox",
|
||||||
|
name: "Proxmox",
|
||||||
|
url: "https://proxmox.com",
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
field: "apiKey",
|
||||||
|
value: "any-encrypted-value",
|
||||||
|
type: "private",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const mappedIntegrations = mapAndDecryptIntegrations([proxmoxIntegration], "encryptionToken");
|
||||||
|
|
||||||
|
expect(mappedIntegrations[0]?.secrets).toEqual([
|
||||||
|
{
|
||||||
|
field: "username",
|
||||||
|
value: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "realm",
|
||||||
|
value: "realm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "tokenId",
|
||||||
|
value: "tokenId",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "apiKey",
|
||||||
|
value: "secret",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user