Skip to content

Commit

Permalink
feat: attempt to make secrets allow empty
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-rw committed Jul 22, 2024
1 parent 7ae59e4 commit 38e48f6
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
"use client";

import { useCallback } from "react";
import {useCallback} from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Alert, Button, Fieldset, Group, SegmentedControl, Stack, Text, TextInput } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";

import { clientApi } from "@homarr/api/client";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import { getAllSecretKindOptions } from "@homarr/definitions";
import type { UseFormReturnType } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import { convertIntegrationTestConnectionError } from "@homarr/integrations/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import {clientApi} from "@homarr/api/client";
import type {IntegrationKind, IntegrationSecretKind} from "@homarr/definitions";
import {getAllSecretKindOptions} from "@homarr/definitions";
import type {UseFormReturnType} from "@homarr/form";
import {useZodForm} from "@homarr/form";
import {convertIntegrationTestConnectionError} from "@homarr/integrations/client";
import {showErrorNotification, showSuccessNotification} from "@homarr/notifications";
import {useI18n, useScopedI18n} from "@homarr/translation/client";
import type {z} from "@homarr/validation";
import {validation} from "@homarr/validation";

import { IntegrationSecretInput } from "../_components/secrets/integration-secret-inputs";
import { revalidatePathActionAsync } from "../../../../revalidatePathAction";
import {IntegrationSecretInput} from "../_components/secrets/integration-secret-inputs";
import {revalidatePathActionAsync} from "../../../../revalidatePathAction";

interface NewIntegrationFormProps {
searchParams: Partial<z.infer<typeof validation.integration.create>> & {
kind: IntegrationKind;
};
}

export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) => {
export const NewIntegrationForm = ({searchParams}: NewIntegrationFormProps) => {
const t = useI18n();
const secretKinds = getAllSecretKindOptions(searchParams.kind);
const router = useRouter();
const form = useZodForm(validation.integration.create.omit({ kind: true }), {
const form = useZodForm(validation.integration.create.omit({kind: true}), {
initialValues: {
name: searchParams.name ?? "",
url: searchParams.url ?? "",
secrets: secretKinds[0].map((kind) => ({
secrets: secretKinds[0]?.map((kind) => ({
kind,
value: "",
})),
},
});
const { mutateAsync, isPending } = clientApi.integration.create.useMutation();
const {mutateAsync, isPending} = clientApi.integration.create.useMutation();

const handleSubmitAsync = async (values: FormType) => {
await mutateAsync(
Expand Down Expand Up @@ -122,7 +122,7 @@ interface SecretKindsSegmentedControlProps {
form: UseFormReturnType<FormType, (values: FormType) => FormType>;
}

const SecretKindsSegmentedControl = ({ secretKinds, form }: SecretKindsSegmentedControlProps) => {
const SecretKindsSegmentedControl = ({secretKinds, form}: SecretKindsSegmentedControlProps) => {
const t = useScopedI18n("integration.secrets");

const secretKindGroups = secretKinds.map((kinds) => ({
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/router/integration/integration-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const integrationRouter = createTRPCRouter({
name: input.name,
url: input.url,
kind: input.kind,
secrets: input.secrets,
secrets: !input.secrets ? null : input.secrets,
});

const integrationId = createId();
Expand All @@ -88,7 +88,7 @@ export const integrationRouter = createTRPCRouter({
kind: input.kind,
});

if (input.secrets.length >= 1) {
if (input.secrets && input.secrets.length >= 1) {
await ctx.db.insert(integrationSecrets).values(
input.secrets.map((secret) => ({
kind: secret.kind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ export const testConnectionAsync = async (
value: `${string}.${string}`;
}[] = [],
) => {
const formSecrets = integration.secrets
const formSecrets = integration.secrets !== null ? integration.secrets
.filter((secret) => secret.value !== null)
.map((secret) => ({
...secret,
// We ensured above that the value is not null
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
value: secret.value!,
source: "form" as const,
}));
})) : [];

const decryptedDbSecrets = dbSecrets.map((secret) => ({
...secret,
Expand All @@ -35,10 +35,13 @@ export const testConnectionAsync = async (
}));

const sourcedSecrets = [...formSecrets, ...decryptedDbSecrets];
console.log('sourcedSecrets' + JSON.stringify(sourcedSecrets));
const secretKinds = getSecretKindOption(integration.kind, sourcedSecrets);
console.log('secretKinds' + JSON.stringify(secretKinds));

const filteredSecrets = secretKinds.map((kind) => {
const secrets = sourcedSecrets.filter((secret) => secret.kind === kind);

// Will never be undefined because of the check before
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (secrets.length === 1) return secrets[0]!;
Expand Down
2 changes: 1 addition & 1 deletion packages/validation/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const integrationCreateSchema = z.object({
kind: zodEnumFromArray(integrationSecretKinds),
value: z.string().nonempty(),
}),
),
).optional(),
});

const integrationUpdateSchema = z.object({
Expand Down

0 comments on commit 38e48f6

Please sign in to comment.