From 2c14bfebc9792b67d5d246807f829f1861bf4a46 Mon Sep 17 00:00:00 2001 From: Ulysse Carion Date: Mon, 7 Oct 2024 08:58:11 -0700 Subject: [PATCH] Make "create app" UI nicer, and make IDP redirect URIs use custom domain (#3) --- src/app/actions.ts | 1 - src/app/app.ts | 2 +- src/app/apps/[id]/login/LoginForm.tsx | 1 + src/components/CreateAppButton.tsx | 20 +++++++++++++++----- src/lib/saml.ts | 5 +++-- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/app/actions.ts b/src/app/actions.ts index 2f2613d..08271ad 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -4,7 +4,6 @@ import { kv } from "@vercel/kv"; import { redirect } from "next/navigation"; import { ulid } from "ulid"; import { App } from "@/app/app"; -import { list } from "postcss"; export async function createApp() { const id = `app_${ulid().toLowerCase()}`; diff --git a/src/app/app.ts b/src/app/app.ts index ab2bd99..f488385 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -18,5 +18,5 @@ export function appIdpEntityId(app: App): string { } export function appIdpRedirectUrl(app: App): string { - return `https://${process.env.VERCEL_URL}/apps/${app.id}/sso`; + return `https://${process.env.DUMMYIDP_CUSTOM_DOMAIN || process.env.VERCEL_URL}/apps/${app.id}/sso`; } diff --git a/src/app/apps/[id]/login/LoginForm.tsx b/src/app/apps/[id]/login/LoginForm.tsx index 54890af..2e01a7b 100644 --- a/src/app/apps/[id]/login/LoginForm.tsx +++ b/src/app/apps/[id]/login/LoginForm.tsx @@ -98,6 +98,7 @@ export function LoginForm({ setAssertion( await encodeAssertion(key, { + assertionId: crypto.randomUUID(), idpEntityId: appIdpEntityId(app), subjectId: user.email, firstName: user.firstName, diff --git a/src/components/CreateAppButton.tsx b/src/components/CreateAppButton.tsx index a27c7f3..55d3283 100644 --- a/src/components/CreateAppButton.tsx +++ b/src/components/CreateAppButton.tsx @@ -1,15 +1,25 @@ "use client"; import { createApp } from "@/app/actions"; +import { useState } from "react"; +import { SymbolIcon } from "@radix-ui/react-icons"; +import clsx from "clsx"; export default function CreateAppButton() { + const [loading, setLoading] = useState(false); return ( - createApp()} - href="#" +
{ + setLoading(true); + createApp(); + }} > Get started - + {loading && } +
); } diff --git a/src/lib/saml.ts b/src/lib/saml.ts index bc1be32..ffdbc5d 100644 --- a/src/lib/saml.ts +++ b/src/lib/saml.ts @@ -1,4 +1,5 @@ export interface AssertionData { + assertionId: string; idpEntityId: string; subjectId: string; firstName: string; @@ -30,7 +31,7 @@ function signedAssertion( digest: string, signature: string, ): string { - return `${digest}${signature}MIIDBzCCAe+gAwIBAgIUCLBK4f75EXEe4gyroYnVaqLoSp4wDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIZHVtbXlpZHAwHhcNMjQwNTEzMjE1NDE2WhcNMzQwNTExMjE1NDE2WjATMREwDwYDVQQDDAhkdW1teWlkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKhmgQmWb8NvGhz952XY4SlJlpWIK72RilhOZS9frDYhqWVJHsGH9Z7sSzrM/0+YvCyEWuZV9gpMeIaHZxEPDqW3RJ7KG51fn/s/qFvwctf+CZDjyfGDzYs+XIgf7p56U48EmYeWpB/aUW64gSbnPqrtWmVFBisOfIx5aY3NubtTsn+g0XbdX0L57+NgSvPQHXh/GPXA7xCIWm54G5kqjozxbKEFA0DS3yb6oHRQWHqIAM/7mJMdUVZNIV1q7c2JIgAl23uDWq+2KTE2R5liP/KjvjwKonVKtTqGqX6ei25rsTHOaDpBH/LdQK2txgsm7R7+IThWNvUI0TttrmwBqyMCAwEAAaNTMFEwHQYDVR0OBBYEFD142gxIAJMhpgMkgpzmRNoW9XbEMB8GA1UdIwQYMBaAFD142gxIAJMhpgMkgpzmRNoW9XbEMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADQd6k6zFIc20GfGHY5C2MFwyGOmP5/UG/JiTq7Zky28G6D0NA0je+GztzXx7VYDfCfHxLcm2k5t9nYhb9kVawiLUUDVF6s+yZUXA4gUA3KoTWh1/oRxR3ggW7dKYm9fsNOdQAbxUUkzp7HLZ45ZlpKUS0hO7es+fPyF5KVw0g0SrtQWwWucnQMAQE9m+B0aOf+92y7JQkdgdR8Gd/XZ4NZfoOnKV7A1utT4rWxYCgICeRTHx9tly5OhPW4hQr5qOpngcsJ9vhr86IjznQXhfj3hql5lA3VbHW04ro37ROIkh2bShDq5dwJJHpYCGrF3MQv8S3m+jzGhYL6m9gFTm/8=${assertionData.idpEntityId}${assertionData.subjectId}${assertionData.spEntityId}${assertionData.firstName}${assertionData.lastName}`; + return `${digest}${signature}MIIDBzCCAe+gAwIBAgIUCLBK4f75EXEe4gyroYnVaqLoSp4wDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIZHVtbXlpZHAwHhcNMjQwNTEzMjE1NDE2WhcNMzQwNTExMjE1NDE2WjATMREwDwYDVQQDDAhkdW1teWlkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKhmgQmWb8NvGhz952XY4SlJlpWIK72RilhOZS9frDYhqWVJHsGH9Z7sSzrM/0+YvCyEWuZV9gpMeIaHZxEPDqW3RJ7KG51fn/s/qFvwctf+CZDjyfGDzYs+XIgf7p56U48EmYeWpB/aUW64gSbnPqrtWmVFBisOfIx5aY3NubtTsn+g0XbdX0L57+NgSvPQHXh/GPXA7xCIWm54G5kqjozxbKEFA0DS3yb6oHRQWHqIAM/7mJMdUVZNIV1q7c2JIgAl23uDWq+2KTE2R5liP/KjvjwKonVKtTqGqX6ei25rsTHOaDpBH/LdQK2txgsm7R7+IThWNvUI0TttrmwBqyMCAwEAAaNTMFEwHQYDVR0OBBYEFD142gxIAJMhpgMkgpzmRNoW9XbEMB8GA1UdIwQYMBaAFD142gxIAJMhpgMkgpzmRNoW9XbEMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADQd6k6zFIc20GfGHY5C2MFwyGOmP5/UG/JiTq7Zky28G6D0NA0je+GztzXx7VYDfCfHxLcm2k5t9nYhb9kVawiLUUDVF6s+yZUXA4gUA3KoTWh1/oRxR3ggW7dKYm9fsNOdQAbxUUkzp7HLZ45ZlpKUS0hO7es+fPyF5KVw0g0SrtQWwWucnQMAQE9m+B0aOf+92y7JQkdgdR8Gd/XZ4NZfoOnKV7A1utT4rWxYCgICeRTHx9tly5OhPW4hQr5qOpngcsJ9vhr86IjznQXhfj3hql5lA3VbHW04ro37ROIkh2bShDq5dwJJHpYCGrF3MQv8S3m+jzGhYL6m9gFTm/8=${assertionData.idpEntityId}${assertionData.subjectId}${assertionData.spEntityId}${assertionData.firstName}${assertionData.lastName}`; } async function signatureValue( @@ -61,7 +62,7 @@ async function digestValue(assertionData: AssertionData): Promise { } function digestPart(assertionData: AssertionData): string { - return `${assertionData.idpEntityId}${assertionData.subjectId}${assertionData.spEntityId}${assertionData.firstName}${assertionData.lastName}`; + return `${assertionData.idpEntityId}${assertionData.subjectId}${assertionData.spEntityId}${assertionData.firstName}${assertionData.lastName}`; } function arrayBufferToBase64(buffer: ArrayBuffer): string {