diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx
index 231de6ddb84..7cd2fd5df03 100644
--- a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/auth-options-form.client.tsx
@@ -1,9 +1,22 @@
"use client";
import { ConfirmationDialog } from "@/components/ui/ConfirmationDialog";
+import { Button } from "@/components/ui/button";
+import { Card } from "@/components/ui/card";
import { Checkbox, CheckboxWithLabel } from "@/components/ui/checkbox";
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form";
+import { FormDescription } from "@/components/ui/form";
+import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import { useState } from "react";
+import { useFieldArray, useForm } from "react-hook-form";
import { toast } from "sonner";
import invariant from "tiny-invariant";
import { type Ecosystem, authOptions } from "../../../../types";
@@ -25,65 +38,212 @@ export function AuthOptionsForm({ ecosystem }: { ecosystem: Ecosystem }) {
} = useUpdateEcosystem({
onError: (error) => {
const message =
- error instanceof Error ? error.message : "Failed to create ecosystem";
+ error instanceof Error ? error.message : "Failed to update ecosystem";
toast.error(message);
},
});
return (
-
- {authOptions.map((option) => (
-
- {
- if (ecosystem.authOptions.includes(option)) {
- setMessageToConfirm({
- title: `Are you sure you want to remove ${option.slice(0, 1).toUpperCase() + option.slice(1)} as an authentication option for this ecosystem?`,
- description:
- "Users will no longer be able to log into your ecosystem using this option. Any users that previously used this option will be unable to log in.",
- authOptions: ecosystem.authOptions.filter(
- (o) => o !== option,
- ),
- });
- } else {
- setMessageToConfirm({
- title: `Are you sure you want to add ${option.slice(0, 1).toUpperCase() + option.slice(1)} as an authentication option for this ecosystem?`,
- description:
- "Users will be able to log into your ecosystem using this option. If you later remove this option users that used it will no longer be able to log in.",
- authOptions: [...ecosystem.authOptions, option],
- });
- }
- }}
- />
- {option.slice(0, 1).toUpperCase() + option.slice(1)}
-
- ))}
-
{
- if (!open) {
- setMessageToConfirm(undefined);
- }
- }}
- title={messageToConfirm?.title}
- description={messageToConfirm?.description}
- onSubmit={() => {
- invariant(messageToConfirm, "Must have message for modal to be open");
- updateEcosystem({
- ecosystem,
- authOptions: messageToConfirm.authOptions,
- });
- }}
- />
+
+
+ {authOptions.map((option) => (
+
+ {
+ if (ecosystem.authOptions?.includes(option)) {
+ setMessageToConfirm({
+ title: `Are you sure you want to remove ${option.slice(0, 1).toUpperCase() + option.slice(1)} as an authentication option for this ecosystem?`,
+ description:
+ "Users will no longer be able to log into your ecosystem using this option. Any users that previously used this option will be unable to log in.",
+ authOptions: ecosystem.authOptions?.filter(
+ (o) => o !== option,
+ ),
+ });
+ } else {
+ setMessageToConfirm({
+ title: `Are you sure you want to add ${option.slice(0, 1).toUpperCase() + option.slice(1)} as an authentication option for this ecosystem?`,
+ description:
+ "Users will be able to log into your ecosystem using this option. If you later remove this option users that used it will no longer be able to log in.",
+ authOptions: [...ecosystem.authOptions, option],
+ });
+ }
+ }}
+ />
+ {option.slice(0, 1).toUpperCase() + option.slice(1)}
+
+ ))}
+ {
+ if (!open) {
+ setMessageToConfirm(undefined);
+ }
+ }}
+ title={messageToConfirm?.title}
+ description={messageToConfirm?.description}
+ onSubmit={() => {
+ invariant(
+ messageToConfirm,
+ "Must have message for modal to be open",
+ );
+ updateEcosystem({
+ ...ecosystem,
+ authOptions: messageToConfirm.authOptions,
+ });
+ }}
+ />
+
+
+
+ );
+}
+
+function CustomAuthOptionsForm({ ecosystem }: { ecosystem: Ecosystem }) {
+ const form = useForm({
+ defaultValues: {
+ customAuthEndpoint: ecosystem.customAuthOptions?.authEndpoint?.url,
+ customHeaders: ecosystem.customAuthOptions?.authEndpoint?.headers,
+ },
+ });
+ const { fields, remove, append } = useFieldArray({
+ control: form.control,
+ name: "customHeaders",
+ });
+ const { mutateAsync: updateEcosystem, isPending } = useUpdateEcosystem({
+ onError: (error) => {
+ const message =
+ error instanceof Error ? error.message : "Failed to update ecosystem";
+ toast.error(message);
+ },
+ onSuccess: () => {
+ toast.success("Custom Auth Options updated");
+ },
+ });
+ return (
+
+
+ Custom Auth Options
+
+
+
+
);
}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/integration-permissions-toggle.client.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/integration-permissions-toggle.client.tsx
index 330e9428d5f..eaaec5c6a21 100644
--- a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/integration-permissions-toggle.client.tsx
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/integration-permissions-toggle.client.tsx
@@ -89,7 +89,7 @@ export function IntegrationPermissionsToggle({
onSubmit={() => {
invariant(messageToConfirm, "Must have message for modal to be open");
updateEcosystem({
- ecosystem,
+ ...ecosystem,
permission: messageToConfirm.permission,
});
}}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-update-ecosystem.ts b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-update-ecosystem.ts
index 9525f1aa7b1..9af2c713066 100644
--- a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-update-ecosystem.ts
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-update-ecosystem.ts
@@ -4,19 +4,10 @@ import {
useMutation,
useQueryClient,
} from "@tanstack/react-query";
-import type { AuthOption, Ecosystem } from "../../../types";
-
-type UpdateEcosystemParams = {
- ecosystem: Ecosystem;
- permission?: "PARTNER_WHITELIST" | "ANYONE";
- authOptions?: AuthOption[];
-};
+import type { Ecosystem } from "../../../types";
export function useUpdateEcosystem(
- options?: Omit<
- UseMutationOptions,
- "mutationFn"
- >,
+ options?: Omit, "mutationFn">,
) {
const { onSuccess, ...queryOptions } = options || {};
const { isLoggedIn, user } = useLoggedInUser();
@@ -24,25 +15,19 @@ export function useUpdateEcosystem(
return useMutation({
// Returns true if the update was successful
- mutationFn: async (params: UpdateEcosystemParams): Promise => {
+ mutationFn: async (params: Ecosystem): Promise => {
if (!isLoggedIn || !user?.jwt) {
throw new Error("Please login to update this ecosystem");
}
- const res = await fetch(
- `${params.ecosystem.url}/${params.ecosystem.id}`,
- {
- method: "PATCH",
- headers: {
- "Content-Type": "application/json",
- Authorization: `Bearer ${user.jwt}`,
- },
- body: JSON.stringify({
- permission: params.permission,
- authOptions: params.authOptions,
- }),
+ const res = await fetch(`${params.url}/${params.id}`, {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${user.jwt}`,
},
- );
+ body: JSON.stringify(params),
+ });
if (!res.ok) {
const body = await res.json();
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts
index b9ea79d386f..b8607d1c66d 100644
--- a/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/types.ts
@@ -13,7 +13,6 @@ export const authOptions = [
"coinbase",
"line",
] as const;
-export type AuthOption = (typeof authOptions)[number];
export type Ecosystem = {
name: string;
@@ -22,6 +21,21 @@ export type Ecosystem = {
slug: string;
permission: "PARTNER_WHITELIST" | "ANYONE";
authOptions: (typeof authOptions)[number][];
+ customAuthOptions?: {
+ authEndpoint?: {
+ url: string;
+ headers?: { key: string; value: string }[];
+ };
+ jwt?: {
+ jwksUri: string;
+ aud: string;
+ };
+ };
+ smartAccountOptions?: {
+ chainIds: number[];
+ sponsorGas: boolean;
+ accountFactoryAddress: string;
+ };
url: string;
status: "active" | "requested" | "paymentFailed";
createdAt: string;