From 2962e4b56b38891954a30d2224196a57d1561ffe Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Tue, 17 Jun 2025 10:37:51 -0700 Subject: [PATCH] Fix missing confirmation email page Signed-off-by: Bryan Frimin --- .../src/pages/auth/ConfirmInvitationPage.tsx | 120 ++++++++++++++++++ apps/console/src/routes.tsx | 4 + pkg/usrmgr/usrmgr.go | 2 +- 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 apps/console/src/pages/auth/ConfirmInvitationPage.tsx diff --git a/apps/console/src/pages/auth/ConfirmInvitationPage.tsx b/apps/console/src/pages/auth/ConfirmInvitationPage.tsx new file mode 100644 index 000000000..236b7064b --- /dev/null +++ b/apps/console/src/pages/auth/ConfirmInvitationPage.tsx @@ -0,0 +1,120 @@ +import { Link, useNavigate } from "react-router"; +import { Button, Field, useToast } from "@probo/ui"; +import { useTranslate } from "@probo/i18n"; +import { z } from "zod"; +import { useFormWithSchema } from "/hooks/useFormWithSchema"; +import { usePageTitle } from "@probo/hooks"; +import { buildEndpoint } from "/providers/RelayProviders"; +import { useEffect } from "react"; + +const schema = z.object({ + token: z.string(), + password: z.string().min(8), +}); + +export default function ConfirmInvitationPage() { + const { __ } = useTranslate(); + const navigate = useNavigate(); + const { toast } = useToast(); + const { register, handleSubmit, formState, setValue } = useFormWithSchema( + schema, + { + defaultValues: { + token: "", + password: "", + }, + } + ); + + const onSubmit = handleSubmit(async (data) => { + const response = await fetch( + buildEndpoint("/api/console/v1/auth/invitation"), + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + credentials: "include", + body: JSON.stringify(data), + } + ); + + // Registration failed + if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + toast({ + title: __("Confirmation failed"), + description: errorData.message || __("Confirmation failed"), + variant: "error", + }); + return; + } + + toast({ + title: __("Success"), + description: __("Invitation confirmed successfully"), + variant: "success", + }); + navigate("/", { replace: true }); + }); + + usePageTitle(__("Confirm invitation")); + + useEffect(() => { + const searchParams = new URLSearchParams(location.search); + const urlToken = searchParams.get("token"); + + if (urlToken) { + setValue("token", urlToken); + } + }, [location.search, setValue]); + + return ( +
+
+

{__("Sign up")}

+

+ {__("Enter your information to create an account")} +

+
+ +
+ + + + + + + +
+

+ {__("Already have an account?")}{" "} + + {__("Log in here")} + +

+
+
+ ); +} diff --git a/apps/console/src/routes.tsx b/apps/console/src/routes.tsx index ee1e51ce2..e8a4ebad0 100644 --- a/apps/console/src/routes.tsx +++ b/apps/console/src/routes.tsx @@ -66,6 +66,10 @@ const routes = [ path: "confirm-email", Component: lazy(() => import("./pages/auth/ConfirmEmailPage")), }, + { + path: "confirm-invitation", + Component: lazy(() => import("./pages/auth/ConfirmInvitationPage")), + }, ], }, { diff --git a/pkg/usrmgr/usrmgr.go b/pkg/usrmgr/usrmgr.go index 6add81e4b..4e1de852c 100644 --- a/pkg/usrmgr/usrmgr.go +++ b/pkg/usrmgr/usrmgr.go @@ -713,7 +713,7 @@ func (s Service) InviteUser( confirmationInvitationUrl := url.URL{ Scheme: "https", Host: s.hostname, - Path: "/confirm-invitation", + Path: "/auth/confirm-invitation", RawQuery: url.Values{ "token": []string{confirmationToken}, }.Encode(),