2023-07-27 15:54:34 +02:00
|
|
|
"use client";
|
|
|
|
|
import { ReactNode, useState } from "react";
|
|
|
|
|
|
2023-07-27 11:05:42 +02:00
|
|
|
import {
|
|
|
|
|
SignInWithGitlab,
|
|
|
|
|
SignInWithAzureAD,
|
|
|
|
|
SignInWithGoogle,
|
|
|
|
|
SignInWithGithub,
|
|
|
|
|
} from "@zitadel/react";
|
2023-07-27 15:54:34 +02:00
|
|
|
import { useRouter } from "next/navigation";
|
2023-07-28 15:23:17 +02:00
|
|
|
import { ProviderSlug } from "#/lib/demos";
|
2023-08-02 13:25:16 +02:00
|
|
|
import Alert from "./Alert";
|
2023-07-18 13:58:33 +02:00
|
|
|
|
|
|
|
|
export interface SignInWithIDPProps {
|
|
|
|
|
children?: ReactNode;
|
2023-08-02 10:23:55 +02:00
|
|
|
host: string;
|
2023-07-27 15:54:34 +02:00
|
|
|
identityProviders: any[];
|
2023-07-31 11:56:23 +02:00
|
|
|
startIDPFlowPath?: (idpId: string) => string;
|
2023-07-18 13:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-31 11:56:23 +02:00
|
|
|
const START_IDP_FLOW_PATH = (idpId: string) =>
|
2023-09-20 08:34:34 +02:00
|
|
|
`/v2beta/users/idps/${idpId}/start`;
|
2023-07-31 11:56:23 +02:00
|
|
|
|
|
|
|
|
export function SignInWithIDP({
|
2023-08-02 10:23:55 +02:00
|
|
|
host,
|
2023-07-31 11:56:23 +02:00
|
|
|
identityProviders,
|
|
|
|
|
startIDPFlowPath = START_IDP_FLOW_PATH,
|
|
|
|
|
}: SignInWithIDPProps) {
|
2023-07-27 15:54:34 +02:00
|
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
|
|
|
const [error, setError] = useState<string>("");
|
|
|
|
|
const router = useRouter();
|
2023-07-18 13:58:33 +02:00
|
|
|
|
2023-07-31 11:56:23 +02:00
|
|
|
async function startFlow(idpId: string, provider: ProviderSlug) {
|
2023-07-27 15:54:34 +02:00
|
|
|
setLoading(true);
|
|
|
|
|
|
|
|
|
|
const res = await fetch("/api/idp/start", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
2023-07-31 11:56:23 +02:00
|
|
|
idpId,
|
2024-03-15 17:21:21 +01:00
|
|
|
successUrl: `${host}/idp/${provider}/success`,
|
|
|
|
|
failureUrl: `${host}/idp/${provider}/failure`,
|
2023-07-27 15:54:34 +02:00
|
|
|
}),
|
|
|
|
|
});
|
2023-07-27 11:05:42 +02:00
|
|
|
|
2023-07-27 15:54:34 +02:00
|
|
|
const response = await res.json();
|
2023-07-18 13:58:33 +02:00
|
|
|
|
2023-07-27 15:54:34 +02:00
|
|
|
setLoading(false);
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
setError(response.details);
|
|
|
|
|
return Promise.reject(response.details);
|
|
|
|
|
}
|
|
|
|
|
return response;
|
2023-07-27 11:05:42 +02:00
|
|
|
}
|
2023-07-18 13:58:33 +02:00
|
|
|
|
|
|
|
|
return (
|
2023-07-27 11:05:42 +02:00
|
|
|
<div className="flex flex-col w-full space-y-2 text-sm">
|
|
|
|
|
{identityProviders &&
|
2023-07-18 13:58:33 +02:00
|
|
|
identityProviders.map((idp, i) => {
|
|
|
|
|
switch (idp.type) {
|
2023-07-27 15:54:34 +02:00
|
|
|
case 6: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITHUB:
|
2023-07-26 09:30:39 +02:00
|
|
|
return (
|
|
|
|
|
<SignInWithGithub
|
|
|
|
|
key={`idp-${i}`}
|
2023-07-28 15:23:17 +02:00
|
|
|
onClick={() =>
|
2023-07-31 11:56:23 +02:00
|
|
|
startFlow(idp.id, ProviderSlug.GITHUB).then(
|
|
|
|
|
({ authUrl }) => {
|
|
|
|
|
router.push(authUrl);
|
|
|
|
|
}
|
|
|
|
|
)
|
2023-07-28 15:23:17 +02:00
|
|
|
}
|
2023-07-26 09:30:39 +02:00
|
|
|
></SignInWithGithub>
|
|
|
|
|
);
|
2023-07-27 15:54:34 +02:00
|
|
|
case 7: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITHUB_ES:
|
2023-07-26 09:30:39 +02:00
|
|
|
return (
|
|
|
|
|
<SignInWithGithub
|
|
|
|
|
key={`idp-${i}`}
|
2023-08-02 13:14:58 +02:00
|
|
|
onClick={() => alert("TODO: unimplemented")}
|
2023-07-26 09:30:39 +02:00
|
|
|
></SignInWithGithub>
|
|
|
|
|
);
|
2023-07-27 15:54:34 +02:00
|
|
|
case 5: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_AZURE_AD:
|
2023-08-02 13:14:58 +02:00
|
|
|
return (
|
|
|
|
|
<SignInWithAzureAD
|
|
|
|
|
key={`idp-${i}`}
|
|
|
|
|
onClick={() => alert("TODO: unimplemented")}
|
|
|
|
|
></SignInWithAzureAD>
|
|
|
|
|
);
|
2023-07-27 15:54:34 +02:00
|
|
|
case 10: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GOOGLE:
|
2023-07-26 09:30:39 +02:00
|
|
|
return (
|
|
|
|
|
<SignInWithGoogle
|
|
|
|
|
key={`idp-${i}`}
|
2023-08-02 13:44:19 +02:00
|
|
|
e2e="google"
|
|
|
|
|
name={idp.name}
|
2023-07-27 15:54:34 +02:00
|
|
|
onClick={() =>
|
2023-07-31 11:56:23 +02:00
|
|
|
startFlow(idp.id, ProviderSlug.GOOGLE).then(
|
|
|
|
|
({ authUrl }) => {
|
|
|
|
|
router.push(authUrl);
|
|
|
|
|
}
|
|
|
|
|
)
|
2023-07-27 15:54:34 +02:00
|
|
|
}
|
2023-07-26 09:30:39 +02:00
|
|
|
></SignInWithGoogle>
|
|
|
|
|
);
|
2023-07-27 15:54:34 +02:00
|
|
|
case 8: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITLAB:
|
2023-08-02 13:14:58 +02:00
|
|
|
return (
|
|
|
|
|
<SignInWithGitlab
|
|
|
|
|
key={`idp-${i}`}
|
|
|
|
|
onClick={() => alert("TODO: unimplemented")}
|
|
|
|
|
></SignInWithGitlab>
|
|
|
|
|
);
|
2023-07-27 15:54:34 +02:00
|
|
|
case 9: //IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITLAB_SELF_HOSTED:
|
2023-08-02 13:14:58 +02:00
|
|
|
return (
|
|
|
|
|
<SignInWithGitlab
|
|
|
|
|
key={`idp-${i}`}
|
|
|
|
|
onClick={() => alert("TODO: unimplemented")}
|
|
|
|
|
></SignInWithGitlab>
|
|
|
|
|
);
|
2023-07-18 13:58:33 +02:00
|
|
|
default:
|
2023-08-02 13:14:58 +02:00
|
|
|
return null;
|
2023-07-18 13:58:33 +02:00
|
|
|
}
|
2023-07-27 11:05:42 +02:00
|
|
|
})}
|
2023-08-02 13:25:16 +02:00
|
|
|
{error && (
|
|
|
|
|
<div className="py-4">
|
|
|
|
|
<Alert>{error}</Alert>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2023-07-18 13:58:33 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SignInWithIDP.displayName = "SignInWithIDP";
|