diff --git a/packages/db/migrations/mysql/0042_add_widget_secret.sql b/packages/db/migrations/mysql/0042_add_widget_secret.sql new file mode 100644 index 000000000..4d150612d --- /dev/null +++ b/packages/db/migrations/mysql/0042_add_widget_secret.sql @@ -0,0 +1,9 @@ +CREATE TABLE `widget_secret` ( + `item_id` varchar(64) NOT NULL, + `kind` varchar(64) NOT NULL, + `value` text NOT NULL, + `updated_at` timestamp NOT NULL, + CONSTRAINT `widget_secret_item_id_kind_pk` PRIMARY KEY(`item_id`,`kind`) +); +--> statement-breakpoint +ALTER TABLE `widget_secret` ADD CONSTRAINT `widget_secret_item_id_item_id_fk` FOREIGN KEY (`item_id`) REFERENCES `item`(`id`) ON DELETE cascade ON UPDATE no action; diff --git a/packages/db/migrations/mysql/meta/_journal.json b/packages/db/migrations/mysql/meta/_journal.json index b2665bb91..4ce2bf038 100644 --- a/packages/db/migrations/mysql/meta/_journal.json +++ b/packages/db/migrations/mysql/meta/_journal.json @@ -295,6 +295,13 @@ "when": 1780764500000, "tag": "0041_merge_custom_widget_url", "breakpoints": true + }, + { + "idx": 42, + "version": "5", + "when": 1783176100870, + "tag": "0042_add_widget_secret", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/migrations/postgresql/0008_add_widget_secret.sql b/packages/db/migrations/postgresql/0008_add_widget_secret.sql new file mode 100644 index 000000000..e5423e774 --- /dev/null +++ b/packages/db/migrations/postgresql/0008_add_widget_secret.sql @@ -0,0 +1,9 @@ +CREATE TABLE "widget_secret" ( + "item_id" varchar(64) NOT NULL, + "kind" varchar(64) NOT NULL, + "value" text NOT NULL, + "updated_at" timestamp NOT NULL, + CONSTRAINT "widget_secret_item_id_kind_pk" PRIMARY KEY("item_id","kind") +); +--> statement-breakpoint +ALTER TABLE "widget_secret" ADD CONSTRAINT "widget_secret_item_id_item_id_fk" FOREIGN KEY ("item_id") REFERENCES "public"."item"("id") ON DELETE cascade ON UPDATE no action; diff --git a/packages/db/migrations/postgresql/meta/_journal.json b/packages/db/migrations/postgresql/meta/_journal.json index 495b5e2fb..829168b9e 100644 --- a/packages/db/migrations/postgresql/meta/_journal.json +++ b/packages/db/migrations/postgresql/meta/_journal.json @@ -57,6 +57,13 @@ "when": 1780764500000, "tag": "0007_merge_custom_widget_url", "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1783176100870, + "tag": "0008_add_widget_secret", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/migrations/sqlite/0040_add_widget_secret.sql b/packages/db/migrations/sqlite/0040_add_widget_secret.sql new file mode 100644 index 000000000..06caa5ed4 --- /dev/null +++ b/packages/db/migrations/sqlite/0040_add_widget_secret.sql @@ -0,0 +1,8 @@ +CREATE TABLE `widget_secret` ( + `item_id` text NOT NULL, + `kind` text NOT NULL, + `value` text NOT NULL, + `updated_at` integer NOT NULL, + PRIMARY KEY(`item_id`, `kind`), + FOREIGN KEY (`item_id`) REFERENCES `item`(`id`) ON UPDATE no action ON DELETE cascade +); diff --git a/packages/db/migrations/sqlite/meta/_journal.json b/packages/db/migrations/sqlite/meta/_journal.json index 85ee5fc47..a99a995ce 100644 --- a/packages/db/migrations/sqlite/meta/_journal.json +++ b/packages/db/migrations/sqlite/meta/_journal.json @@ -281,6 +281,13 @@ "when": 1780764500000, "tag": "0039_merge_custom_widget_url", "breakpoints": true + }, + { + "idx": 40, + "version": "6", + "when": 1783176100870, + "tag": "0040_add_widget_secret", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/widgets/src/_inputs/widget-multiReleasesRepositories-input.tsx b/packages/widgets/src/_inputs/widget-multiReleasesRepositories-input.tsx index 675d56330..45c9ed595 100644 --- a/packages/widgets/src/_inputs/widget-multiReleasesRepositories-input.tsx +++ b/packages/widgets/src/_inputs/widget-multiReleasesRepositories-input.tsx @@ -50,6 +50,7 @@ import { } from "@homarr/definitions"; import { findBestIconMatch, IconPicker } from "@homarr/forms-collection"; import { createModal, useModalAction } from "@homarr/modals"; +import { showErrorNotification } from "@homarr/notifications"; import { useScopedI18n } from "@homarr/translation/client"; import { MaskedImage } from "@homarr/ui"; @@ -269,8 +270,24 @@ const providersWithAuth: ReleaseProviderKind[] = [ const ProviderTokensSection = ({ itemId, repositories }: { itemId: string; repositories: ReleasesRepository[] }) => { const tRepository = useScopedI18n("widget.releases.option.repositories"); const { data: configuredKinds = [], refetch } = clientApi.widget.secrets.getConfiguredKinds.useQuery({ itemId }); - const setSecret = clientApi.widget.secrets.setSecret.useMutation({ onSuccess: () => refetch() }); - const deleteSecret = clientApi.widget.secrets.deleteSecret.useMutation({ onSuccess: () => refetch() }); + const setSecret = clientApi.widget.secrets.setSecret.useMutation({ + onSuccess: () => refetch(), + onError: (error) => { + showErrorNotification({ + title: "Failed to save token", + message: error.message, + }); + }, + }); + const deleteSecret = clientApi.widget.secrets.deleteSecret.useMutation({ + onSuccess: () => refetch(), + onError: (error) => { + showErrorNotification({ + title: "Failed to delete token", + message: error.message, + }); + }, + }); const authProviders = useMemo(() => { const usedProviders = repositories.map((r) => r.provider).filter((p): p is ReleaseProviderKind => p !== undefined);