diff --git a/public/index.html b/public/index.html index d677717..8e4390e 100644 --- a/public/index.html +++ b/public/index.html @@ -9,9 +9,15 @@ + + -
+
diff --git a/public/wordart.png b/public/wordart.png index 2bee76e..ffe6a8d 100644 Binary files a/public/wordart.png and b/public/wordart.png differ diff --git a/src/App.tsx b/src/App.tsx index 07e1eeb..3de2d3e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,10 +11,10 @@ export function App() { } /> + } /> }> } /> } /> - } /> diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 0000000..6d7f122 --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,29 @@ +import * as React from "react" +import * as SeparatorPrimitive from "@radix-ui/react-separator" + +import { cn } from "@/lib/utils" + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref + ) => ( + + ) +) +Separator.displayName = SeparatorPrimitive.Root.displayName + +export { Separator } diff --git a/src/pages/SSOPage.tsx b/src/pages/SSOPage.tsx index b2e3789..c4ca0ae 100644 --- a/src/pages/SSOPage.tsx +++ b/src/pages/SSOPage.tsx @@ -27,6 +27,7 @@ import { import { useSearchParams } from "react-router-dom"; import moment from "moment"; import { clsx } from "clsx"; +import { Separator } from "@/components/ui/separator"; const formSchema = z.object({ email: z.string().min(1, { message: "Email is required." }), @@ -82,118 +83,148 @@ export function SSOPage() { }); async function onSubmit(values: z.infer, e: any) { - const key = await window.crypto.subtle.importKey( - "jwk", - GLOBAL_NONSECURE_KEY, - { - name: "RSASSA-PKCS1-v1_5", - hash: "SHA-256", - }, - true, - ["sign"], - ); + setLoading(true); - const now = moment(new Date()).add(-1, "hour"); - const expire = moment(new Date()).add(1, "hour"); + setTimeout(async () => { + const key = await window.crypto.subtle.importKey( + "jwk", + GLOBAL_NONSECURE_KEY, + { + name: "RSASSA-PKCS1-v1_5", + hash: "SHA-256", + }, + true, + ["sign"], + ); - inputRef.current!.value = await encodeAssertion(key, { - idpEntityId: `https://dummyidp.com/apps/${app.id}`, - subjectId: `${values.email}@${app.requiredDomain}`, - firstName: values.firstName, - lastName: values.lastName, - spEntityId: app.spEntityId, - sessionId: sessionId, - now: now.format(), - expire: expire.format(), - }); - inputRef.current!.form!.action = app.spAcsUrl; - inputRef.current!.form!.submit(); + const now = moment(new Date()).add(-1, "hour"); + const expire = moment(new Date()).add(1, "hour"); + + inputRef.current!.value = await encodeAssertion(key, { + idpEntityId: `https://dummyidp.com/apps/${app.id}`, + subjectId: `${values.email}@${app.requiredDomain}`, + firstName: values.firstName, + lastName: values.lastName, + spEntityId: app.spEntityId, + sessionId: sessionId, + now: now.format(), + expire: expire.format(), + }); + inputRef.current!.form!.action = app.spAcsUrl; + inputRef.current!.form!.submit(); + }, 1000); } + const [loading, setLoading] = useState(false); const inputRef = useRef(null); return ( - <> +
- - - Log on - - Enter some details about who you want DummyIDP to log you in as. - - - -
- - ( - - Email - -
- - - @{app.requiredDomain} - -
-
+
+ {loading && ( +
+ loading +
+ )} + + + Log on + + Enter some details about who you want DummyIDP to say you are. + + + + + + ( + + Email + +
+ + + @{app.requiredDomain} + +
+
- -
- )} - /> - - ( - - First Name - - - - - - )} - /> - - ( - - Last Name - - - - - - )} - /> - -
- -
- - -
-
- + /> + + ( + + First Name + + + + + + )} + /> + + ( + + Last Name + + + + + + )} + /> + +
+ +
+ + + + + +
+

+ DummyIDP is a fake identity provider. It's a dummy stand-in for + something like Okta, Google Workspace, or Microsoft Entra. +

+

+ In the real world, your customers would never see or interact + with DummyIDP in any way. In the real world, your customers + would see their own IDP, not this fake one. +

+

+ We made DummyIDP because there doesn't exist any free, no-hassle + SAML Identity Provider out there that developers can test with. +

+
+ + +
+
); }