mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-11 21:32:12 +00:00
refactor: zitadel server
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
This commit is contained in:
37
README.md
37
README.md
@@ -1,14 +1,17 @@
|
||||
# ZITADEL TypeScript with Turborepo and Changesets
|
||||
|
||||
This repository contains all TypeScript and JavaScript packages and applications you need to create your own ZITADEL Login UI.
|
||||
The repo makes use of the [build system Turbo](https://turbo.build/repo) and the [Changesets CLI for versioning the packages](https://github.com/changesets/changesets).
|
||||
This repository contains all TypeScript and JavaScript packages and applications you need to create your own ZITADEL
|
||||
Login UI.
|
||||
The repo makes use of the [build system Turbo](https://turbo.build/repo) and
|
||||
the [Changesets CLI for versioning the packages](https://github.com/changesets/changesets).
|
||||
|
||||
**⚠️ This repo and packages are in alpha state and subject to change ⚠️**
|
||||
|
||||
The scope of functionality of this repo and packages is limited and under active development.
|
||||
Once the package structure is set and all APIs are fully implemented we'll move this repo to beta state.
|
||||
You can read the [contribution guide](/CONTRIBUTING.md) on how to contribute.
|
||||
Questions can be raised in our [Discord channel](https://discord.gg/erh5Brh7jE) or as a [GitHub issue](https://github.com/zitadel/typescript/issues).
|
||||
Questions can be raised in our [Discord channel](https://discord.gg/erh5Brh7jE) or as
|
||||
a [GitHub issue](https://github.com/zitadel/typescript/issues).
|
||||
|
||||
## Developing Your Own ZITADEL Login UI
|
||||
|
||||
@@ -25,8 +28,8 @@ We think the easiest path of getting up and running, is the following:
|
||||
## Included Apps And Packages
|
||||
|
||||
- `login`: The login UI used by ZITADEL Cloud, powered by Next.js
|
||||
- `@zitadel/server`: core components for establishing node client connection, grpc stub
|
||||
- `@zitadel/client`: core components for establishing web client connection, grpc stub
|
||||
- `@zitadel/node`: core components for establishing node client connection, grpc stub
|
||||
- `@zitadel/client`: shared client utilities
|
||||
- `@zitadel/proto`: shared protobuf types
|
||||
- `@zitadel/react`: shared React utilities and components built with tailwindcss
|
||||
- `@zitadel/next`: shared Next.js utilities
|
||||
@@ -38,9 +41,11 @@ Each package and app is 100% [TypeScript](https://www.typescriptlang.org/).
|
||||
### Login
|
||||
|
||||
The login is currently in a work in progress state.
|
||||
The goal is to implement a login UI, using the session API of ZITADEL, which also implements the OIDC Standard and is ready to use for everyone.
|
||||
The goal is to implement a login UI, using the session API of ZITADEL, which also implements the OIDC Standard and is
|
||||
ready to use for everyone.
|
||||
|
||||
In the first phase we want to have a MVP login ready with the OIDC Standard and a basic feature set. In a second step the features will be extended.
|
||||
In the first phase we want to have a MVP login ready with the OIDC Standard and a basic feature set. In a second step
|
||||
the features will be extended.
|
||||
|
||||
This list should show the current implementation state, and also what is missing.
|
||||
You can already use the current state, and extend it with your needs.
|
||||
@@ -105,11 +110,14 @@ You can already use the current state, and extend it with your needs.
|
||||
## Versioning And Publishing Packages
|
||||
|
||||
Package publishing has been configured using [Changesets](https://github.com/changesets/changesets).
|
||||
Here is their [documentation](https://github.com/changesets/changesets#documentation) for more information about the workflow.
|
||||
Here is their [documentation](https://github.com/changesets/changesets#documentation) for more information about the
|
||||
workflow.
|
||||
|
||||
The [GitHub Action](https://github.com/changesets/action) needs an `NPM_TOKEN` and `GITHUB_TOKEN` in the repository settings. The [Changesets bot](https://github.com/apps/changeset-bot) should also be installed on the GitHub repository.
|
||||
The [GitHub Action](https://github.com/changesets/action) needs an `NPM_TOKEN` and `GITHUB_TOKEN` in the repository
|
||||
settings. The [Changesets bot](https://github.com/apps/changeset-bot) should also be installed on the GitHub repository.
|
||||
|
||||
Read the [changesets documentation](https://github.com/changesets/changesets/blob/main/docs/automating-changesets.md) for more information about this automation
|
||||
Read the [changesets documentation](https://github.com/changesets/changesets/blob/main/docs/automating-changesets.md)
|
||||
for more information about this automation
|
||||
|
||||
### NPM
|
||||
|
||||
@@ -136,8 +144,10 @@ pnpm install
|
||||
```
|
||||
|
||||
then setup the environment for the login application which needs a `.env.local` in `/apps/login`.
|
||||
Go to your instance and create a service user for the application having the IAM_OWNER manager role.
|
||||
This user is required to have access to create users on your primary organization and reading policy data so it can be restricted to your personal use case but we'll stick with IAM_OWNER for convenience. Create a PAT and copy the value to paste it under the `ZITADEL_SERVICE_USER_TOKEN` key.
|
||||
Go to your instance and create a service user for the application having the `IAM_OWNER` manager role.
|
||||
This user is required to have access to create users on your primary organization and reading policy data so it can be
|
||||
restricted to your personal use case but we'll stick with `IAM_OWNER` for convenience. Create a PAT and copy the value to
|
||||
paste it under the `ZITADEL_SERVICE_USER_TOKEN` key.
|
||||
The file should look as follows:
|
||||
|
||||
```
|
||||
@@ -164,7 +174,8 @@ Open the login application with your favorite browser at `localhost:3000`.
|
||||
|
||||
To deploy your own version on Vercel, navigate to your instance and create a service user.
|
||||
Copy its id from the overview and set it as ZITADEL_SERVICE_USER_ID.
|
||||
Then create a personal access token (PAT), copy and set it as ZITADEL_SERVICE_USER_TOKEN, then navigate to your instance settings and make sure it gets IAM_OWNER permissions.
|
||||
Then create a personal access token (PAT), copy and set it as ZITADEL_SERVICE_USER_TOKEN, then navigate to your instance
|
||||
settings and make sure it gets IAM_OWNER permissions.
|
||||
Finally set your instance url as ZITADEL_API_URL. Make sure to set it without trailing slash.
|
||||
|
||||
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fzitadel%2Ftypescript&env=ZITADEL_API_URL,ZITADEL_SERVICE_USER_ID,ZITADEL_SERVICE_USER_TOKEN&root-directory=apps/login&envDescription=Setup%20a%20service%20account%20with%20IAM_OWNER%20membership%20on%20your%20instance%20and%20provide%20its%20id%20and%20personal%20access%20token.&project-name=zitadel-login&repository-name=zitadel-login)
|
||||
|
||||
@@ -32,13 +32,14 @@
|
||||
"*": "prettier --write --ignore-unknown"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.14",
|
||||
"@heroicons/react": "2.0.13",
|
||||
"@tailwindcss/forms": "0.5.3",
|
||||
"@vercel/analytics": "^1.0.0",
|
||||
"@zitadel/client": "workspace:*",
|
||||
"@headlessui/react": "^1.7.18",
|
||||
"@heroicons/react": "2.1.3",
|
||||
"@tailwindcss/forms": "0.5.7",
|
||||
"@vercel/analytics": "^1.2.2",
|
||||
"@zitadel/proto": "workspace:*",
|
||||
"@zitadel/client2": "workspace:*",
|
||||
"@zitadel/react": "workspace:*",
|
||||
"@zitadel/server": "workspace:*",
|
||||
"@zitadel/node": "workspace:*",
|
||||
"clsx": "1.2.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"moment": "^2.29.4",
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { Session } from "@zitadel/server";
|
||||
import { getBrandingSettings, listSessions, server } from "@/lib/zitadel";
|
||||
import { getBrandingSettings, listSessions } from "@/lib/zitadel";
|
||||
import { getAllSessionCookieIds } from "@/utils/cookies";
|
||||
import { UserPlusIcon } from "@heroicons/react/24/outline";
|
||||
import Link from "next/link";
|
||||
import SessionsList from "@/ui/SessionsList";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
|
||||
async function loadSessions(): Promise<Session[]> {
|
||||
async function loadSessions() {
|
||||
const ids = await getAllSessionCookieIds();
|
||||
|
||||
if (ids && ids.length) {
|
||||
const response = await listSessions(
|
||||
server,
|
||||
ids.filter((id: string | undefined) => !!id),
|
||||
);
|
||||
return response?.sessions ?? [];
|
||||
@@ -31,7 +29,7 @@ export default async function Page({
|
||||
|
||||
let sessions = await loadSessions();
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import { ProviderSlug } from "@/lib/demos";
|
||||
import { getBrandingSettings, server } from "@/lib/zitadel";
|
||||
import Alert, { AlertType } from "@/ui/Alert";
|
||||
import { getBrandingSettings } from "@/lib/zitadel";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import IdpSignin from "@/ui/IdpSignin";
|
||||
import {
|
||||
AddHumanUserRequest,
|
||||
IDPInformation,
|
||||
RetrieveIdentityProviderIntentResponse,
|
||||
user,
|
||||
IDPLink,
|
||||
} from "@zitadel/server";
|
||||
import { ClientError } from "nice-grpc";
|
||||
|
||||
const PROVIDER_NAME_MAPPING: {
|
||||
[provider: string]: string;
|
||||
@@ -29,7 +19,7 @@ export default async function Page({
|
||||
const { id, token, authRequestId, organization } = searchParams;
|
||||
const { provider } = params;
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
if (provider) {
|
||||
return (
|
||||
|
||||
@@ -1,59 +1,73 @@
|
||||
import { ProviderSlug } from "@/lib/demos";
|
||||
import { getBrandingSettings, server } from "@/lib/zitadel";
|
||||
import { getBrandingSettings, userService } from "@/lib/zitadel";
|
||||
import Alert, { AlertType } from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import IdpSignin from "@/ui/IdpSignin";
|
||||
import { AddHumanUserRequest } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
import {
|
||||
AddHumanUserRequest,
|
||||
IDPInformation,
|
||||
RetrieveIdentityProviderIntentResponse,
|
||||
user,
|
||||
IDPLink,
|
||||
} from "@zitadel/server";
|
||||
import { ClientError } from "nice-grpc";
|
||||
} from "@zitadel/proto/zitadel/user/v2beta/idp_pb";
|
||||
import { PartialMessage } from "@zitadel/client2";
|
||||
|
||||
const PROVIDER_MAPPING: {
|
||||
[provider: string]: (rI: IDPInformation) => Partial<AddHumanUserRequest>;
|
||||
[provider: string]: (
|
||||
rI: IDPInformation,
|
||||
) => PartialMessage<AddHumanUserRequest>;
|
||||
} = {
|
||||
[ProviderSlug.GOOGLE]: (idp: IDPInformation) => {
|
||||
const idpLink: IDPLink = {
|
||||
const rawInfo = idp.rawInformation?.toJson() as {
|
||||
User: {
|
||||
email: string;
|
||||
name?: string;
|
||||
given_name?: string;
|
||||
family_name?: string;
|
||||
};
|
||||
};
|
||||
|
||||
const idpLink: PartialMessage<IDPLink> = {
|
||||
idpId: idp.idpId,
|
||||
userId: idp.userId,
|
||||
userName: idp.userName,
|
||||
};
|
||||
const req: Partial<AddHumanUserRequest> = {
|
||||
|
||||
const req: PartialMessage<AddHumanUserRequest> = {
|
||||
username: idp.userName,
|
||||
email: {
|
||||
email: idp.rawInformation?.User?.email,
|
||||
isVerified: true,
|
||||
email: rawInfo.User?.email,
|
||||
verification: { case: "isVerified", value: true },
|
||||
},
|
||||
// organisation: Organisation | undefined;
|
||||
profile: {
|
||||
displayName: idp.rawInformation?.User?.name ?? "",
|
||||
givenName: idp.rawInformation?.User?.given_name ?? "",
|
||||
familyName: idp.rawInformation?.User?.family_name ?? "",
|
||||
displayName: rawInfo.User?.name ?? "",
|
||||
givenName: rawInfo.User?.given_name ?? "",
|
||||
familyName: rawInfo.User?.family_name ?? "",
|
||||
},
|
||||
idpLinks: [idpLink],
|
||||
};
|
||||
return req;
|
||||
},
|
||||
[ProviderSlug.GITHUB]: (idp: IDPInformation) => {
|
||||
const idpLink: IDPLink = {
|
||||
const rawInfo = idp.rawInformation?.toJson() as {
|
||||
email: string;
|
||||
name: string;
|
||||
};
|
||||
const idpLink: PartialMessage<IDPLink> = {
|
||||
idpId: idp.idpId,
|
||||
userId: idp.userId,
|
||||
userName: idp.userName,
|
||||
};
|
||||
const req: Partial<AddHumanUserRequest> = {
|
||||
const req: PartialMessage<AddHumanUserRequest> = {
|
||||
username: idp.userName,
|
||||
email: {
|
||||
email: idp.rawInformation?.email,
|
||||
isVerified: true,
|
||||
email: rawInfo?.email,
|
||||
verification: { case: "isVerified", value: true },
|
||||
},
|
||||
// organisation: Organisation | undefined;
|
||||
profile: {
|
||||
displayName: idp.rawInformation?.name ?? "",
|
||||
givenName: idp.rawInformation?.name ?? "",
|
||||
familyName: idp.rawInformation?.name ?? "",
|
||||
displayName: rawInfo?.name ?? "",
|
||||
givenName: rawInfo?.name ?? "",
|
||||
familyName: rawInfo?.name ?? "",
|
||||
},
|
||||
idpLinks: [idpLink],
|
||||
};
|
||||
@@ -61,11 +75,7 @@ const PROVIDER_MAPPING: {
|
||||
},
|
||||
};
|
||||
|
||||
function retrieveIDPIntent(
|
||||
id: string,
|
||||
token: string,
|
||||
): Promise<RetrieveIdentityProviderIntentResponse> {
|
||||
const userService = user.getUser(server);
|
||||
function retrieveIDPIntent(id: string, token: string) {
|
||||
return userService.retrieveIdentityProviderIntent(
|
||||
{ idpIntentId: id, idpIntentToken: token },
|
||||
{},
|
||||
@@ -77,7 +87,6 @@ function createUser(
|
||||
info: IDPInformation,
|
||||
): Promise<string> {
|
||||
const userData = PROVIDER_MAPPING[provider](info);
|
||||
const userService = user.getUser(server);
|
||||
return userService.addHumanUser(userData, {}).then((resp) => resp.userId);
|
||||
}
|
||||
|
||||
@@ -91,7 +100,7 @@ export default async function Page({
|
||||
const { id, token, authRequestId, organization } = searchParams;
|
||||
const { provider } = params;
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
if (provider && id && token) {
|
||||
return retrieveIDPIntent(id, token)
|
||||
@@ -128,7 +137,7 @@ export default async function Page({
|
||||
</DynamicTheme>
|
||||
);
|
||||
})
|
||||
.catch((error: ClientError) => {
|
||||
.catch((error) => {
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
@@ -136,7 +145,7 @@ export default async function Page({
|
||||
<div className="w-full">
|
||||
{
|
||||
<Alert type={AlertType.ALERT}>
|
||||
{JSON.stringify(error.details)}
|
||||
{JSON.stringify(error.message)}
|
||||
</Alert>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
import {
|
||||
getBrandingSettings,
|
||||
getLegalAndSupportSettings,
|
||||
server,
|
||||
settingsService,
|
||||
} from "@/lib/zitadel";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import { SignInWithIDP } from "@/ui/SignInWithIDP";
|
||||
import {
|
||||
GetActiveIdentityProvidersResponse,
|
||||
IdentityProvider,
|
||||
ZitadelServer,
|
||||
settings,
|
||||
} from "@zitadel/server";
|
||||
import { makeReqCtx } from "@zitadel/client2/v2beta";
|
||||
|
||||
function getIdentityProviders(
|
||||
server: ZitadelServer,
|
||||
orgId?: string,
|
||||
): Promise<IdentityProvider[] | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
function getIdentityProviders(orgId?: string) {
|
||||
return settingsService
|
||||
.getActiveIdentityProviders(
|
||||
orgId ? { ctx: { orgId } } : { ctx: { instance: true } },
|
||||
{},
|
||||
)
|
||||
.then((resp: GetActiveIdentityProvidersResponse) => {
|
||||
.getActiveIdentityProviders({ ctx: makeReqCtx(orgId) }, {})
|
||||
.then((resp) => {
|
||||
return resp.identityProviders;
|
||||
});
|
||||
}
|
||||
@@ -35,15 +23,15 @@ export default async function Page({
|
||||
const authRequestId = searchParams?.authRequestId;
|
||||
const organization = searchParams?.organization;
|
||||
|
||||
const legal = await getLegalAndSupportSettings(server, organization);
|
||||
const legal = await getLegalAndSupportSettings(organization);
|
||||
|
||||
const identityProviders = await getIdentityProviders(server, organization);
|
||||
const identityProviders = await getIdentityProviders(organization);
|
||||
|
||||
const host = process.env.VERCEL_URL
|
||||
? `https://${process.env.VERCEL_URL}`
|
||||
: "http://localhost:3000";
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -2,29 +2,17 @@ import {
|
||||
getBrandingSettings,
|
||||
getLegalAndSupportSettings,
|
||||
getLoginSettings,
|
||||
server,
|
||||
settingsService,
|
||||
} from "@/lib/zitadel";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import { SignInWithIDP } from "@/ui/SignInWithIDP";
|
||||
import UsernameForm from "@/ui/UsernameForm";
|
||||
import {
|
||||
GetActiveIdentityProvidersResponse,
|
||||
IdentityProvider,
|
||||
ZitadelServer,
|
||||
settings,
|
||||
} from "@zitadel/server";
|
||||
import { makeReqCtx } from "@zitadel/client2/v2beta";
|
||||
|
||||
function getIdentityProviders(
|
||||
server: ZitadelServer,
|
||||
orgId?: string,
|
||||
): Promise<IdentityProvider[] | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
function getIdentityProviders(orgId?: string) {
|
||||
return settingsService
|
||||
.getActiveIdentityProviders(
|
||||
orgId ? { ctx: { orgId } } : { ctx: { instance: true } },
|
||||
{},
|
||||
)
|
||||
.then((resp: GetActiveIdentityProvidersResponse) => {
|
||||
.getActiveIdentityProviders({ ctx: makeReqCtx(orgId) }, {})
|
||||
.then((resp) => {
|
||||
return resp.identityProviders;
|
||||
});
|
||||
}
|
||||
@@ -39,16 +27,16 @@ export default async function Page({
|
||||
const organization = searchParams?.organization;
|
||||
const submit: boolean = searchParams?.submit === "true";
|
||||
|
||||
const loginSettings = await getLoginSettings(server, organization);
|
||||
const legal = await getLegalAndSupportSettings(server);
|
||||
const loginSettings = await getLoginSettings(organization);
|
||||
const legal = await getLegalAndSupportSettings();
|
||||
|
||||
const identityProviders = await getIdentityProviders(server, organization);
|
||||
const identityProviders = await getIdentityProviders(organization);
|
||||
|
||||
const host = process.env.VERCEL_URL
|
||||
? `https://${process.env.VERCEL_URL}`
|
||||
: "http://localhost:3000";
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
35
apps/login/src/app/(login)/mfa/create/page.tsx
Normal file
35
apps/login/src/app/(login)/mfa/create/page.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
"use client";
|
||||
import { Button, ButtonVariants } from "@/ui/Button";
|
||||
import { TextInput } from "@/ui/Input";
|
||||
import UserAvatar from "@/ui/UserAvatar";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function Page() {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<h1>Password</h1>
|
||||
<p className="ztdl-p mb-6 block">Enter your password.</p>
|
||||
|
||||
<UserAvatar
|
||||
showDropdown
|
||||
displayName="Max Peintner"
|
||||
loginName="max@zitadel.com"
|
||||
></UserAvatar>
|
||||
|
||||
<div className="w-full">
|
||||
<TextInput type="password" label="Password" />
|
||||
</div>
|
||||
<div className="flex w-full flex-row items-center justify-between">
|
||||
<Button
|
||||
onClick={() => router.back()}
|
||||
variant={ButtonVariants.Secondary}
|
||||
>
|
||||
back
|
||||
</Button>
|
||||
<Button variant={ButtonVariants.Primary}>continue</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
getBrandingSettings,
|
||||
getSession,
|
||||
listAuthenticationMethodTypes,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import ChooseSecondFactor from "@/ui/ChooseSecondFactor";
|
||||
@@ -33,7 +32,7 @@ export default async function Page({
|
||||
loginName,
|
||||
organization,
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session && response.session.factors?.user?.id) {
|
||||
return listAuthenticationMethodTypes(
|
||||
response.session.factors.user.id,
|
||||
@@ -49,7 +48,7 @@ export default async function Page({
|
||||
|
||||
async function loadSessionById(sessionId: string, organization?: string) {
|
||||
const recent = await getSessionCookieById(sessionId, organization);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session && response.session.factors?.user?.id) {
|
||||
return listAuthenticationMethodTypes(
|
||||
response.session.factors.user.id,
|
||||
@@ -63,7 +62,7 @@ export default async function Page({
|
||||
});
|
||||
}
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
getSession,
|
||||
getUserByID,
|
||||
listAuthenticationMethodTypes,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import ChooseSecondFactorToSetup from "@/ui/ChooseSecondFactorToSetup";
|
||||
@@ -14,7 +13,6 @@ import {
|
||||
getMostRecentCookieWithLoginname,
|
||||
getSessionCookieById,
|
||||
} from "@/utils/cookies";
|
||||
import { user } from "@zitadel/server";
|
||||
|
||||
export default async function Page({
|
||||
searchParams,
|
||||
@@ -36,16 +34,21 @@ export default async function Page({
|
||||
loginName,
|
||||
organization,
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session && response.session.factors?.user?.id) {
|
||||
const userId = response.session.factors.user.id;
|
||||
return listAuthenticationMethodTypes(userId).then((methods) => {
|
||||
return getUserByID(userId).then((user) => {
|
||||
const humanUser =
|
||||
user.user?.type.case === "human"
|
||||
? user.user?.type.value
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
factors: response.session?.factors,
|
||||
authMethods: methods.authMethodTypes ?? [],
|
||||
phoneVerified: user.user?.human?.phone?.isVerified ?? false,
|
||||
emailVerified: user.user?.human?.email?.isVerified ?? false,
|
||||
phoneVerified: humanUser?.phone?.isVerified ?? false,
|
||||
emailVerified: humanUser?.email?.isVerified ?? false,
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -55,16 +58,20 @@ export default async function Page({
|
||||
|
||||
async function loadSessionById(sessionId: string, organization?: string) {
|
||||
const recent = await getSessionCookieById(sessionId, organization);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session && response.session.factors?.user?.id) {
|
||||
const userId = response.session.factors.user.id;
|
||||
return listAuthenticationMethodTypes(userId).then((methods) => {
|
||||
return getUserByID(userId).then((user) => {
|
||||
const humanUser =
|
||||
user.user?.type.case === "human"
|
||||
? user.user?.type.value
|
||||
: undefined;
|
||||
return {
|
||||
factors: response.session?.factors,
|
||||
authMethods: methods.authMethodTypes ?? [],
|
||||
phoneVerified: user.user?.human?.phone?.isVerified ?? false,
|
||||
emailVerified: user.user?.human?.email?.isVerified ?? false,
|
||||
phoneVerified: humanUser?.phone?.isVerified ?? false,
|
||||
emailVerified: humanUser?.email?.isVerified ?? false,
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -72,8 +79,8 @@ export default async function Page({
|
||||
});
|
||||
}
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const loginSettings = await getLoginSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
const loginSettings = await getLoginSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
getBrandingSettings,
|
||||
getLoginSettings,
|
||||
getSession,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
@@ -24,7 +23,7 @@ export default async function Page({
|
||||
|
||||
const { session, token } = await loadSession(loginName, organization);
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
async function loadSession(loginName?: string, organization?: string) {
|
||||
const recent = await getMostRecentCookieWithLoginname(
|
||||
@@ -32,7 +31,7 @@ export default async function Page({
|
||||
organization,
|
||||
);
|
||||
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
return { session: response?.session, token: recent.token };
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
getBrandingSettings,
|
||||
getSession,
|
||||
registerTOTP,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import { Button, ButtonVariants } from "@/ui/Button";
|
||||
@@ -13,9 +12,8 @@ import { Spinner } from "@/ui/Spinner";
|
||||
import TOTPRegister from "@/ui/TOTPRegister";
|
||||
import UserAvatar from "@/ui/UserAvatar";
|
||||
import { getMostRecentCookieWithLoginname } from "@/utils/cookies";
|
||||
import { RegisterTOTPResponse } from "@zitadel/server";
|
||||
import Link from "next/link";
|
||||
import { ClientError } from "nice-grpc";
|
||||
import { RegisterTOTPResponse } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
|
||||
export default async function Page({
|
||||
searchParams,
|
||||
@@ -28,11 +26,11 @@ export default async function Page({
|
||||
searchParams;
|
||||
const { method } = params;
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
const { session, token } = await loadSession(loginName, organization);
|
||||
|
||||
let totpResponse: RegisterTOTPResponse | undefined,
|
||||
totpError: ClientError | undefined;
|
||||
totpError: Error | undefined;
|
||||
if (session && session.factors?.user?.id) {
|
||||
if (method === "time-based") {
|
||||
await registerTOTP(session.factors.user.id)
|
||||
@@ -63,7 +61,7 @@ export default async function Page({
|
||||
organization,
|
||||
);
|
||||
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
return { session: response?.session, token: recent.token };
|
||||
});
|
||||
}
|
||||
@@ -111,7 +109,7 @@ export default async function Page({
|
||||
|
||||
{totpError && (
|
||||
<div className="py-4">
|
||||
<Alert>{totpError?.details}</Alert>
|
||||
<Alert>{totpError?.message}</Alert>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getBrandingSettings, getSession, server } from "@/lib/zitadel";
|
||||
import { getBrandingSettings, getSession } from "@/lib/zitadel";
|
||||
import Alert, { AlertType } from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import RegisterPasskey from "@/ui/RegisterPasskey";
|
||||
@@ -20,7 +20,7 @@ export default async function Page({
|
||||
loginName,
|
||||
organization,
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ export default async function Page({
|
||||
? "When set up, you will be able to authenticate without a password."
|
||||
: "Your device will ask for your fingerprint, face, or screen lock";
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getBrandingSettings, getSession, server } from "@/lib/zitadel";
|
||||
import { getBrandingSettings, getSession } from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import LoginPasskey from "@/ui/LoginPasskey";
|
||||
@@ -32,7 +32,7 @@ export default async function Page({
|
||||
loginName,
|
||||
organization,
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
@@ -41,14 +41,14 @@ export default async function Page({
|
||||
|
||||
async function loadSessionById(sessionId: string, organization?: string) {
|
||||
const recent = await getSessionCookieById(sessionId, organization);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
getBrandingSettings,
|
||||
getLoginSettings,
|
||||
getSession,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
@@ -25,15 +24,15 @@ export default async function Page({
|
||||
organization,
|
||||
);
|
||||
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const loginSettings = await getLoginSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
const loginSettings = await getLoginSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
getBrandingSettings,
|
||||
getLegalAndSupportSettings,
|
||||
getPasswordComplexitySettings,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import RegisterFormWithoutPassword from "@/ui/RegisterFormWithoutPassword";
|
||||
@@ -18,13 +17,11 @@ export default async function Page({
|
||||
|
||||
const setPassword = !!(firstname && lastname && email);
|
||||
|
||||
const legal = await getLegalAndSupportSettings(server, organization);
|
||||
const passwordComplexitySettings = await getPasswordComplexitySettings(
|
||||
server,
|
||||
organization,
|
||||
);
|
||||
const legal = await getLegalAndSupportSettings(organization);
|
||||
const passwordComplexitySettings =
|
||||
await getPasswordComplexitySettings(organization);
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return setPassword ? (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
createCallback,
|
||||
getBrandingSettings,
|
||||
getSession,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import { createCallback, getBrandingSettings, getSession } from "@/lib/zitadel";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import UserAvatar from "@/ui/UserAvatar";
|
||||
import { getMostRecentCookieWithLoginname } from "@/utils/cookies";
|
||||
@@ -13,14 +8,17 @@ async function loadSession(loginName: string, authRequestId?: string) {
|
||||
const recent = await getMostRecentCookieWithLoginname(`${loginName}`);
|
||||
|
||||
if (authRequestId) {
|
||||
return createCallback(server, {
|
||||
return createCallback({
|
||||
authRequestId,
|
||||
session: { sessionId: recent.id, sessionToken: recent.token },
|
||||
callbackKind: {
|
||||
case: "session",
|
||||
value: { sessionId: recent.id, sessionToken: recent.token },
|
||||
},
|
||||
}).then(({ callbackUrl }) => {
|
||||
return redirect(callbackUrl);
|
||||
});
|
||||
}
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
@@ -31,7 +29,7 @@ export default async function Page({ searchParams }: { searchParams: any }) {
|
||||
const { loginName, authRequestId, organization } = searchParams;
|
||||
const sessionFactors = await loadSession(loginName, authRequestId);
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
getBrandingSettings,
|
||||
getLoginSettings,
|
||||
getSession,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import Alert from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
@@ -22,7 +21,7 @@ export default async function Page({
|
||||
}) {
|
||||
const { loginName, authRequestId, sessionId, organization } = searchParams;
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
const sessionFactors = sessionId
|
||||
? await loadSessionById(sessionId, organization)
|
||||
@@ -36,7 +35,7 @@ export default async function Page({
|
||||
loginName,
|
||||
organization,
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
@@ -45,7 +44,7 @@ export default async function Page({
|
||||
|
||||
async function loadSessionById(sessionId: string, organization?: string) {
|
||||
const recent = await getSessionCookieById(sessionId, organization);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getBrandingSettings, getSession, server } from "@/lib/zitadel";
|
||||
import { getBrandingSettings, getSession } from "@/lib/zitadel";
|
||||
import Alert, { AlertType } from "@/ui/Alert";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import RegisterPasskey from "@/ui/RegisterPasskey";
|
||||
@@ -20,7 +20,7 @@ export default async function Page({
|
||||
loginName,
|
||||
organization,
|
||||
);
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
if (response?.session) {
|
||||
return response.session;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export default async function Page({
|
||||
const description =
|
||||
"Your device will ask for your fingerprint, face, or screen lock";
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getBrandingSettings, server } from "@/lib/zitadel";
|
||||
import { getBrandingSettings } from "@/lib/zitadel";
|
||||
import DynamicTheme from "@/ui/DynamicTheme";
|
||||
import VerifyEmailForm from "@/ui/VerifyEmailForm";
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
@@ -15,7 +15,7 @@ export default async function Page({ searchParams }: { searchParams: any }) {
|
||||
passwordset,
|
||||
} = searchParams;
|
||||
|
||||
const branding = await getBrandingSettings(server, organization);
|
||||
const branding = await getBrandingSettings(organization);
|
||||
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { server, startIdentityProviderFlow } from "@/lib/zitadel";
|
||||
import { startIdentityProviderFlow } from "@/lib/zitadel";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
@@ -6,7 +6,7 @@ export async function POST(request: NextRequest) {
|
||||
if (body) {
|
||||
let { idpId, successUrl, failureUrl } = body;
|
||||
|
||||
return startIdentityProviderFlow(server, {
|
||||
return startIdentityProviderFlow({
|
||||
idpId,
|
||||
urls: {
|
||||
successUrl,
|
||||
|
||||
@@ -7,11 +7,7 @@ export async function POST(request: NextRequest) {
|
||||
if (body) {
|
||||
const { loginName, authRequestId, organization } = body;
|
||||
return listUsers(loginName, organization).then((users) => {
|
||||
if (
|
||||
users.details &&
|
||||
users.details.totalResult == 1 &&
|
||||
users.result[0].userId
|
||||
) {
|
||||
if (users.details?.totalResult == BigInt(1) && users.result[0].userId) {
|
||||
const userId = users.result[0].userId;
|
||||
return createSessionForUserIdAndUpdateCookie(
|
||||
userId,
|
||||
|
||||
@@ -5,8 +5,9 @@ import {
|
||||
getSessionCookieByLoginName,
|
||||
} from "@/utils/cookies";
|
||||
import { setSessionAndUpdateCookie } from "@/utils/session";
|
||||
import { Checks } from "@zitadel/server";
|
||||
import { NextRequest, NextResponse, userAgent } from "next/server";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb";
|
||||
import { PlainMessage } from "@zitadel/client2";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const body = await request.json();
|
||||
@@ -31,7 +32,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
return recentPromise
|
||||
.then((recent) => {
|
||||
const checks: Checks = {};
|
||||
const checks: PlainMessage<Checks> = {};
|
||||
|
||||
if (method === "time-based") {
|
||||
checks.totp = {
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
createPasskeyRegistrationLink,
|
||||
getSession,
|
||||
registerPasskey,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import { getSessionCookieById } from "@/utils/cookies";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
@@ -14,11 +13,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const sessionCookie = await getSessionCookieById(sessionId);
|
||||
|
||||
const session = await getSession(
|
||||
server,
|
||||
sessionCookie.id,
|
||||
sessionCookie.token,
|
||||
);
|
||||
const session = await getSession(sessionCookie.id, sessionCookie.token);
|
||||
|
||||
const domain: string = request.nextUrl.hostname;
|
||||
|
||||
@@ -29,6 +24,9 @@ export async function POST(request: NextRequest) {
|
||||
return createPasskeyRegistrationLink(userId)
|
||||
.then((resp) => {
|
||||
const code = resp.code;
|
||||
if (!code) {
|
||||
throw new Error("Missing code in response");
|
||||
}
|
||||
return registerPasskey(userId, code, domain).then((resp) => {
|
||||
return NextResponse.json(resp);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getSession, server, verifyPasskeyRegistration } from "@/lib/zitadel";
|
||||
import { getSession, verifyPasskeyRegistration } from "@/lib/zitadel";
|
||||
import { getSessionCookieById } from "@/utils/cookies";
|
||||
import { NextRequest, NextResponse, userAgent } from "next/server";
|
||||
|
||||
@@ -15,17 +15,12 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
const sessionCookie = await getSessionCookieById(sessionId);
|
||||
|
||||
const session = await getSession(
|
||||
server,
|
||||
sessionCookie.id,
|
||||
sessionCookie.token,
|
||||
);
|
||||
const session = await getSession(sessionCookie.id, sessionCookie.token);
|
||||
|
||||
const userId = session?.session?.factors?.user?.id;
|
||||
|
||||
if (userId) {
|
||||
return verifyPasskeyRegistration(
|
||||
server,
|
||||
passkeyId,
|
||||
passkeyName,
|
||||
publicKeyCredential,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { addHumanUser, server } from "@/lib/zitadel";
|
||||
import { addHumanUser } from "@/lib/zitadel";
|
||||
import {
|
||||
createSessionAndUpdateCookie,
|
||||
createSessionForUserIdAndUpdateCookie,
|
||||
@@ -17,7 +17,7 @@ export async function POST(request: NextRequest) {
|
||||
authRequestId,
|
||||
} = body;
|
||||
|
||||
return addHumanUser(server, {
|
||||
return addHumanUser({
|
||||
email: email,
|
||||
firstName,
|
||||
lastName,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { setEmail, server } from "@/lib/zitadel";
|
||||
import { setEmail } from "@/lib/zitadel";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
@@ -7,7 +7,7 @@ export async function POST(request: NextRequest) {
|
||||
const { userId, code } = body;
|
||||
|
||||
// replace with resend Mail method once its implemented
|
||||
return setEmail(server, userId)
|
||||
return setEmail(userId)
|
||||
.then((resp) => {
|
||||
return NextResponse.json(resp);
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
server,
|
||||
deleteSession,
|
||||
getSession,
|
||||
getUserByID,
|
||||
@@ -17,7 +16,6 @@ import {
|
||||
createSessionForIdpAndUpdateCookie,
|
||||
setSessionAndUpdateCookie,
|
||||
} from "@/utils/session";
|
||||
import { Challenges, Checks, RequestChallenges } from "@zitadel/server";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
@@ -104,27 +102,23 @@ export async function PUT(request: NextRequest) {
|
||||
challenges &&
|
||||
(challenges.otpEmail === "" || challenges.otpSms === "")
|
||||
) {
|
||||
const sessionResponse = await getSession(
|
||||
server,
|
||||
recent.id,
|
||||
recent.token,
|
||||
);
|
||||
const sessionResponse = await getSession(recent.id, recent.token);
|
||||
|
||||
if (sessionResponse && sessionResponse.session?.factors?.user?.id) {
|
||||
const userResponse = await getUserByID(
|
||||
sessionResponse.session.factors.user.id,
|
||||
);
|
||||
if (
|
||||
challenges.otpEmail === "" &&
|
||||
userResponse.user?.human?.email?.email
|
||||
) {
|
||||
challenges.otpEmail = userResponse.user?.human?.email?.email;
|
||||
const humanUser =
|
||||
userResponse.user?.type.case === "human"
|
||||
? userResponse.user?.type.value
|
||||
: undefined;
|
||||
|
||||
if (challenges.otpEmail === "" && humanUser?.email?.email) {
|
||||
challenges.otpEmail = humanUser?.email?.email;
|
||||
}
|
||||
|
||||
if (
|
||||
challenges.otpSms === "" &&
|
||||
userResponse.user?.human?.phone?.phone
|
||||
) {
|
||||
challenges.otpSms = userResponse.user?.human?.phone?.phone;
|
||||
if (challenges.otpSms === "" && humanUser?.phone?.phone) {
|
||||
challenges.otpSms = humanUser?.phone?.phone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,7 +170,7 @@ export async function DELETE(request: NextRequest) {
|
||||
if (id) {
|
||||
const session = await getSessionCookieById(id);
|
||||
|
||||
return deleteSession(server, session.id, session.token)
|
||||
return deleteSession(session.id, session.token)
|
||||
.then(() => {
|
||||
return removeSessionFromCookie(session)
|
||||
.then(() => {
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
getSession,
|
||||
registerPasskey,
|
||||
registerU2F,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import { getSessionCookieById } from "@/utils/cookies";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
@@ -15,11 +14,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const sessionCookie = await getSessionCookieById(sessionId);
|
||||
|
||||
const session = await getSession(
|
||||
server,
|
||||
sessionCookie.id,
|
||||
sessionCookie.token,
|
||||
);
|
||||
const session = await getSession(sessionCookie.id, sessionCookie.token);
|
||||
|
||||
const domain: string = request.nextUrl.hostname;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getSession, server, verifyU2FRegistration } from "@/lib/zitadel";
|
||||
import { getSession, verifyU2FRegistration } from "@/lib/zitadel";
|
||||
import { getSessionCookieById } from "@/utils/cookies";
|
||||
import { VerifyU2FRegistrationRequest } from "@zitadel/server";
|
||||
import { NextRequest, NextResponse, userAgent } from "next/server";
|
||||
import { VerifyU2FRegistrationRequest } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
import { PlainMessage } from "@zitadel/client2";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const body = await request.json();
|
||||
@@ -16,16 +17,12 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
const sessionCookie = await getSessionCookieById(sessionId);
|
||||
|
||||
const session = await getSession(
|
||||
server,
|
||||
sessionCookie.id,
|
||||
sessionCookie.token,
|
||||
);
|
||||
const session = await getSession(sessionCookie.id, sessionCookie.token);
|
||||
|
||||
const userId = session?.session?.factors?.user?.id;
|
||||
|
||||
if (userId) {
|
||||
const req: VerifyU2FRegistrationRequest = {
|
||||
const req: PlainMessage<VerifyU2FRegistrationRequest> = {
|
||||
publicKeyCredential,
|
||||
u2fId,
|
||||
userId,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { server, verifyEmail } from "@/lib/zitadel";
|
||||
import { verifyEmail } from "@/lib/zitadel";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
@@ -6,7 +6,7 @@ export async function POST(request: NextRequest) {
|
||||
if (body) {
|
||||
const { userId, code } = body;
|
||||
|
||||
return verifyEmail(server, userId, code)
|
||||
return verifyEmail(userId, code)
|
||||
.then((resp) => {
|
||||
return NextResponse.json(resp);
|
||||
})
|
||||
|
||||
@@ -6,8 +6,6 @@ import { LayoutProviders } from "@/ui/LayoutProviders";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import ThemeWrapper from "@/ui/ThemeWrapper";
|
||||
import { getBrandingSettings } from "@/lib/zitadel";
|
||||
import { server } from "../lib/zitadel";
|
||||
import { BrandingSettings } from "@zitadel/server";
|
||||
import ThemeProvider from "@/ui/ThemeProvider";
|
||||
import Theme from "@/ui/Theme";
|
||||
|
||||
|
||||
@@ -3,15 +3,17 @@ import {
|
||||
getAuthRequest,
|
||||
getOrgByDomain,
|
||||
listSessions,
|
||||
server,
|
||||
} from "@/lib/zitadel";
|
||||
import { SessionCookie, getAllSessions } from "@/utils/cookies";
|
||||
import { Session, AuthRequest, Prompt } from "@zitadel/server";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { Session } from "@zitadel/proto/zitadel/session/v2beta/session_pb";
|
||||
import {
|
||||
AuthRequest,
|
||||
Prompt,
|
||||
} from "@zitadel/proto/zitadel/oidc/v2beta/authorization_pb";
|
||||
|
||||
async function loadSessions(ids: string[]): Promise<Session[]> {
|
||||
const response = await listSessions(
|
||||
server,
|
||||
ids.filter((id: string | undefined) => !!id),
|
||||
);
|
||||
|
||||
@@ -81,9 +83,12 @@ export async function GET(request: NextRequest) {
|
||||
sessionToken: cookie?.token,
|
||||
};
|
||||
|
||||
const { callbackUrl } = await createCallback(server, {
|
||||
const { callbackUrl } = await createCallback({
|
||||
authRequestId,
|
||||
session,
|
||||
callbackKind: {
|
||||
case: "session",
|
||||
value: session,
|
||||
},
|
||||
});
|
||||
return NextResponse.redirect(callbackUrl);
|
||||
}
|
||||
@@ -92,7 +97,7 @@ export async function GET(request: NextRequest) {
|
||||
|
||||
if (authRequestId) {
|
||||
console.log(`Login with authRequest: ${authRequestId}`);
|
||||
const { authRequest } = await getAuthRequest(server, { authRequestId });
|
||||
const { authRequest } = await getAuthRequest({ authRequestId });
|
||||
|
||||
let organization = "";
|
||||
|
||||
@@ -132,7 +137,7 @@ export async function GET(request: NextRequest) {
|
||||
return NextResponse.redirect(accountsUrl);
|
||||
};
|
||||
|
||||
if (authRequest && authRequest.prompt.includes(Prompt.PROMPT_CREATE)) {
|
||||
if (authRequest && authRequest.prompt.includes(Prompt.CREATE)) {
|
||||
const registerUrl = new URL("/register", request.url);
|
||||
if (authRequest?.id) {
|
||||
registerUrl.searchParams.set("authRequestId", authRequest?.id);
|
||||
@@ -147,9 +152,9 @@ export async function GET(request: NextRequest) {
|
||||
// use existing session and hydrate it for oidc
|
||||
if (authRequest && sessions.length) {
|
||||
// if some accounts are available for selection and select_account is set
|
||||
if (authRequest.prompt.includes(Prompt.PROMPT_SELECT_ACCOUNT)) {
|
||||
if (authRequest.prompt.includes(Prompt.SELECT_ACCOUNT)) {
|
||||
return gotoAccounts();
|
||||
} else if (authRequest.prompt.includes(Prompt.PROMPT_LOGIN)) {
|
||||
} else if (authRequest.prompt.includes(Prompt.LOGIN)) {
|
||||
// if prompt is login
|
||||
const loginNameUrl = new URL("/loginname", request.url);
|
||||
if (authRequest?.id) {
|
||||
@@ -162,7 +167,7 @@ export async function GET(request: NextRequest) {
|
||||
loginNameUrl.searchParams.set("organization", organization);
|
||||
}
|
||||
return NextResponse.redirect(loginNameUrl);
|
||||
} else if (authRequest.prompt.includes(Prompt.PROMPT_NONE)) {
|
||||
} else if (authRequest.prompt.includes(Prompt.NONE)) {
|
||||
// NONE prompt - silent authentication
|
||||
|
||||
let selectedSession = findSession(sessions, authRequest);
|
||||
@@ -177,9 +182,12 @@ export async function GET(request: NextRequest) {
|
||||
sessionId: cookie?.id,
|
||||
sessionToken: cookie?.token,
|
||||
};
|
||||
const { callbackUrl } = await createCallback(server, {
|
||||
const { callbackUrl } = await createCallback({
|
||||
authRequestId,
|
||||
session,
|
||||
callbackKind: {
|
||||
case: "session",
|
||||
value: session,
|
||||
},
|
||||
});
|
||||
return NextResponse.redirect(callbackUrl);
|
||||
} else {
|
||||
@@ -209,9 +217,12 @@ export async function GET(request: NextRequest) {
|
||||
sessionToken: cookie?.token,
|
||||
};
|
||||
try {
|
||||
const { callbackUrl } = await createCallback(server, {
|
||||
const { callbackUrl } = await createCallback({
|
||||
authRequestId,
|
||||
session,
|
||||
callbackKind: {
|
||||
case: "session",
|
||||
value: session,
|
||||
},
|
||||
});
|
||||
if (callbackUrl) {
|
||||
return NextResponse.redirect(callbackUrl);
|
||||
|
||||
@@ -35,7 +35,7 @@ export const demos: { name: string; items: Item[] }[] = [
|
||||
},
|
||||
{
|
||||
name: "IDP Register",
|
||||
slug: "register/idp",
|
||||
slug: "idp",
|
||||
description: "Add a user from an external identity provider",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use server";
|
||||
|
||||
import { getMostRecentCookieWithLoginname } from "@/utils/cookies";
|
||||
import { getSession, server, verifyTOTPRegistration } from "./zitadel";
|
||||
import { getSession, verifyTOTPRegistration } from "./zitadel";
|
||||
|
||||
export async function verifyTOTP(
|
||||
code: string,
|
||||
@@ -10,7 +10,7 @@ export async function verifyTOTP(
|
||||
) {
|
||||
return getMostRecentCookieWithLoginname(loginName, organization)
|
||||
.then((recent) => {
|
||||
return getSession(server, recent.id, recent.token).then((response) => {
|
||||
return getSession(recent.id, recent.token).then((response) => {
|
||||
return { session: response?.session, token: recent.token };
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,109 +1,51 @@
|
||||
import { VerifyU2FRegistrationRequest } from "@zitadel/server";
|
||||
import {
|
||||
GetUserByIDResponse,
|
||||
RegisterTOTPResponse,
|
||||
VerifyTOTPRegistrationResponse,
|
||||
} from "@zitadel/server";
|
||||
createOIDCServiceClient,
|
||||
createSessionServiceClient,
|
||||
createSettingsServiceClient,
|
||||
createUserServiceClient,
|
||||
makeReqCtx,
|
||||
} from "@zitadel/client2/v2beta";
|
||||
import { createManagementServiceClient } from "@zitadel/client2/v1";
|
||||
import { createServerTransport } from "@zitadel/node";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb";
|
||||
import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2beta/challenge_pb";
|
||||
import {
|
||||
LegalAndSupportSettings,
|
||||
PasswordComplexitySettings,
|
||||
ZitadelServer,
|
||||
VerifyMyAuthFactorOTPResponse,
|
||||
ZitadelServerOptions,
|
||||
user,
|
||||
oidc,
|
||||
settings,
|
||||
getServers,
|
||||
auth,
|
||||
initializeServer,
|
||||
session,
|
||||
GetGeneralSettingsResponse,
|
||||
CreateSessionResponse,
|
||||
GetBrandingSettingsResponse,
|
||||
GetPasswordComplexitySettingsResponse,
|
||||
RegisterU2FResponse,
|
||||
GetLegalAndSupportSettingsResponse,
|
||||
AddHumanUserResponse,
|
||||
BrandingSettings,
|
||||
ListSessionsResponse,
|
||||
GetSessionResponse,
|
||||
VerifyEmailResponse,
|
||||
Checks,
|
||||
SetSessionResponse,
|
||||
SetSessionRequest,
|
||||
ListUsersResponse,
|
||||
management,
|
||||
DeleteSessionResponse,
|
||||
VerifyPasskeyRegistrationResponse,
|
||||
LoginSettings,
|
||||
GetOrgByDomainGlobalResponse,
|
||||
GetLoginSettingsResponse,
|
||||
ListAuthenticationMethodTypesResponse,
|
||||
StartIdentityProviderIntentRequest,
|
||||
StartIdentityProviderIntentResponse,
|
||||
RetrieveIdentityProviderIntentRequest,
|
||||
RetrieveIdentityProviderIntentResponse,
|
||||
GetAuthRequestResponse,
|
||||
GetAuthRequestRequest,
|
||||
VerifyU2FRegistrationRequest,
|
||||
} from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
import {
|
||||
CreateCallbackRequest,
|
||||
CreateCallbackResponse,
|
||||
RequestChallenges,
|
||||
TextQueryMethod,
|
||||
ListHumanAuthFactorsResponse,
|
||||
AddHumanUserRequest,
|
||||
AddOTPEmailResponse,
|
||||
AddOTPSMSResponse,
|
||||
} from "@zitadel/server";
|
||||
} from "@zitadel/proto/zitadel/oidc/v2beta/oidc_service_pb";
|
||||
import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2beta/object_pb";
|
||||
import type { RedirectURLs } from "@zitadel/proto/zitadel/user/v2beta/idp_pb";
|
||||
import { PlainMessage } from "@zitadel/client2";
|
||||
|
||||
const SESSION_LIFETIME_S = 3000;
|
||||
|
||||
export const zitadelConfig: ZitadelServerOptions = {
|
||||
name: "zitadel login",
|
||||
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
token: process.env.ZITADEL_SERVICE_USER_TOKEN ?? "",
|
||||
};
|
||||
const transport = createServerTransport(
|
||||
process.env.ZITADEL_SERVICE_USER_TOKEN!,
|
||||
{baseUrl: process.env.ZITADEL_API_URL!},
|
||||
);
|
||||
|
||||
let server: ZitadelServer;
|
||||
export const sessionService = createSessionServiceClient(transport);
|
||||
export const managementService = createManagementServiceClient(transport);
|
||||
export const userService = createUserServiceClient(transport);
|
||||
export const oidcService = createOIDCServiceClient(transport);
|
||||
export const settingsService = createSettingsServiceClient(transport);
|
||||
|
||||
if (!getServers().length) {
|
||||
console.log("initialize server");
|
||||
server = initializeServer(zitadelConfig);
|
||||
}
|
||||
|
||||
export async function getBrandingSettings(
|
||||
server: ZitadelServer,
|
||||
organization?: string,
|
||||
): Promise<BrandingSettings | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
export async function getBrandingSettings(organization?: string) {
|
||||
return settingsService
|
||||
.getBrandingSettings(
|
||||
{ ctx: organization ? { orgId: organization } : { instance: true } },
|
||||
{},
|
||||
)
|
||||
.then((resp: GetBrandingSettingsResponse) => resp.settings);
|
||||
.getBrandingSettings({ ctx: makeReqCtx(organization) }, {})
|
||||
.then((resp) => resp.settings);
|
||||
}
|
||||
|
||||
export async function getLoginSettings(
|
||||
server: ZitadelServer,
|
||||
orgId?: string,
|
||||
): Promise<LoginSettings | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
export async function getLoginSettings(orgId?: string) {
|
||||
return settingsService
|
||||
.getLoginSettings({ ctx: orgId ? { orgId } : { instance: true } }, {})
|
||||
.then((resp: GetLoginSettingsResponse) => resp.settings);
|
||||
.getLoginSettings({ ctx: makeReqCtx(orgId) }, {})
|
||||
.then((resp) => resp.settings);
|
||||
}
|
||||
|
||||
export async function verifyMyAuthFactorOTP(
|
||||
code: string,
|
||||
): Promise<VerifyMyAuthFactorOTPResponse> {
|
||||
const authService = auth.getAuth(server);
|
||||
return authService.verifyMyAuthFactorOTP({ code }, {});
|
||||
}
|
||||
|
||||
export async function addOTPEmail(
|
||||
userId: string,
|
||||
): Promise<AddOTPEmailResponse | undefined> {
|
||||
const userService = user.getUser(server);
|
||||
export async function addOTPEmail(userId: string) {
|
||||
return userService.addOTPEmail(
|
||||
{
|
||||
userId,
|
||||
@@ -112,98 +54,72 @@ export async function addOTPEmail(
|
||||
);
|
||||
}
|
||||
|
||||
export async function addOTPSMS(
|
||||
userId: string,
|
||||
token?: string,
|
||||
): Promise<AddOTPSMSResponse | undefined> {
|
||||
let userService;
|
||||
if (token) {
|
||||
const authConfig: ZitadelServerOptions = {
|
||||
name: "zitadel login",
|
||||
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
token: token,
|
||||
};
|
||||
export async function addOTPSMS(userId: string, token?: string) {
|
||||
// TODO: Follow up here, I do not understand the branching
|
||||
// let userService;
|
||||
// if (token) {
|
||||
// const authConfig: ZitadelServerOptions = {
|
||||
// name: "zitadel login",
|
||||
// apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
// token: token,
|
||||
// };
|
||||
// const sessionUser = initializeServer(authConfig);
|
||||
// userService = user.getUser(sessionUser);
|
||||
// } else {
|
||||
// userService = user.getUser(server);
|
||||
// }
|
||||
|
||||
const sessionUser = initializeServer(authConfig);
|
||||
userService = user.getUser(sessionUser);
|
||||
} else {
|
||||
userService = user.getUser(server);
|
||||
}
|
||||
return userService.addOTPSMS({ userId }, {});
|
||||
}
|
||||
|
||||
export async function registerTOTP(
|
||||
userId: string,
|
||||
token?: string,
|
||||
): Promise<RegisterTOTPResponse | undefined> {
|
||||
let userService;
|
||||
if (token) {
|
||||
const authConfig: ZitadelServerOptions = {
|
||||
name: "zitadel login",
|
||||
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
token: token,
|
||||
};
|
||||
|
||||
const sessionUser = initializeServer(authConfig);
|
||||
userService = user.getUser(sessionUser);
|
||||
} else {
|
||||
userService = user.getUser(server);
|
||||
}
|
||||
export async function registerTOTP(userId: string, token?: string) {
|
||||
// TODO: Follow up here, I do not understand the branching
|
||||
// let userService;
|
||||
// if (token) {
|
||||
// const authConfig: ZitadelServerOptions = {
|
||||
// name: "zitadel login",
|
||||
// apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
// token: token,
|
||||
// };
|
||||
//
|
||||
// const sessionUser = initializeServer(authConfig);
|
||||
// userService = user.getUser(sessionUser);
|
||||
// } else {
|
||||
// userService = user.getUser(server);
|
||||
// }
|
||||
return userService.registerTOTP({ userId }, {});
|
||||
}
|
||||
|
||||
export async function getGeneralSettings(
|
||||
server: ZitadelServer,
|
||||
): Promise<string[] | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
export async function getGeneralSettings() {
|
||||
return settingsService
|
||||
.getGeneralSettings({}, {})
|
||||
.then((resp: GetGeneralSettingsResponse) => resp.supportedLanguages);
|
||||
.then((resp) => resp.supportedLanguages);
|
||||
}
|
||||
|
||||
export async function getLegalAndSupportSettings(
|
||||
server: ZitadelServer,
|
||||
organization?: string,
|
||||
): Promise<LegalAndSupportSettings | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
export async function getLegalAndSupportSettings(organization?: string) {
|
||||
return settingsService
|
||||
.getLegalAndSupportSettings(
|
||||
{ ctx: organization ? { orgId: organization } : { instance: true } },
|
||||
{},
|
||||
)
|
||||
.then((resp: GetLegalAndSupportSettingsResponse) => {
|
||||
.getLegalAndSupportSettings({ ctx: makeReqCtx(organization) }, {})
|
||||
.then((resp) => {
|
||||
return resp.settings;
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPasswordComplexitySettings(
|
||||
server: ZitadelServer,
|
||||
organization?: string,
|
||||
): Promise<PasswordComplexitySettings | undefined> {
|
||||
const settingsService = settings.getSettings(server);
|
||||
|
||||
export async function getPasswordComplexitySettings(organization?: string) {
|
||||
return settingsService
|
||||
.getPasswordComplexitySettings(
|
||||
organization
|
||||
? { ctx: { orgId: organization } }
|
||||
: { ctx: { instance: true } },
|
||||
{},
|
||||
)
|
||||
.then((resp: GetPasswordComplexitySettingsResponse) => resp.settings);
|
||||
.getPasswordComplexitySettings({ ctx: makeReqCtx(organization) })
|
||||
.then((resp) => resp.settings);
|
||||
}
|
||||
|
||||
export async function createSessionFromChecks(
|
||||
server: ZitadelServer,
|
||||
checks: Checks,
|
||||
challenges: RequestChallenges | undefined,
|
||||
): Promise<CreateSessionResponse | undefined> {
|
||||
const sessionService = session.getSession(server);
|
||||
checks: PlainMessage<Checks>,
|
||||
challenges: PlainMessage<RequestChallenges> | undefined,
|
||||
) {
|
||||
return sessionService.createSession(
|
||||
{
|
||||
checks: checks,
|
||||
challenges,
|
||||
lifetime: {
|
||||
seconds: SESSION_LIFETIME_S,
|
||||
seconds: BigInt(SESSION_LIFETIME_S),
|
||||
nanos: 0,
|
||||
},
|
||||
},
|
||||
@@ -212,77 +128,69 @@ export async function createSessionFromChecks(
|
||||
}
|
||||
|
||||
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: {
|
||||
search: {
|
||||
case: "userId",
|
||||
value: userId,
|
||||
},
|
||||
},
|
||||
idpIntent,
|
||||
},
|
||||
// lifetime: {
|
||||
// seconds: 300,
|
||||
// nanos: 0,
|
||||
// },
|
||||
});
|
||||
}
|
||||
|
||||
return sessionService.createSession(
|
||||
export async function setSession(
|
||||
sessionId: string,
|
||||
sessionToken: string,
|
||||
challenges: RequestChallenges | undefined,
|
||||
checks?: PlainMessage<Checks>,
|
||||
) {
|
||||
return sessionService.setSession(
|
||||
{
|
||||
checks: { user: { userId }, idpIntent },
|
||||
// lifetime: {
|
||||
// seconds: 300,
|
||||
// nanos: 0,
|
||||
// },
|
||||
sessionId,
|
||||
sessionToken,
|
||||
challenges,
|
||||
checks: checks ? checks : {},
|
||||
metadata: {},
|
||||
},
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
export async function setSession(
|
||||
server: ZitadelServer,
|
||||
sessionId: string,
|
||||
sessionToken: string,
|
||||
challenges: RequestChallenges | undefined,
|
||||
checks: Checks,
|
||||
): Promise<SetSessionResponse | undefined> {
|
||||
const sessionService = session.getSession(server);
|
||||
|
||||
const payload: SetSessionRequest = {
|
||||
sessionId,
|
||||
sessionToken,
|
||||
challenges,
|
||||
checks: {},
|
||||
metadata: {},
|
||||
};
|
||||
|
||||
if (checks && payload.checks) {
|
||||
payload.checks = checks;
|
||||
}
|
||||
|
||||
return sessionService.setSession(payload, {});
|
||||
}
|
||||
|
||||
export async function getSession(
|
||||
server: ZitadelServer,
|
||||
sessionId: string,
|
||||
sessionToken: string,
|
||||
): Promise<GetSessionResponse | undefined> {
|
||||
const sessionService = session.getSession(server);
|
||||
export async function getSession(sessionId: string, sessionToken: string) {
|
||||
return sessionService.getSession({ sessionId, sessionToken }, {});
|
||||
}
|
||||
|
||||
export async function deleteSession(
|
||||
server: ZitadelServer,
|
||||
sessionId: string,
|
||||
sessionToken: string,
|
||||
): Promise<DeleteSessionResponse | undefined> {
|
||||
const sessionService = session.getSession(server);
|
||||
export async function deleteSession(sessionId: string, sessionToken: string) {
|
||||
return sessionService.deleteSession({ sessionId, sessionToken }, {});
|
||||
}
|
||||
|
||||
export async function listSessions(
|
||||
server: ZitadelServer,
|
||||
ids: string[],
|
||||
): Promise<ListSessionsResponse | undefined> {
|
||||
const sessionService = session.getSession(server);
|
||||
const query = { offset: 0, limit: 100, asc: true };
|
||||
const queries = [{ idsQuery: { ids } }];
|
||||
return sessionService.listSessions({ queries: queries }, {});
|
||||
export async function listSessions(ids: string[]) {
|
||||
return sessionService.listSessions(
|
||||
{
|
||||
queries: [
|
||||
{
|
||||
query: {
|
||||
case: "idsQuery",
|
||||
value: { ids: ids },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
export type AddHumanUserData = {
|
||||
@@ -293,89 +201,82 @@ export type AddHumanUserData = {
|
||||
organization: string | undefined;
|
||||
};
|
||||
|
||||
export async function addHumanUser(
|
||||
server: ZitadelServer,
|
||||
{ email, firstName, lastName, password, organization }: AddHumanUserData,
|
||||
): Promise<AddHumanUserResponse> {
|
||||
const userService = user.getUser(server);
|
||||
|
||||
const payload: Partial<AddHumanUserRequest> = {
|
||||
export async function addHumanUser({
|
||||
email,
|
||||
firstName,
|
||||
lastName,
|
||||
password,
|
||||
organization,
|
||||
}: AddHumanUserData) {
|
||||
return userService.addHumanUser({
|
||||
email: { email },
|
||||
username: email,
|
||||
profile: { givenName: firstName, familyName: lastName },
|
||||
};
|
||||
|
||||
if (organization) {
|
||||
payload.organization = { orgId: organization };
|
||||
}
|
||||
|
||||
return userService.addHumanUser(
|
||||
password
|
||||
? {
|
||||
...payload,
|
||||
password: { password },
|
||||
}
|
||||
: payload,
|
||||
{},
|
||||
);
|
||||
organization: organization
|
||||
? { org: { case: "orgId", value: organization } }
|
||||
: undefined,
|
||||
passwordType: password
|
||||
? { case: "password", value: { password: password } }
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
export async function verifyTOTPRegistration(
|
||||
code: string,
|
||||
userId: string,
|
||||
token?: string,
|
||||
): Promise<VerifyTOTPRegistrationResponse> {
|
||||
let userService;
|
||||
if (token) {
|
||||
const authConfig: ZitadelServerOptions = {
|
||||
name: "zitadel login",
|
||||
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
token: token,
|
||||
};
|
||||
|
||||
const sessionUser = initializeServer(authConfig);
|
||||
userService = user.getUser(sessionUser);
|
||||
} else {
|
||||
userService = user.getUser(server);
|
||||
}
|
||||
) {
|
||||
// let userService;
|
||||
// if (token) {
|
||||
// const authConfig: ZitadelServerOptions = {
|
||||
// name: "zitadel login",
|
||||
// apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
// token: token,
|
||||
// };
|
||||
//
|
||||
// const sessionUser = initializeServer(authConfig);
|
||||
// userService = user.getUser(sessionUser);
|
||||
// } else {
|
||||
// userService = user.getUser(server);
|
||||
// }
|
||||
return userService.verifyTOTPRegistration({ code, userId }, {});
|
||||
}
|
||||
|
||||
export async function getUserByID(
|
||||
userId: string,
|
||||
): Promise<GetUserByIDResponse> {
|
||||
const userService = user.getUser(server);
|
||||
|
||||
export async function getUserByID(userId: string) {
|
||||
return userService.getUserByID({ userId }, {});
|
||||
}
|
||||
|
||||
export async function listUsers(
|
||||
userName: string,
|
||||
organizationId: string,
|
||||
): Promise<ListUsersResponse> {
|
||||
const userService = user.getUser(server);
|
||||
|
||||
export async function listUsers(userName: string, organizationId: string) {
|
||||
return userService.listUsers(
|
||||
{
|
||||
queries: organizationId
|
||||
? [
|
||||
{
|
||||
userNameQuery: {
|
||||
userName,
|
||||
method: TextQueryMethod.TEXT_QUERY_METHOD_EQUALS,
|
||||
query: {
|
||||
case: "userNameQuery",
|
||||
value: {
|
||||
userName,
|
||||
method: TextQueryMethod.EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
organizationIdQuery: {
|
||||
organizationId,
|
||||
query: {
|
||||
case: "organizationIdQuery",
|
||||
value: {
|
||||
organizationId,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
userNameQuery: {
|
||||
userName,
|
||||
method: TextQueryMethod.TEXT_QUERY_METHOD_EQUALS,
|
||||
query: {
|
||||
case: "userNameQuery",
|
||||
value: {
|
||||
userName,
|
||||
method: TextQueryMethod.EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -384,64 +285,52 @@ export async function listUsers(
|
||||
);
|
||||
}
|
||||
|
||||
export async function getOrgByDomain(
|
||||
domain: string,
|
||||
): Promise<GetOrgByDomainGlobalResponse> {
|
||||
const mgmtService = management.getManagement(server);
|
||||
return mgmtService.getOrgByDomainGlobal({ domain }, {});
|
||||
export async function getOrgByDomain(domain: string) {
|
||||
return managementService.getOrgByDomainGlobal({ domain }, {});
|
||||
}
|
||||
|
||||
export async function startIdentityProviderFlow(
|
||||
server: ZitadelServer,
|
||||
{ idpId, urls }: StartIdentityProviderIntentRequest,
|
||||
): Promise<StartIdentityProviderIntentResponse> {
|
||||
const userService = user.getUser(server);
|
||||
|
||||
export async function startIdentityProviderFlow({
|
||||
idpId,
|
||||
urls,
|
||||
}: {
|
||||
idpId: string;
|
||||
urls: PlainMessage<RedirectURLs>;
|
||||
}) {
|
||||
return userService.startIdentityProviderIntent({
|
||||
idpId,
|
||||
urls,
|
||||
content: {
|
||||
case: "urls",
|
||||
value: urls,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function retrieveIdentityProviderInformation(
|
||||
server: ZitadelServer,
|
||||
{ idpIntentId, idpIntentToken }: RetrieveIdentityProviderIntentRequest,
|
||||
): Promise<RetrieveIdentityProviderIntentResponse> {
|
||||
const userService = user.getUser(server);
|
||||
|
||||
export async function retrieveIdentityProviderInformation({
|
||||
idpIntentId,
|
||||
idpIntentToken,
|
||||
}: RetrieveIdentityProviderIntentRequest) {
|
||||
return userService.retrieveIdentityProviderIntent({
|
||||
idpIntentId,
|
||||
idpIntentToken,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getAuthRequest(
|
||||
server: ZitadelServer,
|
||||
{ authRequestId }: GetAuthRequestRequest,
|
||||
): Promise<GetAuthRequestResponse> {
|
||||
const oidcService = oidc.getOidc(server);
|
||||
|
||||
export async function getAuthRequest({
|
||||
authRequestId,
|
||||
}: {
|
||||
authRequestId: string;
|
||||
}) {
|
||||
return oidcService.getAuthRequest({
|
||||
authRequestId,
|
||||
});
|
||||
}
|
||||
|
||||
export async function createCallback(
|
||||
server: ZitadelServer,
|
||||
req: CreateCallbackRequest,
|
||||
): Promise<CreateCallbackResponse> {
|
||||
const oidcService = oidc.getOidc(server);
|
||||
|
||||
export async function createCallback(req: PlainMessage<CreateCallbackRequest>) {
|
||||
return oidcService.createCallback(req);
|
||||
}
|
||||
|
||||
export async function verifyEmail(
|
||||
server: ZitadelServer,
|
||||
userId: string,
|
||||
verificationCode: string,
|
||||
): Promise<VerifyEmailResponse> {
|
||||
const userservice = user.getUser(server);
|
||||
return userservice.verifyEmail(
|
||||
export async function verifyEmail(userId: string, verificationCode: string) {
|
||||
return userService.verifyEmail(
|
||||
{
|
||||
userId,
|
||||
verificationCode,
|
||||
@@ -452,16 +341,11 @@ export async function verifyEmail(
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @returns the newly set email
|
||||
*/
|
||||
export async function setEmail(
|
||||
server: ZitadelServer,
|
||||
userId: string,
|
||||
): Promise<any> {
|
||||
const userservice = user.getUser(server);
|
||||
return userservice.setEmail(
|
||||
export async function setEmail(userId: string) {
|
||||
return userService.setEmail(
|
||||
{
|
||||
userId,
|
||||
},
|
||||
@@ -471,48 +355,44 @@ export async function setEmail(
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @returns the newly set email
|
||||
*/
|
||||
export async function createPasskeyRegistrationLink(
|
||||
userId: string,
|
||||
token?: string,
|
||||
): Promise<any> {
|
||||
let userService;
|
||||
if (token) {
|
||||
const authConfig: ZitadelServerOptions = {
|
||||
name: "zitadel login",
|
||||
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
token: token,
|
||||
};
|
||||
|
||||
const sessionUser = initializeServer(authConfig);
|
||||
userService = user.getUser(sessionUser);
|
||||
} else {
|
||||
userService = user.getUser(server);
|
||||
}
|
||||
) {
|
||||
// let userService;
|
||||
// if (token) {
|
||||
// const authConfig: ZitadelServerOptions = {
|
||||
// name: "zitadel login",
|
||||
// apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||
// token: token,
|
||||
// };
|
||||
//
|
||||
// const sessionUser = initializeServer(authConfig);
|
||||
// userService = user.getUser(sessionUser);
|
||||
// } else {
|
||||
// userService = user.getUser(server);
|
||||
// }
|
||||
|
||||
return userService.createPasskeyRegistrationLink({
|
||||
userId,
|
||||
returnCode: {},
|
||||
medium: {
|
||||
case: "returnCode",
|
||||
value: {},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @param domain the domain on which the factor is registered
|
||||
* @returns the newly set email
|
||||
*/
|
||||
export async function registerU2F(
|
||||
userId: string,
|
||||
domain: string,
|
||||
): Promise<RegisterU2FResponse> {
|
||||
const userservice = user.getUser(server);
|
||||
|
||||
return userservice.registerU2F({
|
||||
export async function registerU2F(userId: string, domain: string) {
|
||||
return userService.registerU2F({
|
||||
userId,
|
||||
domain,
|
||||
});
|
||||
@@ -520,27 +400,22 @@ export async function registerU2F(
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @param domain the domain on which the factor is registered
|
||||
* @returns the newly set email
|
||||
*/
|
||||
export async function verifyU2FRegistration(
|
||||
request: VerifyU2FRegistrationRequest,
|
||||
): Promise<any> {
|
||||
const userservice = user.getUser(server);
|
||||
|
||||
return userservice.verifyU2FRegistration(request, {});
|
||||
request: PlainMessage<VerifyU2FRegistrationRequest>,
|
||||
) {
|
||||
return userService.verifyU2FRegistration(request, {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @returns the newly set email
|
||||
*/
|
||||
export async function verifyPasskeyRegistration(
|
||||
server: ZitadelServer,
|
||||
passkeyId: string,
|
||||
passkeyName: string,
|
||||
publicKeyCredential:
|
||||
@@ -549,9 +424,8 @@ export async function verifyPasskeyRegistration(
|
||||
}
|
||||
| undefined,
|
||||
userId: string,
|
||||
): Promise<VerifyPasskeyRegistrationResponse> {
|
||||
const userservice = user.getUser(server);
|
||||
return userservice.verifyPasskeyRegistration(
|
||||
) {
|
||||
return userService.verifyPasskeyRegistration(
|
||||
{
|
||||
passkeyId,
|
||||
passkeyName,
|
||||
@@ -564,7 +438,6 @@ export async function verifyPasskeyRegistration(
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @returns the newly set email
|
||||
*/
|
||||
@@ -572,9 +445,8 @@ export async function registerPasskey(
|
||||
userId: string,
|
||||
code: { id: string; code: string },
|
||||
domain: string,
|
||||
): Promise<any> {
|
||||
const userservice = user.getUser(server);
|
||||
return userservice.registerPasskey({
|
||||
) {
|
||||
return userService.registerPasskey({
|
||||
userId,
|
||||
code,
|
||||
domain,
|
||||
@@ -584,17 +456,11 @@ export async function registerPasskey(
|
||||
|
||||
/**
|
||||
*
|
||||
* @param server
|
||||
* @param userId the id of the user where the email should be set
|
||||
* @returns the newly set email
|
||||
*/
|
||||
export async function listAuthenticationMethodTypes(
|
||||
userId: string,
|
||||
): Promise<ListAuthenticationMethodTypesResponse> {
|
||||
const userservice = user.getUser(server);
|
||||
return userservice.listAuthenticationMethodTypes({
|
||||
export async function listAuthenticationMethodTypes(userId: string) {
|
||||
return userService.listAuthenticationMethodTypes({
|
||||
userId,
|
||||
});
|
||||
}
|
||||
|
||||
export { server };
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
AuthenticationMethodType,
|
||||
LoginSettings,
|
||||
login,
|
||||
} from "@zitadel/server";
|
||||
import Link from "next/link";
|
||||
import { BadgeState, StateBadge } from "./StateBadge";
|
||||
import clsx from "clsx";
|
||||
import { CheckIcon } from "@heroicons/react/24/outline";
|
||||
import { EMAIL, SMS, TOTP, U2F } from "./AuthMethods";
|
||||
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
|
||||
type Props = {
|
||||
loginName?: string;
|
||||
@@ -46,10 +42,14 @@ export default function ChooseSecondFactor({
|
||||
{userMethods.map((method, i) => {
|
||||
return (
|
||||
<div key={"method-" + i}>
|
||||
{method === 4 && TOTP(false, "/otp/time-based?" + params)}
|
||||
{method === 5 && U2F(false, "/u2f?" + params)}
|
||||
{method === 7 && EMAIL(false, "/otp/email?" + params)}
|
||||
{method === 6 && SMS(false, "/otp/sms?" + params)}
|
||||
{method === AuthenticationMethodType.TOTP &&
|
||||
TOTP(false, "/otp/time-based?" + params)}
|
||||
{method === AuthenticationMethodType.U2F &&
|
||||
U2F(false, "/u2f?" + params)}
|
||||
{method === AuthenticationMethodType.OTP_EMAIL &&
|
||||
EMAIL(false, "/otp/email?" + params)}
|
||||
{method === AuthenticationMethodType.OTP_SMS &&
|
||||
SMS(false, "/otp/sms?" + params)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { AuthenticationMethodType, LoginSettings } from "@zitadel/server";
|
||||
import { EMAIL, SMS, TOTP, U2F } from "./AuthMethods";
|
||||
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb";
|
||||
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
|
||||
type Props = {
|
||||
loginName?: string;
|
||||
@@ -48,13 +49,25 @@ export default function ChooseSecondFactorToSetup({
|
||||
<div className="grid grid-cols-1 gap-5 w-full pt-4">
|
||||
{loginSettings.secondFactors.map((factor, i) => {
|
||||
return factor === 1
|
||||
? TOTP(userMethods.includes(4), "/otp/time-based/set?" + params)
|
||||
? TOTP(
|
||||
userMethods.includes(AuthenticationMethodType.TOTP),
|
||||
"/otp/time-based/set?" + params,
|
||||
)
|
||||
: factor === 2
|
||||
? U2F(userMethods.includes(5), "/u2f/set?" + params)
|
||||
? U2F(
|
||||
userMethods.includes(AuthenticationMethodType.U2F),
|
||||
"/u2f/set?" + params,
|
||||
)
|
||||
: factor === 3 && emailVerified
|
||||
? EMAIL(userMethods.includes(7), "/otp/email/set?" + params)
|
||||
? EMAIL(
|
||||
userMethods.includes(AuthenticationMethodType.OTP_EMAIL),
|
||||
"/otp/email/set?" + params,
|
||||
)
|
||||
: factor === 4 && phoneVerified
|
||||
? SMS(userMethods.includes(6), "/otp/sms/set?" + params)
|
||||
? SMS(
|
||||
userMethods.includes(AuthenticationMethodType.OTP_SMS),
|
||||
"/otp/sms/set?" + params,
|
||||
)
|
||||
: null;
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { BrandingSettings } from "@zitadel/server";
|
||||
import React from "react";
|
||||
import { Logo } from "@/ui/Logo";
|
||||
import ThemeWrapper from "./ThemeWrapper";
|
||||
import { LayoutProviders } from "./LayoutProviders";
|
||||
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2beta/branding_settings_pb";
|
||||
|
||||
export default function DynamicTheme({
|
||||
branding,
|
||||
|
||||
@@ -6,10 +6,11 @@ import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
|
||||
import { Button, ButtonVariants } from "./Button";
|
||||
import Alert, { AlertType } from "./Alert";
|
||||
import { Spinner } from "./Spinner";
|
||||
import { Checks } from "@zitadel/server";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { TextInput } from "./Input";
|
||||
import { Challenges } from "@zitadel/server";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb";
|
||||
import { PlainMessage } from "@zitadel/client2";
|
||||
import { Challenges } from "@zitadel/proto/zitadel/session/v2beta/challenge_pb";
|
||||
|
||||
// either loginName or sessionId must be provided
|
||||
type Props = {
|
||||
@@ -63,7 +64,7 @@ export default function LoginOTP({
|
||||
}, []);
|
||||
|
||||
async function updateSessionForOTPChallenge() {
|
||||
const challenges: Challenges = {};
|
||||
const challenges: PlainMessage<Challenges> = {};
|
||||
|
||||
if (method === "email") {
|
||||
challenges.otpEmail = "";
|
||||
@@ -111,7 +112,7 @@ export default function LoginOTP({
|
||||
body.authRequestId = authRequestId;
|
||||
}
|
||||
|
||||
const checks: Checks = {};
|
||||
const checks: PlainMessage<Checks> = {};
|
||||
if (method === "sms") {
|
||||
checks.otpSms = { code: values.code };
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
|
||||
import { Button, ButtonVariants } from "./Button";
|
||||
import Alert from "./Alert";
|
||||
import { Spinner } from "./Spinner";
|
||||
import { Checks } from "@zitadel/server";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb";
|
||||
|
||||
// either loginName or sessionId must be provided
|
||||
type Props = {
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
symbolValidator,
|
||||
upperCaseValidator,
|
||||
} from "@/utils/validators";
|
||||
import { PasswordComplexitySettings } from "@zitadel/server";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2beta/password_settings_pb";
|
||||
|
||||
type Props = {
|
||||
passwordComplexitySettings: PasswordComplexitySettings;
|
||||
@@ -68,7 +68,7 @@ export default function PasswordComplexity({
|
||||
<div className="flex flex-row items-center">
|
||||
{hasMinLength ? check : cross}
|
||||
<span className={desc}>
|
||||
Password length {passwordComplexitySettings.minLength}
|
||||
Password length {passwordComplexitySettings.minLength.toString()}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -7,12 +7,9 @@ import { useForm } from "react-hook-form";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Spinner } from "./Spinner";
|
||||
import Alert from "./Alert";
|
||||
import {
|
||||
LoginSettings,
|
||||
AuthFactor,
|
||||
Checks,
|
||||
AuthenticationMethodType,
|
||||
} from "@zitadel/server";
|
||||
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb";
|
||||
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
|
||||
type Inputs = {
|
||||
password: string;
|
||||
@@ -83,7 +80,8 @@ export default function PasswordForm({
|
||||
|
||||
// exclude password
|
||||
const availableSecondFactors = resp.authMethods?.filter(
|
||||
(m: AuthenticationMethodType) => m !== 1,
|
||||
(m: AuthenticationMethodType) =>
|
||||
m !== AuthenticationMethodType.PASSWORD,
|
||||
);
|
||||
if (availableSecondFactors.length == 1) {
|
||||
const params = new URLSearchParams({
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React, { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { Checkbox } from "./Checkbox";
|
||||
import { LegalAndSupportSettings } from "@zitadel/server";
|
||||
import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2beta/legal_settings_pb";
|
||||
|
||||
type Props = {
|
||||
legal: LegalAndSupportSettings;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { LegalAndSupportSettings } from "@zitadel/server";
|
||||
import { useState } from "react";
|
||||
import { Button, ButtonVariants } from "./Button";
|
||||
import { TextInput } from "./Input";
|
||||
@@ -12,6 +11,7 @@ import AuthenticationMethodRadio, {
|
||||
methods,
|
||||
} from "./AuthenticationMethodRadio";
|
||||
import Alert from "./Alert";
|
||||
import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2beta/legal_settings_pb";
|
||||
|
||||
type Inputs =
|
||||
| {
|
||||
|
||||
@@ -6,8 +6,8 @@ import { useForm } from "react-hook-form";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Spinner } from "./Spinner";
|
||||
import Alert from "./Alert";
|
||||
import { AuthRequest, RegisterPasskeyResponse } from "@zitadel/server";
|
||||
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
|
||||
import { RegisterPasskeyResponse } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
type Inputs = {};
|
||||
|
||||
type Props = {
|
||||
@@ -89,37 +89,31 @@ export default function RegisterPasskey({
|
||||
function submitRegisterAndContinue(value: Inputs): Promise<boolean | void> {
|
||||
return submitRegister().then((resp: RegisterPasskeyResponse) => {
|
||||
const passkeyId = resp.passkeyId;
|
||||
const options: CredentialCreationOptions =
|
||||
(resp.publicKeyCredentialCreationOptions?.toJson() as CredentialCreationOptions) ??
|
||||
{};
|
||||
|
||||
if (
|
||||
resp.publicKeyCredentialCreationOptions &&
|
||||
resp.publicKeyCredentialCreationOptions.publicKey
|
||||
) {
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.challenge =
|
||||
coerceToArrayBuffer(
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.challenge,
|
||||
"challenge",
|
||||
);
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.user.id =
|
||||
coerceToArrayBuffer(
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.user.id,
|
||||
"userid",
|
||||
);
|
||||
if (
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.excludeCredentials
|
||||
) {
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.excludeCredentials.map(
|
||||
(cred: any) => {
|
||||
cred.id = coerceToArrayBuffer(
|
||||
cred.id as string,
|
||||
"excludeCredentials.id",
|
||||
);
|
||||
return cred;
|
||||
},
|
||||
);
|
||||
if (options?.publicKey) {
|
||||
options.publicKey.challenge = coerceToArrayBuffer(
|
||||
options.publicKey.challenge,
|
||||
"challenge",
|
||||
);
|
||||
options.publicKey.user.id = coerceToArrayBuffer(
|
||||
options.publicKey.user.id,
|
||||
"userid",
|
||||
);
|
||||
if (options.publicKey.excludeCredentials) {
|
||||
options.publicKey.excludeCredentials.map((cred: any) => {
|
||||
cred.id = coerceToArrayBuffer(
|
||||
cred.id as string,
|
||||
"excludeCredentials.id",
|
||||
);
|
||||
return cred;
|
||||
});
|
||||
}
|
||||
|
||||
navigator.credentials
|
||||
.create(resp.publicKeyCredentialCreationOptions)
|
||||
.create(options)
|
||||
.then((resp) => {
|
||||
if (
|
||||
resp &&
|
||||
|
||||
@@ -6,8 +6,8 @@ import { useForm } from "react-hook-form";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Spinner } from "./Spinner";
|
||||
import Alert from "./Alert";
|
||||
import { RegisterU2FResponse } from "@zitadel/server";
|
||||
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
|
||||
import { RegisterU2FResponse } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb";
|
||||
type Inputs = {};
|
||||
|
||||
type Props = {
|
||||
@@ -87,37 +87,31 @@ export default function RegisterU2F({
|
||||
function submitRegisterAndContinue(value: Inputs): Promise<boolean | void> {
|
||||
return submitRegister().then((resp: RegisterU2FResponse) => {
|
||||
const u2fId = resp.u2fId;
|
||||
const options: CredentialCreationOptions =
|
||||
(resp.publicKeyCredentialCreationOptions?.toJson() as CredentialCreationOptions) ??
|
||||
{};
|
||||
|
||||
if (
|
||||
resp.publicKeyCredentialCreationOptions &&
|
||||
resp.publicKeyCredentialCreationOptions.publicKey
|
||||
) {
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.challenge =
|
||||
coerceToArrayBuffer(
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.challenge,
|
||||
"challenge",
|
||||
);
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.user.id =
|
||||
coerceToArrayBuffer(
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.user.id,
|
||||
"userid",
|
||||
);
|
||||
if (
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.excludeCredentials
|
||||
) {
|
||||
resp.publicKeyCredentialCreationOptions.publicKey.excludeCredentials.map(
|
||||
(cred: any) => {
|
||||
cred.id = coerceToArrayBuffer(
|
||||
cred.id as string,
|
||||
"excludeCredentials.id",
|
||||
);
|
||||
return cred;
|
||||
},
|
||||
);
|
||||
if (options.publicKey) {
|
||||
options.publicKey.challenge = coerceToArrayBuffer(
|
||||
options.publicKey.challenge,
|
||||
"challenge",
|
||||
);
|
||||
options.publicKey.user.id = coerceToArrayBuffer(
|
||||
options.publicKey.user.id,
|
||||
"userid",
|
||||
);
|
||||
if (options.publicKey.excludeCredentials) {
|
||||
options.publicKey.excludeCredentials.map((cred: any) => {
|
||||
cred.id = coerceToArrayBuffer(
|
||||
cred.id as string,
|
||||
"excludeCredentials.id",
|
||||
);
|
||||
return cred;
|
||||
});
|
||||
}
|
||||
|
||||
navigator.credentials
|
||||
.create(resp.publicKeyCredentialCreationOptions)
|
||||
.create(options)
|
||||
.then((resp) => {
|
||||
if (
|
||||
resp &&
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
"use client";
|
||||
import { Session } from "@zitadel/server";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { Avatar } from "./Avatar";
|
||||
import moment from "moment";
|
||||
import { XCircleIcon } from "@heroicons/react/24/outline";
|
||||
import { Session } from "@zitadel/proto/zitadel/session/v2beta/session_pb";
|
||||
|
||||
export default function SessionItem({
|
||||
session,
|
||||
@@ -15,6 +16,8 @@ export default function SessionItem({
|
||||
reload: () => void;
|
||||
authRequestId?: string;
|
||||
}) {
|
||||
// TODO: remove casting when bufbuild/protobuf-es@v2 is released
|
||||
session = Session.fromJson(session as any);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
async function clearSession(id: string) {
|
||||
@@ -43,7 +46,7 @@ export default function SessionItem({
|
||||
const validPassword = session?.factors?.password?.verifiedAt;
|
||||
const validPasskey = session?.factors?.webAuthN?.verifiedAt;
|
||||
const stillValid = session.expirationDate
|
||||
? session.expirationDate > new Date()
|
||||
? session.expirationDate.toDate() > new Date()
|
||||
: true;
|
||||
|
||||
const validDate = validPassword || validPasskey;
|
||||
@@ -96,7 +99,7 @@ export default function SessionItem({
|
||||
</span>
|
||||
{validUser && (
|
||||
<span className="text-xs opacity-80">
|
||||
{validDate && moment(new Date(validDate)).fromNow()}
|
||||
{validDate && moment(validDate.toDate()).fromNow()}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { Session } from "@zitadel/server";
|
||||
import SessionItem from "./SessionItem";
|
||||
import Alert from "./Alert";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Session } from "@zitadel/proto/zitadel/session/v2beta/session_pb";
|
||||
|
||||
type Props = {
|
||||
sessions: Session[];
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { PasswordComplexitySettings } from "@zitadel/server";
|
||||
import PasswordComplexity from "./PasswordComplexity";
|
||||
import { useState } from "react";
|
||||
import { Button, ButtonVariants } from "./Button";
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Spinner } from "./Spinner";
|
||||
import Alert from "./Alert";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2beta/password_settings_pb";
|
||||
|
||||
type Inputs =
|
||||
| {
|
||||
|
||||
@@ -10,11 +10,12 @@ import {
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ProviderSlug } from "@/lib/demos";
|
||||
import Alert from "./Alert";
|
||||
import { IdentityProvider } from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb";
|
||||
|
||||
export interface SignInWithIDPProps {
|
||||
children?: ReactNode;
|
||||
host: string;
|
||||
identityProviders: any[];
|
||||
identityProviders: IdentityProvider[];
|
||||
authRequestId?: string;
|
||||
organization?: string;
|
||||
startIDPFlowPath?: (idpId: string) => string;
|
||||
@@ -30,6 +31,11 @@ export function SignInWithIDP({
|
||||
organization,
|
||||
startIDPFlowPath = START_IDP_FLOW_PATH,
|
||||
}: SignInWithIDPProps) {
|
||||
// TODO: remove casting when bufbuild/protobuf-es@v2 is released
|
||||
identityProviders = identityProviders.map((idp) =>
|
||||
IdentityProvider.fromJson(idp as any),
|
||||
);
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const router = useRouter();
|
||||
|
||||
@@ -10,7 +10,6 @@ import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { verifyTOTP } from "@/lib/server-actions";
|
||||
import { login } from "@zitadel/server";
|
||||
|
||||
type Inputs = {
|
||||
code: string;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { BrandingSettings } from "@zitadel/server";
|
||||
import { setTheme } from "@/utils/colors";
|
||||
import { useEffect } from "react";
|
||||
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2beta/branding_settings_pb";
|
||||
import { PartialMessage } from "@zitadel/client2";
|
||||
|
||||
type Props = {
|
||||
branding: Partial<BrandingSettings> | undefined;
|
||||
branding: PartialMessage<BrandingSettings> | undefined;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import { TextInput } from "./Input";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Spinner } from "./Spinner";
|
||||
import { LoginSettings } from "@zitadel/server";
|
||||
import Alert from "./Alert";
|
||||
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb";
|
||||
|
||||
type Inputs = {
|
||||
loginName: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import tinycolor from "tinycolor2";
|
||||
|
||||
import { BrandingSettings } from "@zitadel/server";
|
||||
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2beta/branding_settings_pb";
|
||||
import { PartialMessage } from "@zitadel/client2";
|
||||
|
||||
export interface Color {
|
||||
name: string;
|
||||
@@ -69,7 +69,10 @@ type BrandingColors = {
|
||||
};
|
||||
};
|
||||
|
||||
export function setTheme(document: any, policy?: Partial<BrandingSettings>) {
|
||||
export function setTheme(
|
||||
document: any,
|
||||
policy?: PartialMessage<BrandingSettings>,
|
||||
) {
|
||||
const lP: BrandingColors = {
|
||||
lightTheme: {
|
||||
backgroundColor: policy?.lightTheme?.backgroundColor || BACKGROUND,
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
createSessionFromChecks,
|
||||
createSessionForUserIdAndIdpIntent,
|
||||
getSession,
|
||||
server,
|
||||
setSession,
|
||||
} from "@/lib/zitadel";
|
||||
import {
|
||||
@@ -13,11 +12,12 @@ import {
|
||||
updateSessionCookie,
|
||||
} from "./cookies";
|
||||
import {
|
||||
Session,
|
||||
Challenges,
|
||||
RequestChallenges,
|
||||
Checks,
|
||||
} from "@zitadel/server";
|
||||
} from "@zitadel/proto/zitadel/session/v2beta/challenge_pb";
|
||||
import { Session } from "@zitadel/proto/zitadel/session/v2beta/session_pb";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb";
|
||||
import { PlainMessage } from "@zitadel/client2";
|
||||
|
||||
export async function createSessionAndUpdateCookie(
|
||||
loginName: string,
|
||||
@@ -25,22 +25,20 @@ export async function createSessionAndUpdateCookie(
|
||||
challenges: RequestChallenges | undefined,
|
||||
organization?: string,
|
||||
authRequestId?: string,
|
||||
): Promise<Session> {
|
||||
) {
|
||||
const createdSession = await createSessionFromChecks(
|
||||
server,
|
||||
password
|
||||
? {
|
||||
user: { loginName },
|
||||
user: { search: { case: "loginName", value: loginName } },
|
||||
password: { password },
|
||||
// totp: { code: totpCode },
|
||||
}
|
||||
: { user: { loginName } },
|
||||
: { user: { search: { case: "loginName", value: loginName } } },
|
||||
challenges,
|
||||
);
|
||||
|
||||
if (createdSession) {
|
||||
return getSession(
|
||||
server,
|
||||
createdSession.sessionId,
|
||||
createdSession.sessionToken,
|
||||
).then((response) => {
|
||||
@@ -48,9 +46,9 @@ export async function createSessionAndUpdateCookie(
|
||||
const sessionCookie: SessionCookie = {
|
||||
id: createdSession.sessionId,
|
||||
token: createdSession.sessionToken,
|
||||
creationDate: `${response.session.creationDate?.getTime() ?? ""}`,
|
||||
expirationDate: `${response.session.expirationDate?.getTime() ?? ""}`,
|
||||
changeDate: `${response.session.changeDate?.getTime() ?? ""}`,
|
||||
creationDate: `${response.session.creationDate?.toDate().getTime() ?? ""}`,
|
||||
expirationDate: `${response.session.expirationDate?.toDate().getTime() ?? ""}`,
|
||||
changeDate: `${response.session.changeDate?.toDate().getTime() ?? ""}`,
|
||||
loginName: response.session.factors.user.loginName ?? "",
|
||||
organization: response.session.factors.user.organizationId ?? "",
|
||||
};
|
||||
@@ -82,20 +80,18 @@ export async function createSessionForUserIdAndUpdateCookie(
|
||||
authRequestId: string | undefined,
|
||||
): Promise<Session> {
|
||||
const createdSession = await createSessionFromChecks(
|
||||
server,
|
||||
password
|
||||
? {
|
||||
user: { userId },
|
||||
user: { search: { case: "userId", value: userId } },
|
||||
password: { password },
|
||||
// totp: { code: totpCode },
|
||||
}
|
||||
: { user: { userId } },
|
||||
: { user: { search: { case: "userId", value: userId } } },
|
||||
challenges,
|
||||
);
|
||||
|
||||
if (createdSession) {
|
||||
return getSession(
|
||||
server,
|
||||
createdSession.sessionId,
|
||||
createdSession.sessionToken,
|
||||
).then((response) => {
|
||||
@@ -103,9 +99,9 @@ export async function createSessionForUserIdAndUpdateCookie(
|
||||
const sessionCookie: SessionCookie = {
|
||||
id: createdSession.sessionId,
|
||||
token: createdSession.sessionToken,
|
||||
creationDate: `${response.session.creationDate?.getTime() ?? ""}`,
|
||||
expirationDate: `${response.session.expirationDate?.getTime() ?? ""}`,
|
||||
changeDate: `${response.session.changeDate?.getTime() ?? ""}`,
|
||||
creationDate: `${response.session.creationDate?.toDate().getTime() ?? ""}`,
|
||||
expirationDate: `${response.session.expirationDate?.toDate().getTime() ?? ""}`,
|
||||
changeDate: `${response.session.changeDate?.toDate().getTime() ?? ""}`,
|
||||
loginName: response.session.factors.user.loginName ?? "",
|
||||
};
|
||||
|
||||
@@ -140,14 +136,12 @@ export async function createSessionForIdpAndUpdateCookie(
|
||||
authRequestId: string | undefined,
|
||||
): Promise<Session> {
|
||||
const createdSession = await createSessionForUserIdAndIdpIntent(
|
||||
server,
|
||||
userId,
|
||||
idpIntent,
|
||||
);
|
||||
|
||||
if (createdSession) {
|
||||
return getSession(
|
||||
server,
|
||||
createdSession.sessionId,
|
||||
createdSession.sessionToken,
|
||||
).then((response) => {
|
||||
@@ -155,9 +149,9 @@ export async function createSessionForIdpAndUpdateCookie(
|
||||
const sessionCookie: SessionCookie = {
|
||||
id: createdSession.sessionId,
|
||||
token: createdSession.sessionToken,
|
||||
creationDate: `${response.session.creationDate?.getTime() ?? ""}`,
|
||||
expirationDate: `${response.session.expirationDate?.getTime() ?? ""}`,
|
||||
changeDate: `${response.session.changeDate?.getTime() ?? ""}`,
|
||||
creationDate: `${response.session.creationDate?.toDate().getTime() ?? ""}`,
|
||||
expirationDate: `${response.session.expirationDate?.toDate().getTime() ?? ""}`,
|
||||
changeDate: `${response.session.changeDate?.toDate().getTime() ?? ""}`,
|
||||
loginName: response.session.factors.user.loginName ?? "",
|
||||
organization: response.session.factors.user.organizationId ?? "",
|
||||
};
|
||||
@@ -188,12 +182,11 @@ export type SessionWithChallenges = Session & {
|
||||
|
||||
export async function setSessionAndUpdateCookie(
|
||||
recentCookie: SessionCookie,
|
||||
checks: Checks,
|
||||
checks: PlainMessage<Checks>,
|
||||
challenges: RequestChallenges | undefined,
|
||||
authRequestId: string | undefined,
|
||||
): Promise<SessionWithChallenges> {
|
||||
) {
|
||||
return setSession(
|
||||
server,
|
||||
recentCookie.id,
|
||||
recentCookie.token,
|
||||
challenges,
|
||||
@@ -205,7 +198,7 @@ export async function setSessionAndUpdateCookie(
|
||||
token: updatedSession.sessionToken,
|
||||
creationDate: recentCookie.creationDate,
|
||||
expirationDate: recentCookie.expirationDate,
|
||||
changeDate: `${updatedSession.details?.changeDate?.getTime() ?? ""}`,
|
||||
changeDate: `${updatedSession.details?.changeDate?.toDate().getTime() ?? ""}`,
|
||||
loginName: recentCookie.loginName,
|
||||
organization: recentCookie.organization,
|
||||
};
|
||||
@@ -214,7 +207,7 @@ export async function setSessionAndUpdateCookie(
|
||||
sessionCookie.authRequestId = authRequestId;
|
||||
}
|
||||
|
||||
return getSession(server, sessionCookie.id, sessionCookie.token).then(
|
||||
return getSession(sessionCookie.id, sessionCookie.token).then(
|
||||
(response) => {
|
||||
if (response?.session && response.session.factors?.user?.loginName) {
|
||||
const { session } = response;
|
||||
@@ -223,7 +216,7 @@ export async function setSessionAndUpdateCookie(
|
||||
token: updatedSession.sessionToken,
|
||||
creationDate: sessionCookie.creationDate,
|
||||
expirationDate: sessionCookie.expirationDate,
|
||||
changeDate: `${session.changeDate?.getTime() ?? ""}`,
|
||||
changeDate: `${session.changeDate?.toDate().getTime() ?? ""}`,
|
||||
loginName: session.factors?.user?.loginName ?? "",
|
||||
organization: session.factors?.user?.organizationId ?? "",
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"extends": "@zitadel/tsconfig/nextjs.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "preserve",
|
||||
"rootDir": ".",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
|
||||
@@ -6,16 +6,32 @@
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
|
||||
"dependsOn": [
|
||||
"@zitadel/node#build",
|
||||
"@zitadel/client2#build",
|
||||
"@zitadel/react#build"
|
||||
]
|
||||
},
|
||||
"test:integration": {
|
||||
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
|
||||
"dependsOn": [
|
||||
"@zitadel/node#build",
|
||||
"@zitadel/client2#build",
|
||||
"@zitadel/react#build"
|
||||
]
|
||||
},
|
||||
"test:unit": {
|
||||
"dependsOn": ["@zitadel/server#build"]
|
||||
"dependsOn": [
|
||||
"@zitadel/node#build",
|
||||
"@zitadel/client2#build",
|
||||
"@zitadel/react#build"
|
||||
]
|
||||
},
|
||||
"test:watch": {
|
||||
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
|
||||
"dependsOn": [
|
||||
"@zitadel/node#build",
|
||||
"@zitadel/client2#build",
|
||||
"@zitadel/react#build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
"version": "0.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-config-next": "^14.2.3",
|
||||
"@typescript-eslint/parser": "^7.9.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"eslint-config-turbo": "^1.13.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"test": "pnpm test:unit",
|
||||
@@ -19,25 +22,21 @@
|
||||
"lint": "eslint \"src/**/*.ts*\"",
|
||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@zitadel/react": "workspace:*",
|
||||
"@zitadel/node": "workspace:*",
|
||||
"next": "^14.2.3",
|
||||
"react": "18.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "^14.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^17.0.13",
|
||||
"@zitadel/tsconfig": "workspace:*",
|
||||
"eslint-config-zitadel": "workspace:*",
|
||||
"tailwindcss": "3.2.4",
|
||||
"postcss": "8.4.21",
|
||||
"zitadel-tailwind-config": "workspace:*",
|
||||
"@zitadel/server": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@zitadel/react": "workspace:*",
|
||||
"@zitadel/server": "workspace:*",
|
||||
"next": "^14.2.3",
|
||||
"react": "18.2.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "^14.2.3"
|
||||
"zitadel-tailwind-config": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"build": {
|
||||
"outputs": ["dist/**"],
|
||||
"dependsOn": ["@zitadel/react#build", "@zitadel/server#build"]
|
||||
"dependsOn": ["@zitadel/react#build"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@connectrpc/connect-node": "^1.4.0",
|
||||
"@connectrpc/connect-web": "^1.4.0",
|
||||
"jose": "^5.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.2",
|
||||
"@zitadel/client2": "workspace:*",
|
||||
"@zitadel/tsconfig": "workspace:*",
|
||||
"eslint-config-zitadel": "workspace:*"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { NewAuthorizationBearerInterceptor } from "@zitadel/client2";
|
||||
import {
|
||||
createGrpcWebTransport,
|
||||
GrpcTransportOptions,
|
||||
} from "@connectrpc/connect-node";
|
||||
// import {
|
||||
// createGrpcWebTransport,
|
||||
// GrpcWebTransportOptions,
|
||||
// } from "@connectrpc/connect-node";
|
||||
import { createGrpcWebTransport, GrpcWebTransportOptions } from "@connectrpc/connect-web";
|
||||
import { importPKCS8, SignJWT } from "jose";
|
||||
|
||||
/**
|
||||
@@ -12,7 +13,7 @@ import { importPKCS8, SignJWT } from "jose";
|
||||
*/
|
||||
export function createServerTransport(
|
||||
token: string,
|
||||
opts: GrpcTransportOptions,
|
||||
opts: GrpcWebTransportOptions,
|
||||
) {
|
||||
return createGrpcWebTransport({
|
||||
...opts,
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
"./styles.css": "./dist/index.css",
|
||||
"./assets/*": "./dist/assets/*"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"test": "pnpm test:unit",
|
||||
@@ -25,6 +28,9 @@
|
||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
||||
"copy-files": "cp -R ./src/public/ ./dist/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^6.4.5",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
@@ -38,11 +44,5 @@
|
||||
"sass": "^1.77.1",
|
||||
"tailwindcss": "3.2.4",
|
||||
"zitadel-tailwind-config": "workspace:*"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"extends": "@zitadel/tsconfig/react-library.json",
|
||||
"include": ["."],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
"exclude": ["dist", "build", "node_modules"],
|
||||
"compilerOptions": {
|
||||
"types": ["@testing-library/jest-dom"]
|
||||
}
|
||||
}
|
||||
|
||||
741
pnpm-lock.yaml
generated
741
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user