mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 06:42:59 +00:00
login with idp
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { ProviderSlug } from "#/lib/demos";
|
||||
import { server } from "#/lib/zitadel";
|
||||
import Alert, { AlertType } from "#/ui/Alert";
|
||||
import { createSessionForIdpAndUpdateCookie } from "#/utils/session";
|
||||
import {
|
||||
AddHumanUserRequest,
|
||||
IDPInformation,
|
||||
@@ -96,21 +97,50 @@ export default async function Page({
|
||||
return retrieveIDP(id, token)
|
||||
.then((information) => {
|
||||
if (information) {
|
||||
return createUser(provider, information).catch((error) => {
|
||||
throw new Error(error.details);
|
||||
});
|
||||
console.log(information);
|
||||
|
||||
// handle login
|
||||
if (information.userId) {
|
||||
return createSessionForIdpAndUpdateCookie(
|
||||
information.userId,
|
||||
{
|
||||
idpIntentId: id,
|
||||
idpIntentToken: token,
|
||||
},
|
||||
undefined
|
||||
)
|
||||
.then((session) => {
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<h1>Login successful</h1>
|
||||
<div>You have successfully been loggedIn!</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
throw new Error(error.details);
|
||||
});
|
||||
} else {
|
||||
// handle register
|
||||
|
||||
return createUser(provider, information)
|
||||
.then((userId) => {
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<h1>Register successful</h1>
|
||||
<div>You have successfully been registered!</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
throw new Error(error.details);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw new Error("Could not get user information.");
|
||||
}
|
||||
})
|
||||
.then((userId) => {
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<h1>Register successful</h1>
|
||||
<div>You have successfully been registered!</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
||||
.catch((error: Error) => {
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
@@ -1,5 +1,31 @@
|
||||
import { getLoginSettings, server } from "#/lib/zitadel";
|
||||
import {
|
||||
getLegalAndSupportSettings,
|
||||
getLoginSettings,
|
||||
server,
|
||||
} from "#/lib/zitadel";
|
||||
import { SignInWithIDP } from "#/ui/SignInWithIDP";
|
||||
import UsernameForm from "#/ui/UsernameForm";
|
||||
import {
|
||||
GetActiveIdentityProvidersResponse,
|
||||
IdentityProvider,
|
||||
ZitadelServer,
|
||||
settings,
|
||||
} from "@zitadel/server";
|
||||
|
||||
function getIdentityProviders(
|
||||
server: ZitadelServer,
|
||||
orgId?: string
|
||||
): Promise<IdentityProvider[] | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
return settingsService
|
||||
.getActiveIdentityProviders(
|
||||
orgId ? { ctx: { orgId } } : { ctx: { instance: true } },
|
||||
{}
|
||||
)
|
||||
.then((resp: GetActiveIdentityProvidersResponse) => {
|
||||
return resp.identityProviders;
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Page({
|
||||
searchParams,
|
||||
@@ -12,6 +38,14 @@ export default async function Page({
|
||||
const submit: boolean = searchParams?.submit === "true";
|
||||
|
||||
const loginSettings = await getLoginSettings(server, organization);
|
||||
const legal = await getLegalAndSupportSettings(server);
|
||||
|
||||
// TODO if org idps should be shown replace emptystring with the orgId.
|
||||
const identityProviders = await getIdentityProviders(server, "");
|
||||
|
||||
const host = process.env.VERCEL_URL
|
||||
? `https://${process.env.VERCEL_URL}`
|
||||
: "http://localhost:3000";
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
@@ -25,6 +59,13 @@ export default async function Page({
|
||||
organization={organization}
|
||||
submit={submit}
|
||||
/>
|
||||
|
||||
{legal && identityProviders && process.env.ZITADEL_API_URL && (
|
||||
<SignInWithIDP
|
||||
host={host}
|
||||
identityProviders={identityProviders}
|
||||
></SignInWithIDP>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,6 +125,23 @@ export async function createSession(
|
||||
);
|
||||
}
|
||||
|
||||
export async function createSessionForUserIdAndIdpIntent(
|
||||
server: ZitadelServer,
|
||||
userId: string,
|
||||
idpIntent: {
|
||||
idpIntentId?: string | undefined;
|
||||
idpIntentToken?: string | undefined;
|
||||
}
|
||||
): Promise<CreateSessionResponse | undefined> {
|
||||
const sessionService = session.getSession(server);
|
||||
return sessionService.createSession(
|
||||
{
|
||||
checks: { user: { userId }, idpIntent },
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
export async function setSession(
|
||||
server: ZitadelServer,
|
||||
sessionId: string,
|
||||
|
||||
@@ -42,8 +42,12 @@ export default function SessionItem({
|
||||
|
||||
const validPassword = session?.factors?.password?.verifiedAt;
|
||||
const validPasskey = session?.factors?.webAuthN?.verifiedAt;
|
||||
const stillValid = session.expirationDate
|
||||
? session.expirationDate > new Date()
|
||||
: true;
|
||||
|
||||
const validUser = validPassword || validPasskey;
|
||||
const validDate = validPassword || validPasskey;
|
||||
const validUser = (validPassword || validPasskey) && stillValid;
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -92,7 +96,7 @@ export default function SessionItem({
|
||||
</span>
|
||||
{validUser && (
|
||||
<span className="text-xs opacity-80">
|
||||
{moment(new Date(validUser)).fromNow()}
|
||||
{validDate && moment(new Date(validDate)).fromNow()}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -40,8 +40,8 @@ export function SignInWithIDP({
|
||||
},
|
||||
body: JSON.stringify({
|
||||
idpId,
|
||||
successUrl: `${host}/register/idp/${provider}/success`,
|
||||
failureUrl: `${host}/register/idp/${provider}/failure`,
|
||||
successUrl: `${host}/idp/${provider}/success`,
|
||||
failureUrl: `${host}/idp/${provider}/failure`,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { createSession, getSession, server, setSession } from "#/lib/zitadel";
|
||||
import {
|
||||
createSession,
|
||||
createSessionForUserIdAndIdpIntent,
|
||||
getSession,
|
||||
server,
|
||||
setSession,
|
||||
} from "#/lib/zitadel";
|
||||
import {
|
||||
SessionCookie,
|
||||
addSessionToCookie,
|
||||
@@ -49,6 +55,50 @@ export async function createSessionAndUpdateCookie(
|
||||
}
|
||||
}
|
||||
|
||||
export async function createSessionForIdpAndUpdateCookie(
|
||||
userId: string,
|
||||
idpIntent: {
|
||||
idpIntentId?: string | undefined;
|
||||
idpIntentToken?: string | undefined;
|
||||
},
|
||||
authRequestId: string | undefined
|
||||
): Promise<Session> {
|
||||
const createdSession = await createSessionForUserIdAndIdpIntent(
|
||||
server,
|
||||
userId,
|
||||
idpIntent
|
||||
);
|
||||
|
||||
if (createdSession) {
|
||||
return getSession(
|
||||
server,
|
||||
createdSession.sessionId,
|
||||
createdSession.sessionToken
|
||||
).then((response) => {
|
||||
if (response?.session && response.session?.factors?.user?.loginName) {
|
||||
const sessionCookie: SessionCookie = {
|
||||
id: createdSession.sessionId,
|
||||
token: createdSession.sessionToken,
|
||||
changeDate: response.session.changeDate?.toString() ?? "",
|
||||
loginName: response.session?.factors?.user?.loginName ?? "",
|
||||
};
|
||||
|
||||
if (authRequestId) {
|
||||
sessionCookie.authRequestId = authRequestId;
|
||||
}
|
||||
|
||||
return addSessionToCookie(sessionCookie).then(() => {
|
||||
return response.session as Session;
|
||||
});
|
||||
} else {
|
||||
throw "could not get session or session does not have loginName";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw "Could not create session";
|
||||
}
|
||||
}
|
||||
|
||||
export type SessionWithChallenges = Session & {
|
||||
challenges: Challenges | undefined;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user