fix: split up proxmox secrets are incorrectly migrated (#2124)

This commit is contained in:
Meier Lukas
2025-01-26 21:24:50 +01:00
committed by GitHub
parent ecbd2d14da
commit 57b523fa80
2 changed files with 114 additions and 10 deletions

View File

@@ -44,17 +44,75 @@ export const mapAndDecryptIntegrations = (
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");
return preparedIntegrations.map(({ type, name, url, properties }) => ({
id: createId(),
name,
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,
})),
const decryptedProperties = 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,
},
];
};

View 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",
},
]);
});
});