diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8cbf69d --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +Copyright 2024 Codomain Data Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ffdd28c --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# DummyIDP + +[DummyIDP](https://ssoready.com/docs/dummyidp) is a website you can use to test +your application's SAML and SCIM support end-to-end. From your application's +perspective, it's exactly like the identity provider ("IDP") your customers use, +but unlike commercial IDPs there's no "input your email" or "talk to sales" step +to use DummyIDP. + +DummyIDP implements the "Identity Provider" side of the SAML and SCIM protocols. +It is meant for use as a way to test your application's support for the "Service +Provider" side of the SAML and SCIM protocols. See ["DummyIDP Security +Posture"](https://ssoready.com/docs/dummyidp#dummyidp-security-posture) for +details. + +## Local development / self-hosting + +DummyIDP is available for free online at https://dummyidp.com. You can also +self-host it or hack on it locally. + +DummyIDP is a Next.js application. It is deployed in production on Vercel. You +can hack on it yourself by running: + +```bash +npm run dev +``` diff --git a/public/DummyIDP-Assertion.xml.png b/public/DummyIDP-Assertion.xml.png new file mode 100644 index 0000000..0167959 Binary files /dev/null and b/public/DummyIDP-Assertion.xml.png differ diff --git a/public/SCIM-Request.http.png b/public/SCIM-Request.http.png new file mode 100644 index 0000000..4fba136 Binary files /dev/null and b/public/SCIM-Request.http.png differ diff --git a/src/app/apps/[id]/page.tsx b/src/app/apps/[id]/page.tsx index 9a3f561..155078f 100644 --- a/src/app/apps/[id]/page.tsx +++ b/src/app/apps/[id]/page.tsx @@ -31,6 +31,7 @@ import { SimulateLoginButton } from "@/app/apps/[id]/SimulateLoginButton"; import { SCIMSettingsForm } from "@/app/apps/[id]/SCIMSettingsForm"; import { Metadata } from "next"; import { INSECURE_PUBLIC_CERTIFICATE } from "@/lib/insecure-cert"; +import { Badge } from "@/components/ui/badge"; export const metadata: Metadata = { title: "App", @@ -142,6 +143,15 @@ export default async function Page({ params }: { params: { id: string } }) { SCIM Settings + {app.scimBaseUrl && app.scimBearerToken && ( + + Syncing + + + + + + )} Settings for directory syncing over SCIM. Optional. diff --git a/src/app/page.tsx b/src/app/page.tsx index 124a1aa..89b9f39 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,50 +1,183 @@ -import CreateAppButton from "@/components/CreateAppButton"; +import CreateAppButton, { + InlineCreateAppLink, +} from "@/components/CreateAppButton"; import Navbar from "@/components/Navbar"; import Link from "next/link"; import { ChevronRightIcon } from "@radix-ui/react-icons"; +import { clsx } from "clsx"; export default function Page() { return ( -
-
+ <> +
+
-
-
-
- +
+
+ + Implementing SAML? Check out SSOReady + + + } + /> +
+ +
+

+ SAML made easy +

+

+ DummyIDP lets you test SAML and SCIM without setting up a + full-blown identity provider +

+ - -
+ +
+
+

+ Test SAML & SCIM with ease +

+

+ Everything you need to test an Enterprise SSO implementation, + without talking to sales +

+ +
+ + } + fade={["bottom"]} + className="max-lg:rounded-t-4xl lg:col-span-3 lg:rounded-tl-4xl" + /> + + } + fade={["bottom"]} + className="lg:col-span-3 lg:rounded-tr-4xl" + /> + + No need to talk to sales or give us your email. Just{" "} + + + create an app + + {" "} + and get going. + + } + className="lg:col-span-2 lg:rounded-bl-4xl" + /> + + + The DummyIDP.com service is free for anyone to use. You can + self-host or{" "} + + fork us on GitHub + + . + + } + className="max-lg:rounded-b-4xl lg:col-span-2 lg:rounded-br-4xl" + /> +
+
+
+ + ); +} + +function BentoCard({ + className = "", + eyebrow, + title, + description, + graphic, + fade = [], + tall, +}: { + dark?: boolean; + className?: string; + eyebrow: React.ReactNode; + title: React.ReactNode; + description: React.ReactNode; + graphic?: React.ReactNode; + fade?: ("top" | "bottom")[]; + tall?: boolean; +}) { + return ( +
+
+ {graphic} + {fade.includes("top") && ( +
+ )} + {fade.includes("bottom") && ( +
+ )} +
+
+

+ {eyebrow} +

+

+ {title} +

+

+ {description} +

+
); } diff --git a/src/components/CreateAppButton.tsx b/src/components/CreateAppButton.tsx index 55d3283..5bf01eb 100644 --- a/src/components/CreateAppButton.tsx +++ b/src/components/CreateAppButton.tsx @@ -23,3 +23,15 @@ export default function CreateAppButton() {
); } + +export function InlineCreateAppLink({ + children, +}: { + children?: React.ReactNode; +}) { + return ( + createApp()}> + {children} + + ); +} diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 959a7c6..30bb9ba 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -60,7 +60,7 @@ export function Footer() { Read the docs diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index c5c929e..0da02a0 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import Image from "next/image"; import wordmark from "@/wordmark.svg"; import React from "react"; +import { InlineCreateAppLink } from "@/components/CreateAppButton"; const links = [ { href: "https://ssoready.com/docs/dummyidp", label: "Docs" }, @@ -23,6 +24,13 @@ function DesktopNav() { ))} + + +
+ Create a DummyIDP App +
+
+
); } diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx new file mode 100644 index 0000000..da6c375 --- /dev/null +++ b/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-md border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 dark:border-slate-800 dark:focus:ring-slate-300", + { + variants: { + variant: { + default: + "border-transparent bg-slate-900 text-slate-50 shadow hover:bg-slate-900/80 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/80", + secondary: + "border-transparent bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80", + destructive: + "border-transparent bg-red-500 text-slate-50 shadow hover:bg-red-500/80 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/80", + outline: "text-slate-950 dark:text-slate-50", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants }