From 6da145672bee072c865f069fe0e8ad4025a89632 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Sun, 7 Apr 2024 03:56:46 -0400 Subject: [PATCH] refactor: zitadel server Signed-off-by: Yordis Prieto --- README.md | 37 +- apps/login/package.json | 10 +- apps/login/src/app/(login)/accounts/page.tsx | 28 +- apps/login/src/app/(login)/error.tsx | 14 +- .../(login)/idp/[provider]/failure/page.tsx | 14 +- .../(login)/idp/[provider]/success/page.tsx | 82 +- apps/login/src/app/(login)/idp/page.tsx | 26 +- apps/login/src/app/(login)/loginname/page.tsx | 44 +- .../login/src/app/(login)/mfa/create/page.tsx | 35 + apps/login/src/app/(login)/mfa/page.tsx | 103 +-- apps/login/src/app/(login)/mfa/set/page.tsx | 136 +--- .../src/app/(login)/passkey/add/page.tsx | 17 +- .../src/app/(login)/passkey/login/page.tsx | 27 +- apps/login/src/app/(login)/password/page.tsx | 79 +- apps/login/src/app/(login)/register/page.tsx | 11 +- apps/login/src/app/(login)/signedin/page.tsx | 37 +- apps/login/src/app/(login)/verify/page.tsx | 4 +- apps/login/src/app/api/idp/start/route.ts | 20 +- apps/login/src/app/api/loginname/route.ts | 13 +- apps/login/src/app/api/passkeys/route.ts | 38 +- .../src/app/api/passkeys/verify/route.ts | 25 +- apps/login/src/app/api/registeruser/route.ts | 9 +- .../src/app/api/resendverifyemail/route.ts | 5 +- apps/login/src/app/api/session/route.ts | 144 ++-- apps/login/src/app/api/verifyemail/route.ts | 8 +- apps/login/src/app/layout.tsx | 5 - apps/login/src/app/login/route.ts | 150 ++-- apps/login/src/lib/demos.ts | 2 +- apps/login/src/lib/zitadel.ts | 657 ++++------------ apps/login/src/ui/DynamicTheme.tsx | 2 +- apps/login/src/ui/PasswordComplexity.tsx | 4 +- apps/login/src/ui/PasswordForm.tsx | 140 +--- apps/login/src/ui/PrivacyPolicyCheckboxes.tsx | 2 +- .../src/ui/RegisterFormWithoutPassword.tsx | 2 +- apps/login/src/ui/RegisterPasskey.tsx | 33 +- apps/login/src/ui/SessionItem.tsx | 5 +- apps/login/src/ui/SessionsList.tsx | 2 +- apps/login/src/ui/SetPasswordForm.tsx | 2 +- apps/login/src/ui/SignInWithIDP.tsx | 15 +- apps/login/src/ui/ThemeWrapper.tsx | 2 +- apps/login/src/ui/UsernameForm.tsx | 2 +- apps/login/src/utils/colors.ts | 3 +- apps/login/src/utils/cookies.ts | 185 +++-- apps/login/src/utils/session.ts | 336 +++++---- apps/login/tsconfig.json | 1 - apps/login/turbo.json | 8 +- package.json | 8 +- packages/eslint-config-zitadel/package.json | 6 +- .../{.eslintrc.js => .eslintrc.cjs} | 0 packages/zitadel-client/buf.gen.yaml | 14 - packages/zitadel-client/package.json | 41 +- packages/zitadel-client/src/app.ts | 45 -- packages/zitadel-client/src/auth.ts | 19 - packages/zitadel-client/src/helpers.ts | 8 + packages/zitadel-client/src/index.ts | 7 +- .../zitadel-client/src/interceptors.test.ts | 80 ++ packages/zitadel-client/src/interceptors.ts | 16 + .../zitadel-client/src/middleware.test.ts | 76 -- packages/zitadel-client/src/middleware.ts | 14 - packages/zitadel-client/src/v1.ts | 11 + packages/zitadel-client/src/v2beta.ts | 28 + packages/zitadel-client/src/v3alpha.ts | 8 + packages/zitadel-client/tsup.config.ts | 10 +- packages/zitadel-next/package.json | 16 +- packages/zitadel-next/turbo.json | 2 +- .../.eslintrc.cjs} | 1 + .../.gitignore | 0 .../examples/app.ts | 0 packages/zitadel-node/package.json | 61 ++ packages/zitadel-node/src/index.ts | 35 + .../tsconfig.json | 0 .../tsup.config.ts | 8 +- packages/zitadel-node/turbo.json | 11 + packages/zitadel-react/package.json | 12 +- packages/zitadel-react/tsconfig.json | 5 +- packages/zitadel-server/buf.gen.yaml | 18 - packages/zitadel-server/package.json | 40 - packages/zitadel-server/src/admin/admin.ts | 24 - packages/zitadel-server/src/admin/index.ts | 1 - packages/zitadel-server/src/auth/auth.ts | 50 -- packages/zitadel-server/src/auth/index.ts | 2 - packages/zitadel-server/src/index.ts | 142 ---- packages/zitadel-server/src/internal.ts | 3 - .../zitadel-server/src/management/index.ts | 3 - .../src/management/management.ts | 45 -- .../zitadel-server/src/middleware.test.ts | 76 -- packages/zitadel-server/src/middleware.ts | 23 - packages/zitadel-server/src/server.ts | 70 -- packages/zitadel-server/src/system/index.ts | 1 - packages/zitadel-server/src/system/system.ts | 35 - packages/zitadel-server/src/v2/oidc/index.ts | 2 - packages/zitadel-server/src/v2/oidc/oidc.ts | 24 - .../zitadel-server/src/v2/session/index.ts | 2 - .../zitadel-server/src/v2/session/session.ts | 28 - .../zitadel-server/src/v2/settings/index.ts | 2 - .../src/v2/settings/settings.ts | 28 - packages/zitadel-server/src/v2/user/index.ts | 2 - packages/zitadel-server/src/v2/user/user.ts | 28 - packages/zitadel-server/turbo.json | 21 - packages/zitadel-tailwind-config/package.json | 4 +- pnpm-lock.yaml | 705 +++++++++++------- 101 files changed, 1678 insertions(+), 2767 deletions(-) create mode 100644 apps/login/src/app/(login)/mfa/create/page.tsx rename packages/zitadel-client/{.eslintrc.js => .eslintrc.cjs} (100%) delete mode 100644 packages/zitadel-client/buf.gen.yaml delete mode 100644 packages/zitadel-client/src/app.ts delete mode 100644 packages/zitadel-client/src/auth.ts create mode 100644 packages/zitadel-client/src/helpers.ts create mode 100644 packages/zitadel-client/src/interceptors.test.ts create mode 100644 packages/zitadel-client/src/interceptors.ts delete mode 100644 packages/zitadel-client/src/middleware.test.ts delete mode 100644 packages/zitadel-client/src/middleware.ts create mode 100644 packages/zitadel-client/src/v1.ts create mode 100644 packages/zitadel-client/src/v2beta.ts create mode 100644 packages/zitadel-client/src/v3alpha.ts rename packages/{zitadel-server/.eslintrc.js => zitadel-node/.eslintrc.cjs} (54%) rename packages/{zitadel-server => zitadel-node}/.gitignore (100%) rename packages/{zitadel-server => zitadel-node}/examples/app.ts (100%) create mode 100644 packages/zitadel-node/package.json create mode 100644 packages/zitadel-node/src/index.ts rename packages/{zitadel-server => zitadel-node}/tsconfig.json (100%) rename packages/{zitadel-server => zitadel-node}/tsup.config.ts (65%) create mode 100644 packages/zitadel-node/turbo.json delete mode 100644 packages/zitadel-server/buf.gen.yaml delete mode 100644 packages/zitadel-server/package.json delete mode 100644 packages/zitadel-server/src/admin/admin.ts delete mode 100644 packages/zitadel-server/src/admin/index.ts delete mode 100644 packages/zitadel-server/src/auth/auth.ts delete mode 100644 packages/zitadel-server/src/auth/index.ts delete mode 100644 packages/zitadel-server/src/index.ts delete mode 100644 packages/zitadel-server/src/internal.ts delete mode 100644 packages/zitadel-server/src/management/index.ts delete mode 100644 packages/zitadel-server/src/management/management.ts delete mode 100644 packages/zitadel-server/src/middleware.test.ts delete mode 100644 packages/zitadel-server/src/middleware.ts delete mode 100644 packages/zitadel-server/src/server.ts delete mode 100644 packages/zitadel-server/src/system/index.ts delete mode 100644 packages/zitadel-server/src/system/system.ts delete mode 100644 packages/zitadel-server/src/v2/oidc/index.ts delete mode 100644 packages/zitadel-server/src/v2/oidc/oidc.ts delete mode 100644 packages/zitadel-server/src/v2/session/index.ts delete mode 100644 packages/zitadel-server/src/v2/session/session.ts delete mode 100644 packages/zitadel-server/src/v2/settings/index.ts delete mode 100644 packages/zitadel-server/src/v2/settings/settings.ts delete mode 100644 packages/zitadel-server/src/v2/user/index.ts delete mode 100644 packages/zitadel-server/src/v2/user/user.ts delete mode 100644 packages/zitadel-server/turbo.json diff --git a/README.md b/README.md index eb89909ea..cfe1f022f 100644 --- a/README.md +++ b/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. [![Deploy with Vercel](https://vercel.com/button)](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) diff --git a/apps/login/package.json b/apps/login/package.json index 44dc1bb49..5ce7020ac 100644 --- a/apps/login/package.json +++ b/apps/login/package.json @@ -32,13 +32,13 @@ "*": "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", + "@headlessui/react": "^1.7.18", + "@heroicons/react": "2.1.3", + "@tailwindcss/forms": "0.5.7", + "@vercel/analytics": "^1.2.2", + "@zitadel/proto": "workspace:*", "@zitadel/client": "workspace:*", "@zitadel/react": "workspace:*", - "@zitadel/server": "workspace:*", "clsx": "1.2.1", "copy-to-clipboard": "^3.3.3", "moment": "^2.29.4", diff --git a/apps/login/src/app/(login)/accounts/page.tsx b/apps/login/src/app/(login)/accounts/page.tsx index 638b7de06..836dccf40 100644 --- a/apps/login/src/app/(login)/accounts/page.tsx +++ b/apps/login/src/app/(login)/accounts/page.tsx @@ -1,5 +1,5 @@ -import { Session } from "@zitadel/server"; -import { getBrandingSettings, listSessions, server } from "@/lib/zitadel"; +import { Session } from "@zitadel/proto/zitadel/session/v2beta/session_pb"; +import { getBrandingSettings, sessionService } from "@/lib/zitadel"; import { getAllSessionCookieIds } from "@/utils/cookies"; import { UserPlusIcon } from "@heroicons/react/24/outline"; import Link from "next/link"; @@ -9,16 +9,22 @@ import DynamicTheme from "@/ui/DynamicTheme"; async function loadSessions(): Promise { const ids = await getAllSessionCookieIds(); - if (ids && ids.length) { - const response = await listSessions( - server, - ids.filter((id: string | undefined) => !!id), - ); - return response?.sessions ?? []; - } else { - console.info("No session cookie found."); + if (ids.length === 0) { return []; } + + const response = await sessionService.listSessions({ + queries: [ + { + query: { + case: "idsQuery", + value: { ids: ids.filter((id: string | undefined) => !!id) }, + }, + }, + ], + }); + + return response.sessions; } export default async function Page({ @@ -31,7 +37,7 @@ export default async function Page({ let sessions = await loadSessions(); - const branding = await getBrandingSettings(server, organization); + const branding = await getBrandingSettings(organization); return ( diff --git a/apps/login/src/app/(login)/error.tsx b/apps/login/src/app/(login)/error.tsx index 47b2e505c..51066c5d8 100644 --- a/apps/login/src/app/(login)/error.tsx +++ b/apps/login/src/app/(login)/error.tsx @@ -2,21 +2,19 @@ import { Boundary } from "@/ui/Boundary"; import { Button } from "@/ui/Button"; -import React from "react"; - -export default function Error({ error, reset }: any) { - React.useEffect(() => { - console.log("logging error:", error); - }, [error]); +export default function Error(props: { + error: Error | null; + reset: () => void; +}) { return (
- Error: {error?.message} + Error: {props.error?.message}
- +
diff --git a/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx index 2c55493e9..188aed21b 100644 --- a/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx +++ b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx @@ -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 ( diff --git a/apps/login/src/app/(login)/idp/[provider]/success/page.tsx b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx index 4c40a9a08..6f7eee9d1 100644 --- a/apps/login/src/app/(login)/idp/[provider]/success/page.tsx +++ b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx @@ -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 { PartialMessage } from "@zitadel/client"; import { - AddHumanUserRequest, IDPInformation, - RetrieveIdentityProviderIntentResponse, - user, IDPLink, -} from "@zitadel/server"; -import { ClientError } from "nice-grpc"; +} from "@zitadel/proto/zitadel/user/v2beta/idp_pb"; +import { AddHumanUserRequest } from "@zitadel/proto/zitadel/user/v2beta/user_service_pb"; const PROVIDER_MAPPING: { - [provider: string]: (rI: IDPInformation) => Partial; + [provider: string]: ( + rI: IDPInformation, + ) => PartialMessage; } = { [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 = { idpId: idp.idpId, userId: idp.userId, userName: idp.userName, }; - const req: Partial = { + + const req: PartialMessage = { 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 = { idpId: idp.idpId, userId: idp.userId, userName: idp.userName, }; - const req: Partial = { + const req: PartialMessage = { 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 { - 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 { const userData = PROVIDER_MAPPING[provider](info); - const userService = user.getUser(server); return userService.addHumanUser(userData, {}).then((resp) => resp.userId); } @@ -91,13 +100,12 @@ 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) .then((resp) => { const { idpInformation, userId } = resp; - if (idpInformation) { // handle login if (userId) { @@ -128,7 +136,7 @@ export default async function Page({
); }) - .catch((error: ClientError) => { + .catch((error) => { return (
@@ -136,7 +144,7 @@ export default async function Page({
{ - {JSON.stringify(error.details)} + {JSON.stringify(error.message)} }
@@ -167,14 +175,10 @@ export default async function Page({ }); } else { return ( - -
-
-

Register

-

No id and token received!

-
-
-
+
+

Register

+

No id and token received!

+
); } } diff --git a/apps/login/src/app/(login)/idp/page.tsx b/apps/login/src/app/(login)/idp/page.tsx index f9ea08d83..ac6bc25f1 100644 --- a/apps/login/src/app/(login)/idp/page.tsx +++ b/apps/login/src/app/(login)/idp/page.tsx @@ -1,27 +1,19 @@ 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/client/v2beta"; +import { IdentityProvider } from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb"; +import { GetActiveIdentityProvidersResponse } from "@zitadel/proto/zitadel/settings/v2beta/settings_service_pb"; function getIdentityProviders( - server: ZitadelServer, orgId?: string, ): Promise { - const settingsService = settings.getSettings(server); return settingsService - .getActiveIdentityProviders( - orgId ? { ctx: { orgId } } : { ctx: { instance: true } }, - {}, - ) + .getActiveIdentityProviders({ ctx: makeReqCtx(orgId) }) .then((resp: GetActiveIdentityProvidersResponse) => { return resp.identityProviders; }); @@ -35,15 +27,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 ( @@ -59,7 +51,7 @@ export default async function Page({ identityProviders={identityProviders} authRequestId={authRequestId} organization={organization} - > + /> )}
diff --git a/apps/login/src/app/(login)/loginname/page.tsx b/apps/login/src/app/(login)/loginname/page.tsx index ca875b6b6..dd91789d5 100644 --- a/apps/login/src/app/(login)/loginname/page.tsx +++ b/apps/login/src/app/(login)/loginname/page.tsx @@ -2,53 +2,29 @@ import { getBrandingSettings, getLegalAndSupportSettings, getLoginSettings, - server, + getIdentityProviders, } 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"; - -function getIdentityProviders( - server: ZitadelServer, - orgId?: string, -): Promise { - const settingsService = settings.getSettings(server); - return settingsService - .getActiveIdentityProviders( - orgId ? { ctx: { orgId } } : { ctx: { instance: true } }, - {}, - ) - .then((resp: GetActiveIdentityProvidersResponse) => { - return resp.identityProviders; - }); -} -export default async function Page({ - searchParams, -}: { +export default async function Page(props: { searchParams: Record; }) { - const loginName = searchParams?.loginName; - const authRequestId = searchParams?.authRequestId; - const organization = searchParams?.organization; - const submit: boolean = searchParams?.submit === "true"; - - const loginSettings = await getLoginSettings(server, organization); - const legal = await getLegalAndSupportSettings(server); + const loginName = props.searchParams?.loginName; + const authRequestId = props.searchParams?.authRequestId; + const organization = props.searchParams?.organization; + const submit: boolean = props.searchParams?.submit === "true"; - const identityProviders = await getIdentityProviders(server, organization); + const loginSettings = await getLoginSettings(organization); + const legal = await getLegalAndSupportSettings(); + 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 ( diff --git a/apps/login/src/app/(login)/mfa/create/page.tsx b/apps/login/src/app/(login)/mfa/create/page.tsx new file mode 100644 index 000000000..4fd798f7e --- /dev/null +++ b/apps/login/src/app/(login)/mfa/create/page.tsx @@ -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 ( +
+

Password

+

Enter your password.

+ + + +
+ +
+
+ + +
+
+ ); +} diff --git a/apps/login/src/app/(login)/mfa/page.tsx b/apps/login/src/app/(login)/mfa/page.tsx index 1d13c02f8..b0916e9ac 100644 --- a/apps/login/src/app/(login)/mfa/page.tsx +++ b/apps/login/src/app/(login)/mfa/page.tsx @@ -1,102 +1,3 @@ -import { - getBrandingSettings, - getSession, - listAuthenticationMethodTypes, - server, -} from "@/lib/zitadel"; -import Alert from "@/ui/Alert"; -import ChooseSecondFactor from "@/ui/ChooseSecondFactor"; -import DynamicTheme from "@/ui/DynamicTheme"; -import UserAvatar from "@/ui/UserAvatar"; -import { - getMostRecentCookieWithLoginname, - getSessionCookieById, -} from "@/utils/cookies"; - -export default async function Page({ - searchParams, -}: { - searchParams: Record; -}) { - const { loginName, checkAfter, authRequestId, organization, sessionId } = - searchParams; - - const sessionFactors = sessionId - ? await loadSessionById(sessionId, organization) - : await loadSessionByLoginname(loginName, organization); - - async function loadSessionByLoginname( - loginName?: string, - organization?: string, - ) { - const recent = await getMostRecentCookieWithLoginname( - loginName, - organization, - ); - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session && response.session.factors?.user?.id) { - return listAuthenticationMethodTypes( - response.session.factors.user.id, - ).then((methods) => { - return { - factors: response.session?.factors, - authMethods: methods.authMethodTypes ?? [], - }; - }); - } - }); - } - - async function loadSessionById(sessionId: string, organization?: string) { - const recent = await getSessionCookieById(sessionId, organization); - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session && response.session.factors?.user?.id) { - return listAuthenticationMethodTypes( - response.session.factors.user.id, - ).then((methods) => { - return { - factors: response.session?.factors, - authMethods: methods.authMethodTypes ?? [], - }; - }); - } - }); - } - - const branding = await getBrandingSettings(server, organization); - - return ( - -
-

Verify 2-Factor

- -

Choose one of the following second factors.

- - {sessionFactors && ( - - )} - - {!(loginName || sessionId) && ( - Provide your active session as loginName param - )} - - {sessionFactors ? ( - - ) : ( - No second factors available to setup. - )} -
-
- ); +export default function Page() { + return
mfa
; } diff --git a/apps/login/src/app/(login)/mfa/set/page.tsx b/apps/login/src/app/(login)/mfa/set/page.tsx index 9d855b105..3ffaf5f06 100644 --- a/apps/login/src/app/(login)/mfa/set/page.tsx +++ b/apps/login/src/app/(login)/mfa/set/page.tsx @@ -1,116 +1,34 @@ -import { - getBrandingSettings, - getLoginSettings, - getSession, - getUserByID, - listAuthenticationMethodTypes, - server, -} from "@/lib/zitadel"; -import Alert from "@/ui/Alert"; -import ChooseSecondFactorToSetup from "@/ui/ChooseSecondFactorToSetup"; -import DynamicTheme from "@/ui/DynamicTheme"; +"use client"; +import { Button, ButtonVariants } from "@/ui/Button"; +import { TextInput } from "@/ui/Input"; import UserAvatar from "@/ui/UserAvatar"; -import { - getMostRecentCookieWithLoginname, - getSessionCookieById, -} from "@/utils/cookies"; -import { user } from "@zitadel/server"; +import { useRouter } from "next/navigation"; -export default async function Page({ - searchParams, -}: { - searchParams: Record; -}) { - const { loginName, checkAfter, authRequestId, organization, sessionId } = - searchParams; - - const sessionWithData = sessionId - ? await loadSessionById(sessionId, organization) - : await loadSessionByLoginname(loginName, organization); - - async function loadSessionByLoginname( - loginName?: string, - organization?: string, - ) { - const recent = await getMostRecentCookieWithLoginname( - loginName, - organization, - ); - return getSession(server, 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) => { - return { - factors: response.session?.factors, - authMethods: methods.authMethodTypes ?? [], - phoneVerified: user.user?.human?.phone?.isVerified ?? false, - emailVerified: user.user?.human?.email?.isVerified ?? false, - }; - }); - }); - } - }); - } - - async function loadSessionById(sessionId: string, organization?: string) { - const recent = await getSessionCookieById(sessionId, organization); - return getSession(server, 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) => { - return { - factors: response.session?.factors, - authMethods: methods.authMethodTypes ?? [], - phoneVerified: user.user?.human?.phone?.isVerified ?? false, - emailVerified: user.user?.human?.email?.isVerified ?? false, - }; - }); - }); - } - }); - } - - const branding = await getBrandingSettings(server, organization); - const loginSettings = await getLoginSettings(server, organization); +export default function Page() { + const router = useRouter(); return ( - -
-

Set up 2-Factor

- -

Choose one of the following second factors.

- - {sessionWithData && ( - - )} - - {!(loginName || sessionId) && ( - Provide your active session as loginName param - )} - - {loginSettings && sessionWithData ? ( - - ) : ( - No second factors available to setup. - )} +
+

Password

+

Enter your password.

+ + +
+ +
+
+ +
- +
); } diff --git a/apps/login/src/app/(login)/passkey/add/page.tsx b/apps/login/src/app/(login)/passkey/add/page.tsx index 33980960f..cf4cb4b13 100644 --- a/apps/login/src/app/(login)/passkey/add/page.tsx +++ b/apps/login/src/app/(login)/passkey/add/page.tsx @@ -1,9 +1,9 @@ -import { getBrandingSettings, getSession, server } from "@/lib/zitadel"; +import { getBrandingSettings, sessionService } from "@/lib/zitadel"; import Alert, { AlertType } from "@/ui/Alert"; import DynamicTheme from "@/ui/DynamicTheme"; import RegisterPasskey from "@/ui/RegisterPasskey"; import UserAvatar from "@/ui/UserAvatar"; -import { getMostRecentCookieWithLoginname } from "@/utils/cookies"; +import { getMostRecentCookieWithLoginName } from "@/utils/cookies"; export default async function Page({ searchParams, @@ -16,15 +16,15 @@ export default async function Page({ const sessionFactors = await loadSession(loginName); async function loadSession(loginName?: string) { - const recent = await getMostRecentCookieWithLoginname( + const recent = await getMostRecentCookieWithLoginName( loginName, organization, ); - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session) { - return response.session; - } + const response = await sessionService.getSession({ + sessionId: recent.id, + sessionToken: recent.token, }); + return response?.session; } const title = !!promptPasswordless ? "Authenticate with a passkey" @@ -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 ( @@ -45,7 +45,6 @@ export default async function Page({ loginName={loginName ?? sessionFactors.factors?.user?.loginName} displayName={sessionFactors.factors?.user?.displayName} showDropdown - searchParams={searchParams} > )}

{description}

diff --git a/apps/login/src/app/(login)/passkey/login/page.tsx b/apps/login/src/app/(login)/passkey/login/page.tsx index 00a1b2a1b..544543631 100644 --- a/apps/login/src/app/(login)/passkey/login/page.tsx +++ b/apps/login/src/app/(login)/passkey/login/page.tsx @@ -1,10 +1,10 @@ -import { getBrandingSettings, getSession, server } from "@/lib/zitadel"; +import { getBrandingSettings, sessionService } from "@/lib/zitadel"; import Alert from "@/ui/Alert"; import DynamicTheme from "@/ui/DynamicTheme"; import LoginPasskey from "@/ui/LoginPasskey"; import UserAvatar from "@/ui/UserAvatar"; import { - getMostRecentCookieWithLoginname, + getMostRecentCookieWithLoginName, getSessionCookieById, } from "@/utils/cookies"; @@ -28,27 +28,27 @@ export default async function Page({ loginName?: string, organization?: string, ) { - const recent = await getMostRecentCookieWithLoginname( + const recent = await getMostRecentCookieWithLoginName( loginName, organization, ); - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session) { - return response.session; - } + const response = await sessionService.getSession({ + sessionId: recent.id, + sessionToken: recent.token, }); + return response?.session; } async function loadSessionById(sessionId: string, organization?: string) { const recent = await getSessionCookieById(sessionId, organization); - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session) { - return response.session; - } + const response = await sessionService.getSession({ + sessionId: recent.id, + sessionToken: recent.token, }); + return response?.session; } - const branding = await getBrandingSettings(server, organization); + const branding = await getBrandingSettings(organization); return ( @@ -60,11 +60,12 @@ export default async function Page({ loginName={loginName ?? sessionFactors.factors?.user?.loginName} displayName={sessionFactors.factors?.user?.displayName} showDropdown - searchParams={searchParams} > )}

{description}

+ {!sessionFactors &&
} + {!(loginName || sessionId) && ( Provide your active session as loginName param )} diff --git a/apps/login/src/app/(login)/password/page.tsx b/apps/login/src/app/(login)/password/page.tsx index 75938ccdd..e89142e0e 100644 --- a/apps/login/src/app/(login)/password/page.tsx +++ b/apps/login/src/app/(login)/password/page.tsx @@ -1,71 +1,50 @@ -import { - getBrandingSettings, - getLoginSettings, - getSession, - server, -} from "@/lib/zitadel"; +import { getBrandingSettings, sessionService } from "@/lib/zitadel"; import Alert from "@/ui/Alert"; import DynamicTheme from "@/ui/DynamicTheme"; import PasswordForm from "@/ui/PasswordForm"; import UserAvatar from "@/ui/UserAvatar"; -import { getMostRecentCookieWithLoginname } from "@/utils/cookies"; +import { getMostRecentCookieWithLoginName } from "@/utils/cookies"; -export default async function Page({ - searchParams, -}: { +export default async function Page(props: { searchParams: Record; }) { - const { loginName, organization, promptPasswordless, authRequestId, alt } = - searchParams; - const sessionFactors = await loadSession(loginName, organization); + const recent = await getMostRecentCookieWithLoginName( + props.searchParams.loginName, + props.searchParams.organization, + ); - async function loadSession(loginName?: string, organization?: string) { - const recent = await getMostRecentCookieWithLoginname( - loginName, - organization, - ); + const response = await sessionService.getSession({ + sessionId: recent.id, + sessionToken: recent.token, + }); - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session) { - return response.session; - } - }); - } + const branding = await getBrandingSettings(props.searchParams.organization); - const branding = await getBrandingSettings(server, organization); - const loginSettings = await getLoginSettings(server, organization); + if (!response.session) { + throw new Error("Session not found"); + } return (
-

{sessionFactors?.factors?.user?.displayName ?? "Password"}

+

{response.session.factors?.user?.displayName ?? "Password"}

Enter your password.

- {!sessionFactors && ( -
- - Could not get the context of the user. Make sure to enter the - username first or provide a loginName as searchParam. - -
- )} - - {sessionFactors && ( - - )} +
diff --git a/apps/login/src/app/(login)/register/page.tsx b/apps/login/src/app/(login)/register/page.tsx index b41634c48..d9f7ef0f6 100644 --- a/apps/login/src/app/(login)/register/page.tsx +++ b/apps/login/src/app/(login)/register/page.tsx @@ -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 ? ( diff --git a/apps/login/src/app/(login)/signedin/page.tsx b/apps/login/src/app/(login)/signedin/page.tsx index edf4b491c..a61765d20 100644 --- a/apps/login/src/app/(login)/signedin/page.tsx +++ b/apps/login/src/app/(login)/signedin/page.tsx @@ -1,37 +1,41 @@ import { - createCallback, getBrandingSettings, - getSession, - server, + sessionService, + oidcService, } from "@/lib/zitadel"; import DynamicTheme from "@/ui/DynamicTheme"; import UserAvatar from "@/ui/UserAvatar"; -import { getMostRecentCookieWithLoginname } from "@/utils/cookies"; +import { getMostRecentCookieWithLoginName } from "@/utils/cookies"; import { redirect } from "next/navigation"; async function loadSession(loginName: string, authRequestId?: string) { - const recent = await getMostRecentCookieWithLoginname(`${loginName}`); + const recent = await getMostRecentCookieWithLoginName(`${loginName}`); if (authRequestId) { - return createCallback(server, { - authRequestId, - session: { sessionId: recent.id, sessionToken: recent.token }, - }).then(({ callbackUrl }) => { - return redirect(callbackUrl); - }); + return oidcService + .createCallback({ + authRequestId, + callbackKind: { + case: "session", + value: { sessionId: recent.id, sessionToken: recent.token }, + }, + }) + .then(({ callbackUrl }) => { + return redirect(callbackUrl); + }); } - return getSession(server, recent.id, recent.token).then((response) => { - if (response?.session) { - return response.session; - } + const response = await sessionService.getSession({ + sessionId: recent.id, + sessionToken: recent.token, }); + return response?.session; } 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 ( @@ -43,7 +47,6 @@ export default async function Page({ searchParams }: { searchParams: any }) { loginName={loginName ?? sessionFactors?.factors?.user?.loginName} displayName={sessionFactors?.factors?.user?.displayName} showDropdown - searchParams={searchParams} >
diff --git a/apps/login/src/app/(login)/verify/page.tsx b/apps/login/src/app/(login)/verify/page.tsx index 0049fcecd..5bc0cb0eb 100644 --- a/apps/login/src/app/(login)/verify/page.tsx +++ b/apps/login/src/app/(login)/verify/page.tsx @@ -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 ( diff --git a/apps/login/src/app/api/idp/start/route.ts b/apps/login/src/app/api/idp/start/route.ts index 795e563f8..e76a870e6 100644 --- a/apps/login/src/app/api/idp/start/route.ts +++ b/apps/login/src/app/api/idp/start/route.ts @@ -1,4 +1,4 @@ -import { server, startIdentityProviderFlow } from "@/lib/zitadel"; +import { userService } from "@/lib/zitadel"; import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { @@ -6,13 +6,17 @@ export async function POST(request: NextRequest) { if (body) { let { idpId, successUrl, failureUrl } = body; - return startIdentityProviderFlow(server, { - idpId, - urls: { - successUrl, - failureUrl, - }, - }) + return userService + .startIdentityProviderIntent({ + idpId, + content: { + case: "urls", + value: { + successUrl, + failureUrl, + }, + }, + }) .then((resp) => { return NextResponse.json(resp); }) diff --git a/apps/login/src/app/api/loginname/route.ts b/apps/login/src/app/api/loginname/route.ts index 75c9635cb..3b089b051 100644 --- a/apps/login/src/app/api/loginname/route.ts +++ b/apps/login/src/app/api/loginname/route.ts @@ -1,4 +1,4 @@ -import { listAuthenticationMethodTypes, listUsers } from "@/lib/zitadel"; +import { listUsers, userService } from "@/lib/zitadel"; import { createSessionForUserIdAndUpdateCookie } from "@/utils/session"; import { NextRequest, NextResponse } from "next/server"; @@ -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, @@ -21,7 +17,10 @@ export async function POST(request: NextRequest) { ) .then((session) => { if (session.factors?.user?.id) { - return listAuthenticationMethodTypes(session.factors?.user?.id) + return userService + .listAuthenticationMethodTypes({ + userId: session.factors?.user?.id, + }) .then((methods) => { return NextResponse.json({ authMethodTypes: methods.authMethodTypes, diff --git a/apps/login/src/app/api/passkeys/route.ts b/apps/login/src/app/api/passkeys/route.ts index 36293280a..0c1525c0d 100644 --- a/apps/login/src/app/api/passkeys/route.ts +++ b/apps/login/src/app/api/passkeys/route.ts @@ -1,9 +1,4 @@ -import { - createPasskeyRegistrationLink, - getSession, - registerPasskey, - server, -} from "@/lib/zitadel"; +import { sessionService, userService } from "@/lib/zitadel"; import { getSessionCookieById } from "@/utils/cookies"; import { NextRequest, NextResponse } from "next/server"; @@ -14,11 +9,10 @@ export async function POST(request: NextRequest) { const sessionCookie = await getSessionCookieById(sessionId); - const session = await getSession( - server, - sessionCookie.id, - sessionCookie.token, - ); + const session = await sessionService.getSession({ + sessionId: sessionCookie.id, + sessionToken: sessionCookie.token, + }); const domain: string = request.nextUrl.hostname; @@ -26,12 +20,26 @@ export async function POST(request: NextRequest) { if (userId) { // TODO: add org context - return createPasskeyRegistrationLink(userId) + return userService + .createPasskeyRegistrationLink({ + userId, + medium: { + case: "returnCode", + value: {}, + }, + }) .then((resp) => { const code = resp.code; - return registerPasskey(userId, code, domain).then((resp) => { - return NextResponse.json(resp); - }); + return userService + .registerPasskey({ + userId, + code, + domain, + // authenticator: + }) + .then((resp) => { + return NextResponse.json(resp); + }); }) .catch((error) => { console.error("error on creating passkey registration link"); diff --git a/apps/login/src/app/api/passkeys/verify/route.ts b/apps/login/src/app/api/passkeys/verify/route.ts index 4cfd83425..d913d46e8 100644 --- a/apps/login/src/app/api/passkeys/verify/route.ts +++ b/apps/login/src/app/api/passkeys/verify/route.ts @@ -1,4 +1,4 @@ -import { getSession, server, verifyPasskeyRegistration } from "@/lib/zitadel"; +import { sessionService, userService } from "@/lib/zitadel"; import { getSessionCookieById } from "@/utils/cookies"; import { NextRequest, NextResponse, userAgent } from "next/server"; @@ -15,22 +15,21 @@ export async function POST(request: NextRequest) { } const sessionCookie = await getSessionCookieById(sessionId); - const session = await getSession( - server, - sessionCookie.id, - sessionCookie.token, - ); + const session = await sessionService.getSession({ + sessionId: sessionCookie.id, + sessionToken: sessionCookie.token, + }); const userId = session?.session?.factors?.user?.id; if (userId) { - return verifyPasskeyRegistration( - server, - passkeyId, - passkeyName, - publicKeyCredential, - userId, - ) + return userService + .verifyPasskeyRegistration({ + passkeyId, + passkeyName, + publicKeyCredential, + userId, + }) .then((resp) => { return NextResponse.json(resp); }) diff --git a/apps/login/src/app/api/registeruser/route.ts b/apps/login/src/app/api/registeruser/route.ts index 7ed49f48b..efd94759f 100644 --- a/apps/login/src/app/api/registeruser/route.ts +++ b/apps/login/src/app/api/registeruser/route.ts @@ -1,8 +1,5 @@ -import { addHumanUser, server } from "@/lib/zitadel"; -import { - createSessionAndUpdateCookie, - createSessionForUserIdAndUpdateCookie, -} from "@/utils/session"; +import { addHumanUser } from "@/lib/zitadel"; +import { createSessionForUserIdAndUpdateCookie } from "@/utils/session"; import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { @@ -17,7 +14,7 @@ export async function POST(request: NextRequest) { authRequestId, } = body; - return addHumanUser(server, { + return addHumanUser({ email: email, firstName, lastName, diff --git a/apps/login/src/app/api/resendverifyemail/route.ts b/apps/login/src/app/api/resendverifyemail/route.ts index 3ccd724d4..ef851706b 100644 --- a/apps/login/src/app/api/resendverifyemail/route.ts +++ b/apps/login/src/app/api/resendverifyemail/route.ts @@ -1,4 +1,4 @@ -import { setEmail, server } from "@/lib/zitadel"; +import { userService } from "@/lib/zitadel"; import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { @@ -7,7 +7,8 @@ export async function POST(request: NextRequest) { const { userId, code } = body; // replace with resend Mail method once its implemented - return setEmail(server, userId) + return userService + .setEmail({ userId }) .then((resp) => { return NextResponse.json(resp); }) diff --git a/apps/login/src/app/api/session/route.ts b/apps/login/src/app/api/session/route.ts index 404933406..e8dff7d7b 100644 --- a/apps/login/src/app/api/session/route.ts +++ b/apps/login/src/app/api/session/route.ts @@ -1,10 +1,4 @@ -import { - server, - deleteSession, - getSession, - getUserByID, - listAuthenticationMethodTypes, -} from "@/lib/zitadel"; +import { sessionService } from "@/lib/zitadel"; import { SessionCookie, getMostRecentSessionCookie, @@ -17,8 +11,8 @@ import { createSessionForIdpAndUpdateCookie, setSessionAndUpdateCookie, } from "@/utils/session"; -import { Challenges, Checks, RequestChallenges } from "@zitadel/server"; import { NextRequest, NextResponse } from "next/server"; +import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2beta/challenge_pb"; export async function POST(request: NextRequest) { const body = await request.json(); @@ -68,102 +62,55 @@ export async function POST(request: NextRequest) { export async function PUT(request: NextRequest) { const body = await request.json(); - if (body) { - const { - loginName, - sessionId, - organization, - checks, - authRequestId, - challenges, - } = body; + if (!body) { + return NextResponse.json( + { details: "Request body is missing" }, + { status: 400 }, + ); + } - const recentPromise: Promise = sessionId - ? getSessionCookieById(sessionId).catch((error) => { - return Promise.reject(error); - }) - : loginName - ? getSessionCookieByLoginName(loginName, organization).catch( - (error) => { - return Promise.reject(error); - }, - ) - : getMostRecentSessionCookie().catch((error) => { - return Promise.reject(error); - }); + const { + loginName, + sessionId, + organization, + password, + webAuthN, + authRequestId, + } = body; + const challenges: RequestChallenges = body.challenges; - const domain: string = request.nextUrl.hostname; + const sessionCookie = sessionId + ? await getSessionCookieById(sessionId) + : loginName + ? await getSessionCookieByLoginName(loginName, organization) + : await getMostRecentSessionCookie(); - if (challenges && challenges.webAuthN && !challenges.webAuthN.domain) { - challenges.webAuthN.domain = domain; - } + if (!sessionCookie) { + return NextResponse.json( + { details: "No session cookie found" }, + { status: 404 }, + ); + } - return recentPromise - .then(async (recent) => { - if ( - challenges && - (challenges.otpEmail === "" || challenges.otpSms === "") - ) { - const sessionResponse = await getSession( - server, - 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 domain: string = request.nextUrl.hostname; - if ( - challenges.otpSms === "" && - userResponse.user?.human?.phone?.phone - ) { - challenges.otpSms = userResponse.user?.human?.phone?.phone; - } - } - } + if (challenges && challenges.webAuthN && !challenges.webAuthN.domain) { + challenges.webAuthN.domain = domain; + } - return setSessionAndUpdateCookie( - recent, - checks, - challenges, - authRequestId, - ).then(async (session) => { - // if password, check if user has MFA methods - let authMethods; - if (checks && checks.password && session.factors?.user?.id) { - const response = await listAuthenticationMethodTypes( - session.factors?.user?.id, - ); - if (response.authMethodTypes && response.authMethodTypes.length) { - authMethods = response.authMethodTypes; - } - } + const session = await setSessionAndUpdateCookie( + sessionCookie, + password, + webAuthN, + challenges, + authRequestId, + ); - return NextResponse.json({ - sessionId: session.id, - factors: session.factors, - challenges: session.challenges, - authMethods, - }); - }); - }) - .catch((error) => { - console.error(error); - return NextResponse.json({ details: error }, { status: 500 }); - }); - } else { - return NextResponse.json( - { details: "Request body is missing" }, - { status: 400 }, - ); - } + return NextResponse.json({ + sessionId: session.id, + factors: session.factors, + challenges: session.challenges, + }); } /** @@ -176,7 +123,8 @@ export async function DELETE(request: NextRequest) { if (id) { const session = await getSessionCookieById(id); - return deleteSession(server, session.id, session.token) + return sessionService + .deleteSession({ sessionId: session.id, sessionToken: session.token }) .then(() => { return removeSessionFromCookie(session) .then(() => { diff --git a/apps/login/src/app/api/verifyemail/route.ts b/apps/login/src/app/api/verifyemail/route.ts index e2aae9833..0ac424a11 100644 --- a/apps/login/src/app/api/verifyemail/route.ts +++ b/apps/login/src/app/api/verifyemail/route.ts @@ -1,4 +1,4 @@ -import { server, verifyEmail } from "@/lib/zitadel"; +import { userService } from "@/lib/zitadel"; import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { @@ -6,7 +6,11 @@ export async function POST(request: NextRequest) { if (body) { const { userId, code } = body; - return verifyEmail(server, userId, code) + return userService + .verifyEmail({ + userId, + verificationCode: code, + }) .then((resp) => { return NextResponse.json(resp); }) diff --git a/apps/login/src/app/layout.tsx b/apps/login/src/app/layout.tsx index 0eb4b191b..0561ba51d 100644 --- a/apps/login/src/app/layout.tsx +++ b/apps/login/src/app/layout.tsx @@ -2,12 +2,7 @@ import "@/styles/globals.scss"; import { AddressBar } from "@/ui/AddressBar"; import { GlobalNav } from "@/ui/GlobalNav"; import { Lato } from "next/font/google"; -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"; diff --git a/apps/login/src/app/login/route.ts b/apps/login/src/app/login/route.ts index e6a8c3357..58d21f8cb 100644 --- a/apps/login/src/app/login/route.ts +++ b/apps/login/src/app/login/route.ts @@ -1,21 +1,25 @@ -import { - createCallback, - getAuthRequest, - getOrgByDomain, - listSessions, - server, -} from "@/lib/zitadel"; +import { sessionService, managementService, oidcService } from "@/lib/zitadel"; import { SessionCookie, getAllSessions } from "@/utils/cookies"; -import { Session, AuthRequest, Prompt } from "@zitadel/server"; import { NextRequest, NextResponse } from "next/server"; +import { + AuthRequest, + Prompt, +} from "@zitadel/proto/zitadel/oidc/v2beta/authorization_pb"; +import { Session } from "@zitadel/proto/zitadel/session/v2beta/session_pb"; async function loadSessions(ids: string[]): Promise { - const response = await listSessions( - server, - ids.filter((id: string | undefined) => !!id), - ); - - return response?.sessions ?? []; + const response = await sessionService.listSessions({ + queries: [ + { + query: { + case: "idsQuery", + value: { ids: ids.filter((id: string | undefined) => !!id) }, + }, + }, + ], + }); + + return response.sessions; } const ORG_SCOPE_REGEX = /urn:zitadel:iam:org:id:([0-9]+)/; @@ -53,13 +57,6 @@ export async function GET(request: NextRequest) { sessions = await loadSessions(ids); } - /** - * TODO: before automatically redirecting to the callbackUrl, check if the session is still valid - * possible scenaio: - * mfa is required, session is not valid anymore (e.g. session expired, user logged out, etc.) - * to check for mfa for automatically selected session -> const response = await listAuthenticationMethodTypes(userId); - **/ - if (authRequestId && sessionId) { console.log( `Login with session: ${sessionId} and authRequest: ${authRequestId}`, @@ -76,14 +73,15 @@ export async function GET(request: NextRequest) { if (cookie && cookie.id && cookie.token) { console.log(`Found sessioncookie ${cookie.id}`); - const session = { - sessionId: cookie?.id, - sessionToken: cookie?.token, - }; - - const { callbackUrl } = await createCallback(server, { + const { callbackUrl } = await oidcService.createCallback({ authRequestId, - session, + callbackKind: { + case: "session", + value: { + sessionId: cookie?.id, + sessionToken: cookie?.token, + }, + }, }); return NextResponse.redirect(callbackUrl); } @@ -92,9 +90,8 @@ export async function GET(request: NextRequest) { if (authRequestId) { console.log(`Login with authRequest: ${authRequestId}`); - const { authRequest } = await getAuthRequest(server, { authRequestId }); - - let organization = ""; + const { authRequest } = await oidcService.getAuthRequest({ authRequestId }); + let organization; if (authRequest?.scope) { const orgScope = authRequest.scope.find((s: string) => @@ -113,26 +110,16 @@ export async function GET(request: NextRequest) { const matched = ORG_DOMAIN_SCOPE_REGEX.exec(orgDomainScope); const orgDomain = matched?.[1] ?? ""; if (orgDomain) { - const org = await getOrgByDomain(orgDomain); + const org = await managementService.getOrgByDomainGlobal({ + domain: orgDomain, + }); organization = org?.org?.id ?? ""; } } } } - const gotoAccounts = (): NextResponse => { - const accountsUrl = new URL("/accounts", request.url); - if (authRequest?.id) { - accountsUrl.searchParams.set("authRequestId", authRequest?.id); - } - if (organization) { - accountsUrl.searchParams.set("organization", organization); - } - - 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 +134,17 @@ 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)) { - return gotoAccounts(); - } else if (authRequest.prompt.includes(Prompt.PROMPT_LOGIN)) { + if (authRequest.prompt.includes(Prompt.SELECT_ACCOUNT)) { + const accountsUrl = new URL("/accounts", request.url); + if (authRequest?.id) { + accountsUrl.searchParams.set("authRequestId", authRequest?.id); + } + if (organization) { + accountsUrl.searchParams.set("organization", organization); + } + + return NextResponse.redirect(accountsUrl); + } else if (authRequest.prompt.includes(Prompt.LOGIN)) { // if prompt is login const loginNameUrl = new URL("/loginname", request.url); if (authRequest?.id) { @@ -162,7 +157,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); @@ -173,13 +168,15 @@ export async function GET(request: NextRequest) { ); if (cookie && cookie.id && cookie.token) { - const session = { - sessionId: cookie?.id, - sessionToken: cookie?.token, - }; - const { callbackUrl } = await createCallback(server, { + const { callbackUrl } = await oidcService.createCallback({ authRequestId, - session, + callbackKind: { + case: "session", + value: { + sessionId: cookie?.id, + sessionToken: cookie?.token, + }, + }, }); return NextResponse.redirect(callbackUrl); } else { @@ -204,29 +201,32 @@ export async function GET(request: NextRequest) { ); if (cookie && cookie.id && cookie.token) { - const session = { - sessionId: cookie?.id, - sessionToken: cookie?.token, - }; - try { - const { callbackUrl } = await createCallback(server, { - authRequestId, - session, - }); - if (callbackUrl) { - return NextResponse.redirect(callbackUrl); - } else { - return gotoAccounts(); - } - } catch (error) { - console.error(error); - return gotoAccounts(); - } + const { callbackUrl } = await oidcService.createCallback({ + authRequestId, + callbackKind: { + case: "session", + value: { + sessionId: cookie?.id, + sessionToken: cookie?.token, + }, + }, + }); + return NextResponse.redirect(callbackUrl); } else { - return gotoAccounts(); + const accountsUrl = new URL("/accounts", request.url); + accountsUrl.searchParams.set("authRequestId", authRequestId); + if (organization) { + accountsUrl.searchParams.set("organization", organization); + } + return NextResponse.redirect(accountsUrl); } } else { - return gotoAccounts(); + const accountsUrl = new URL("/accounts", request.url); + accountsUrl.searchParams.set("authRequestId", authRequestId); + if (organization) { + accountsUrl.searchParams.set("organization", organization); + } + return NextResponse.redirect(accountsUrl); } } } else { diff --git a/apps/login/src/lib/demos.ts b/apps/login/src/lib/demos.ts index fa0742a46..844c9105d 100644 --- a/apps/login/src/lib/demos.ts +++ b/apps/login/src/lib/demos.ts @@ -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", }, ], diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index b4f0ec90e..861589bff 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -1,229 +1,160 @@ -import { VerifyU2FRegistrationRequest } from "@zitadel/server"; import { - GetUserByIDResponse, - RegisterTOTPResponse, - VerifyTOTPRegistrationResponse, -} from "@zitadel/server"; + createSessionServiceClient, + createUserServiceClient, + createOIDCServiceClient, + createSettingsServiceClient, + makeReqCtx, +} from "@zitadel/client/v2beta"; +import { createManagementServiceClient } from "@zitadel/client/v1"; + +import { PartialMessage } from "@zitadel/client"; +import { createServerTransport } from "@zitadel/node"; +import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2beta/branding_settings_pb"; import { - LegalAndSupportSettings, - PasswordComplexitySettings, - ZitadelServer, - VerifyMyAuthFactorOTPResponse, - ZitadelServerOptions, - user, - oidc, - settings, - getServers, - auth, - initializeServer, - session, - GetGeneralSettingsResponse, - CreateSessionResponse, + GetActiveIdentityProvidersResponse, 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, - CreateCallbackRequest, - CreateCallbackResponse, - RequestChallenges, - TextQueryMethod, - ListHumanAuthFactorsResponse, + GetPasswordComplexitySettingsResponse, +} from "@zitadel/proto/zitadel/settings/v2beta/settings_service_pb"; +import { + IdentityProvider, + LoginSettings, +} from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb"; +import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2beta/legal_settings_pb"; +import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2beta/password_settings_pb"; +import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2beta/challenge_pb"; +import { CreateSessionResponse } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb"; +import { AddHumanUserRequest, - AddOTPEmailResponse, - AddOTPSMSResponse, -} from "@zitadel/server"; - -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 ?? "", -}; + AddHumanUserResponse, + ListUsersRequest, + ListUsersResponse, +} from "@zitadel/proto/zitadel/user/v2beta/user_service_pb"; +import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2beta/object_pb"; +import { SearchQuery } from "@zitadel/proto/zitadel/user/v2beta/query_pb"; + +const transport = createServerTransport( + process.env.ZITADEL_SERVICE_USER_TOKEN!, + { + baseUrl: process.env.ZITADEL_API_URL!, + httpVersion: "2", + }, +); -let server: ZitadelServer; - -if (!getServers().length) { - console.log("initialize server"); - server = initializeServer(zitadelConfig); -} +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); export async function getBrandingSettings( - server: ZitadelServer, - organization?: string, + orgId?: string, ): Promise { - const settingsService = settings.getSettings(server); return settingsService - .getBrandingSettings( - { ctx: organization ? { orgId: organization } : { instance: true } }, - {}, - ) + .getBrandingSettings({ ctx: makeReqCtx(orgId) }) .then((resp: GetBrandingSettingsResponse) => resp.settings); } export async function getLoginSettings( - server: ZitadelServer, orgId?: string, ): Promise { - const settingsService = settings.getSettings(server); return settingsService - .getLoginSettings({ ctx: orgId ? { orgId } : { instance: true } }, {}) + .getLoginSettings({ ctx: makeReqCtx(orgId) }) .then((resp: GetLoginSettingsResponse) => resp.settings); } -export async function verifyMyAuthFactorOTP( - code: string, -): Promise { - const authService = auth.getAuth(server); - return authService.verifyMyAuthFactorOTP({ code }, {}); -} - -export async function addOTPEmail( - userId: string, -): Promise { - const userService = user.getUser(server); - return userService.addOTPEmail( - { - userId, - }, - {}, - ); -} - -export async function addOTPSMS( - userId: string, - token?: string, -): Promise { - 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.addOTPSMS({ userId }, {}); -} - -export async function registerTOTP( - userId: string, - token?: string, -): Promise { - 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 { - const settingsService = settings.getSettings(server); +export function getIdentityProviders( + orgId?: string, +): Promise { return settingsService - .getGeneralSettings({}, {}) - .then((resp: GetGeneralSettingsResponse) => resp.supportedLanguages); + .getActiveIdentityProviders({ ctx: makeReqCtx(orgId) }) + .then((resp: GetActiveIdentityProvidersResponse) => { + return resp.identityProviders; + }); } export async function getLegalAndSupportSettings( - server: ZitadelServer, - organization?: string, + orgId?: string, ): Promise { - const settingsService = settings.getSettings(server); return settingsService - .getLegalAndSupportSettings( - { ctx: organization ? { orgId: organization } : { instance: true } }, - {}, - ) + .getLegalAndSupportSettings({ ctx: makeReqCtx(orgId) }, {}) .then((resp: GetLegalAndSupportSettingsResponse) => { return resp.settings; }); } export async function getPasswordComplexitySettings( - server: ZitadelServer, - organization?: string, + orgId?: string, ): Promise { - const settingsService = settings.getSettings(server); - return settingsService - .getPasswordComplexitySettings( - organization - ? { ctx: { orgId: organization } } - : { ctx: { instance: true } }, - {}, - ) + .getPasswordComplexitySettings({ ctx: makeReqCtx(orgId) }) .then((resp: GetPasswordComplexitySettingsResponse) => resp.settings); } -export async function createSessionFromChecks( - server: ZitadelServer, - checks: Checks, +export async function createSessionForLoginname( + loginName: string, + password: string | undefined, challenges: RequestChallenges | undefined, ): Promise { - const sessionService = session.getSession(server); - return sessionService.createSession( - { - checks: checks, - challenges, - lifetime: { - seconds: SESSION_LIFETIME_S, - nanos: 0, - }, - }, - {}, - ); + return password + ? sessionService.createSession( + { + checks: { + user: { + search: { + case: "loginName", + value: loginName, + }, + }, + password: { password }, + }, + challenges, + lifetime: { + seconds: BigInt(300), + nanos: 0, + }, + }, + {}, + ) + : sessionService.createSession( + { + checks: { + user: { + search: { + case: "loginName", + value: loginName, + }, + }, + }, + challenges, + lifetime: { + seconds: BigInt(300), + nanos: 0, + }, + }, + {}, + ); } export async function createSessionForUserIdAndIdpIntent( - server: ZitadelServer, userId: string, idpIntent: { idpIntentId?: string | undefined; idpIntentToken?: string | undefined; }, ): Promise { - const sessionService = session.getSession(server); - return sessionService.createSession( { - checks: { user: { userId }, idpIntent }, + checks: { + user: { + search: { + case: "userId", + value: userId, + }, + }, + idpIntent, + }, // lifetime: { // seconds: 300, // nanos: 0, @@ -233,58 +164,6 @@ export async function createSessionForUserIdAndIdpIntent( ); } -export async function setSession( - server: ZitadelServer, - sessionId: string, - sessionToken: string, - challenges: RequestChallenges | undefined, - checks: Checks, -): Promise { - 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 { - const sessionService = session.getSession(server); - return sessionService.getSession({ sessionId, sessionToken }, {}); -} - -export async function deleteSession( - server: ZitadelServer, - sessionId: string, - sessionToken: string, -): Promise { - const sessionService = session.getSession(server); - return sessionService.deleteSession({ sessionId, sessionToken }, {}); -} - -export async function listSessions( - server: ZitadelServer, - ids: string[], -): Promise { - const sessionService = session.getSession(server); - const query = { offset: 0, limit: 100, asc: true }; - const queries = [{ idsQuery: { ids } }]; - return sessionService.listSessions({ queries: queries }, {}); -} - export type AddHumanUserData = { firstName: string; lastName: string; @@ -293,308 +172,60 @@ export type AddHumanUserData = { organization: string | undefined; }; -export async function addHumanUser( - server: ZitadelServer, - { email, firstName, lastName, password, organization }: AddHumanUserData, -): Promise { - const userService = user.getUser(server); - - const payload: Partial = { +export async function addHumanUser({ + email, + firstName, + lastName, + password, + organization, +}: AddHumanUserData): Promise { + const payload: PartialMessage = { email: { email }, username: email, profile: { givenName: firstName, familyName: lastName }, }; if (organization) { - payload.organization = { orgId: organization }; + payload.organization = { + org: { case: "orgId", value: organization }, + }; } - return userService.addHumanUser( - password - ? { - ...payload, - password: { password }, - } - : payload, - {}, - ); -} - -export async function verifyTOTPRegistration( - code: string, - userId: string, - token?: string, -): Promise { - let userService; - if (token) { - const authConfig: ZitadelServerOptions = { - name: "zitadel login", - apiUrl: process.env.ZITADEL_API_URL ?? "", - token: token, + if (password) { + payload.passwordType = { + case: "password", + value: { + password: password, + }, }; - - 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 { - const userService = user.getUser(server); - - return userService.getUserByID({ userId }, {}); + return userService.addHumanUser(payload); } export async function listUsers( userName: string, - organizationId: string, + organizationId?: string, ): Promise { - const userService = user.getUser(server); - - return userService.listUsers( - { - queries: organizationId - ? [ - { - userNameQuery: { - userName, - method: TextQueryMethod.TEXT_QUERY_METHOD_EQUALS, - }, - }, - { - organizationIdQuery: { - organizationId, - }, - }, - ] - : [ - { - userNameQuery: { - userName, - method: TextQueryMethod.TEXT_QUERY_METHOD_EQUALS, - }, - }, - ], - }, - {}, - ); -} - -export async function getOrgByDomain( - domain: string, -): Promise { - const mgmtService = management.getManagement(server); - return mgmtService.getOrgByDomainGlobal({ domain }, {}); -} - -export async function startIdentityProviderFlow( - server: ZitadelServer, - { idpId, urls }: StartIdentityProviderIntentRequest, -): Promise { - const userService = user.getUser(server); - - return userService.startIdentityProviderIntent({ - idpId, - urls, - }); -} - -export async function retrieveIdentityProviderInformation( - server: ZitadelServer, - { idpIntentId, idpIntentToken }: RetrieveIdentityProviderIntentRequest, -): Promise { - const userService = user.getUser(server); - - return userService.retrieveIdentityProviderIntent({ - idpIntentId, - idpIntentToken, - }); -} - -export async function getAuthRequest( - server: ZitadelServer, - { authRequestId }: GetAuthRequestRequest, -): Promise { - const oidcService = oidc.getOidc(server); - - return oidcService.getAuthRequest({ - authRequestId, - }); -} - -export async function createCallback( - server: ZitadelServer, - req: CreateCallbackRequest, -): Promise { - const oidcService = oidc.getOidc(server); - - return oidcService.createCallback(req); -} - -export async function verifyEmail( - server: ZitadelServer, - userId: string, - verificationCode: string, -): Promise { - const userservice = user.getUser(server); - return userservice.verifyEmail( - { - userId, - verificationCode, - }, - {}, - ); -} - -/** - * - * @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 { - const userservice = user.getUser(server); - return userservice.setEmail( - { - userId, - }, - {}, - ); -} - -/** - * - * @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 { - 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 queries = [ + new SearchQuery({ + query: { + case: "userNameQuery", + value: { userName, method: TextQueryMethod.EQUALS }, + }, + }), + ]; + + if (organizationId) { + queries.push( + new SearchQuery({ + query: { + case: "organizationIdQuery", + value: { organizationId }, + }, + }), + ); } - return userService.createPasskeyRegistrationLink({ - userId, - returnCode: {}, - }); -} - -/** - * - * @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 { - const userservice = user.getUser(server); - - return userservice.registerU2F({ - userId, - domain, - }); -} - -/** - * - * @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 { - const userservice = user.getUser(server); - - 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: - | { - [key: string]: any; - } - | undefined, - userId: string, -): Promise { - const userservice = user.getUser(server); - return userservice.verifyPasskeyRegistration( - { - passkeyId, - passkeyName, - publicKeyCredential, - userId, - }, - {}, - ); -} - -/** - * - * @param server - * @param userId the id of the user where the email should be set - * @returns the newly set email - */ -export async function registerPasskey( - userId: string, - code: { id: string; code: string }, - domain: string, -): Promise { - const userservice = user.getUser(server); - return userservice.registerPasskey({ - userId, - code, - domain, - // authenticator: - }); + return userService.listUsers(new ListUsersRequest({ queries })); } - -/** - * - * @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 { - const userservice = user.getUser(server); - return userservice.listAuthenticationMethodTypes({ - userId, - }); -} - -export { server }; diff --git a/apps/login/src/ui/DynamicTheme.tsx b/apps/login/src/ui/DynamicTheme.tsx index 0a91d8a5d..6c8a1ffee 100644 --- a/apps/login/src/ui/DynamicTheme.tsx +++ b/apps/login/src/ui/DynamicTheme.tsx @@ -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, diff --git a/apps/login/src/ui/PasswordComplexity.tsx b/apps/login/src/ui/PasswordComplexity.tsx index 7b18dffbb..35ee959cc 100644 --- a/apps/login/src/ui/PasswordComplexity.tsx +++ b/apps/login/src/ui/PasswordComplexity.tsx @@ -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({
{hasMinLength ? check : cross} - Password length {passwordComplexitySettings.minLength} + Password length {passwordComplexitySettings.minLength.toString()}
) : ( diff --git a/apps/login/src/ui/PasswordForm.tsx b/apps/login/src/ui/PasswordForm.tsx index d9e766b61..2a837179f 100644 --- a/apps/login/src/ui/PasswordForm.tsx +++ b/apps/login/src/ui/PasswordForm.tsx @@ -7,19 +7,12 @@ 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"; type Inputs = { password: string; }; type Props = { - loginSettings: LoginSettings | undefined; loginName?: string; organization?: string; authRequestId?: string; @@ -28,7 +21,6 @@ type Props = { }; export default function PasswordForm({ - loginSettings, loginName, organization, authRequestId, @@ -57,9 +49,7 @@ export default function PasswordForm({ body: JSON.stringify({ loginName, organization, - checks: { - password: { password: values.password }, - } as Checks, + password: values.password, authRequestId, }), }); @@ -68,76 +58,15 @@ export default function PasswordForm({ setLoading(false); if (!res.ok) { - console.log(response.details.details); - setError(response.details?.details ?? "Could not verify password"); + setError(response.details); return Promise.reject(response.details); } return response; } function submitPasswordAndContinue(value: Inputs): Promise { - return submitPassword(value).then((resp) => { - // if user has mfa -> /otp/[method] or /u2f - // if mfa is forced and user has no mfa -> /mfa/set - // if no passwordless -> /passkey/add - - // exclude password - const availableSecondFactors = resp.authMethods?.filter( - (m: AuthenticationMethodType) => m !== 1, - ); - if (availableSecondFactors.length == 1) { - const params = new URLSearchParams({ - loginName: resp.factors.user.loginName, - }); - - if (authRequestId) { - params.append("authRequestId", authRequestId); - } - - if (organization) { - params.append("organization", organization); - } - - const factor = availableSecondFactors[0]; - if (factor === 4) { - return router.push(`/otp/time-based?` + params); - } else if (factor === 6) { - return router.push(`/otp/sms?` + params); - } else if (factor === 7) { - return router.push(`/otp/email?` + params); - } else if (factor === 5) { - return router.push(`/u2f?` + params); - } - } else if (availableSecondFactors.length >= 1) { - const params = new URLSearchParams({ - loginName: resp.factors.user.loginName, - }); - - if (authRequestId) { - params.append("authRequestId", authRequestId); - } - - if (organization) { - params.append("organization", organization); - } - - return router.push(`/mfa?` + params); - } else if (loginSettings?.forceMfa && !availableSecondFactors.length) { - const params = new URLSearchParams({ - loginName: resp.factors.user.loginName, - checkAfter: "true", // this defines if the check is directly made after the setup - }); - - if (authRequestId) { - params.append("authRequestId", authRequestId); - } - - if (organization) { - params.append("organization", organization); - } - - return router.push(`/mfa/set?` + params); - } else if ( + return submitPassword(value).then((resp: any) => { + if ( resp.factors && !resp.factors.passwordless && // if session was not verified with a passkey promptPasswordless && // if explicitly prompted due policy @@ -148,48 +77,47 @@ export default function PasswordForm({ promptPasswordless: "true", }); - if (authRequestId) { - params.append("authRequestId", authRequestId); - } - if (organization) { params.append("organization", organization); } return router.push(`/passkey/add?` + params); - } else if (authRequestId && resp && resp.sessionId) { - const params = new URLSearchParams({ - sessionId: resp.sessionId, - authRequest: authRequestId, - }); - - if (organization) { - params.append("organization", organization); - } - - return router.push(`/login?` + params); } else { - // without OIDC flow - const params = new URLSearchParams( - authRequestId - ? { - loginName: resp.factors.user.loginName, - authRequestId, - } - : { - loginName: resp.factors.user.loginName, - }, - ); - - if (organization) { - params.append("organization", organization); + if (authRequestId && resp && resp.sessionId) { + const params = new URLSearchParams({ + sessionId: resp.sessionId, + authRequest: authRequestId, + }); + + if (organization) { + params.append("organization", organization); + } + + return router.push(`/login?` + params); + } else { + const params = new URLSearchParams( + authRequestId + ? { + loginName: resp.factors.user.loginName, + authRequestId, + } + : { + loginName: resp.factors.user.loginName, + }, + ); + + if (organization) { + params.append("organization", organization); + } + + return router.push(`/signedin?` + params); } - - return router.push(`/signedin?` + params); } }); } + const { errors } = formState; + return (
diff --git a/apps/login/src/ui/PrivacyPolicyCheckboxes.tsx b/apps/login/src/ui/PrivacyPolicyCheckboxes.tsx index da94e428c..4879bad38 100644 --- a/apps/login/src/ui/PrivacyPolicyCheckboxes.tsx +++ b/apps/login/src/ui/PrivacyPolicyCheckboxes.tsx @@ -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; diff --git a/apps/login/src/ui/RegisterFormWithoutPassword.tsx b/apps/login/src/ui/RegisterFormWithoutPassword.tsx index fc95aac02..54237111e 100644 --- a/apps/login/src/ui/RegisterFormWithoutPassword.tsx +++ b/apps/login/src/ui/RegisterFormWithoutPassword.tsx @@ -1,6 +1,6 @@ "use client"; -import { LegalAndSupportSettings } from "@zitadel/server"; +import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2beta/legal_settings_pb"; import { useState } from "react"; import { Button, ButtonVariants } from "./Button"; import { TextInput } from "./Input"; diff --git a/apps/login/src/ui/RegisterPasskey.tsx b/apps/login/src/ui/RegisterPasskey.tsx index 67c864c0c..f07559180 100644 --- a/apps/login/src/ui/RegisterPasskey.tsx +++ b/apps/login/src/ui/RegisterPasskey.tsx @@ -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,25 +89,27 @@ export default function RegisterPasskey({ function submitRegisterAndContinue(value: Inputs): Promise { return submitRegister().then((resp: RegisterPasskeyResponse) => { const passkeyId = resp.passkeyId; + const publicKeyCredentialCreationOptions = + resp.publicKeyCredentialCreationOptions?.toJson() as { + publicKey?: PublicKeyCredentialCreationOptions; + }; if ( - resp.publicKeyCredentialCreationOptions && - resp.publicKeyCredentialCreationOptions.publicKey + publicKeyCredentialCreationOptions && + publicKeyCredentialCreationOptions.publicKey ) { - resp.publicKeyCredentialCreationOptions.publicKey.challenge = + publicKeyCredentialCreationOptions.publicKey.challenge = coerceToArrayBuffer( - resp.publicKeyCredentialCreationOptions.publicKey.challenge, + publicKeyCredentialCreationOptions.publicKey.challenge, "challenge", ); - resp.publicKeyCredentialCreationOptions.publicKey.user.id = + publicKeyCredentialCreationOptions.publicKey.user.id = coerceToArrayBuffer( - resp.publicKeyCredentialCreationOptions.publicKey.user.id, + publicKeyCredentialCreationOptions.publicKey.user.id, "userid", ); - if ( - resp.publicKeyCredentialCreationOptions.publicKey.excludeCredentials - ) { - resp.publicKeyCredentialCreationOptions.publicKey.excludeCredentials.map( + if (publicKeyCredentialCreationOptions.publicKey.excludeCredentials) { + publicKeyCredentialCreationOptions.publicKey.excludeCredentials.map( (cred: any) => { cred.id = coerceToArrayBuffer( cred.id as string, @@ -119,7 +121,7 @@ export default function RegisterPasskey({ } navigator.credentials - .create(resp.publicKeyCredentialCreationOptions) + .create(publicKeyCredentialCreationOptions) .then((resp) => { if ( resp && @@ -200,17 +202,14 @@ export default function RegisterPasskey({ onClick={() => { const params = new URLSearchParams(); if (authRequestId) { - params.set("authRequest", authRequestId); - } - if (sessionId) { - params.set("sessionId", sessionId); + params.set("authRequestId", authRequestId); } if (organization) { params.set("organization", organization); } - router.push("/login?" + params); + router.push("/accounts?" + params); }} > skip diff --git a/apps/login/src/ui/SessionItem.tsx b/apps/login/src/ui/SessionItem.tsx index 5a620f210..07698507e 100644 --- a/apps/login/src/ui/SessionItem.tsx +++ b/apps/login/src/ui/SessionItem.tsx @@ -1,10 +1,10 @@ "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, @@ -43,7 +43,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() + ? new Date(session.expirationDate.toDate()) > new Date() : true; const validDate = validPassword || validPasskey; @@ -96,6 +96,7 @@ export default function SessionItem({ {validUser && ( + {/*@ts-expect-error follow up here why the original object is lost and it is string value instead*/} {validDate && moment(new Date(validDate)).fromNow()} )} diff --git a/apps/login/src/ui/SessionsList.tsx b/apps/login/src/ui/SessionsList.tsx index a7e0c4cfa..d55679f8c 100644 --- a/apps/login/src/ui/SessionsList.tsx +++ b/apps/login/src/ui/SessionsList.tsx @@ -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[]; diff --git a/apps/login/src/ui/SetPasswordForm.tsx b/apps/login/src/ui/SetPasswordForm.tsx index ed74d7b64..177d302a1 100644 --- a/apps/login/src/ui/SetPasswordForm.tsx +++ b/apps/login/src/ui/SetPasswordForm.tsx @@ -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 = | { diff --git a/apps/login/src/ui/SignInWithIDP.tsx b/apps/login/src/ui/SignInWithIDP.tsx index 4e7499995..e2244f3b3 100644 --- a/apps/login/src/ui/SignInWithIDP.tsx +++ b/apps/login/src/ui/SignInWithIDP.tsx @@ -10,6 +10,7 @@ import { import { useRouter } from "next/navigation"; import { ProviderSlug } from "@/lib/demos"; import Alert from "./Alert"; +import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2beta/login_settings_pb"; export interface SignInWithIDPProps { children?: ReactNode; @@ -72,11 +73,11 @@ export function SignInWithIDP({ } return ( -
+
{identityProviders && identityProviders.map((idp, i) => { switch (idp.type) { - case 6: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITHUB: + case "IDENTITY_PROVIDER_TYPE_GITHUB": return ( ); - case 7: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITHUB_ES: + case "IDENTITY_PROVIDER_TYPE_GITHUB_ES": return ( alert("TODO: unimplemented")} > ); - case 5: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_AZURE_AD: + case "IDENTITY_PROVIDER_TYPE_AZURE_AD": return ( alert("TODO: unimplemented")} > ); - case 10: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GOOGLE: + case "IDENTITY_PROVIDER_TYPE_GOOGLE": return ( ); - case 8: // IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITLAB: + case IdentityProviderType.GITLAB: return ( alert("TODO: unimplemented")} > ); - case 9: //IdentityProviderType.IDENTITY_PROVIDER_TYPE_GITLAB_SELF_HOSTED: + case IdentityProviderType.GITLAB_SELF_HOSTED: return ( | undefined; diff --git a/apps/login/src/ui/UsernameForm.tsx b/apps/login/src/ui/UsernameForm.tsx index e1f42a8c7..39c540492 100644 --- a/apps/login/src/ui/UsernameForm.tsx +++ b/apps/login/src/ui/UsernameForm.tsx @@ -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; diff --git a/apps/login/src/utils/colors.ts b/apps/login/src/utils/colors.ts index a5fba8e0c..b15615e3f 100644 --- a/apps/login/src/utils/colors.ts +++ b/apps/login/src/utils/colors.ts @@ -1,6 +1,5 @@ import tinycolor from "tinycolor2"; - -import { BrandingSettings } from "@zitadel/server"; +import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2beta/branding_settings_pb"; export interface Color { name: string; diff --git a/apps/login/src/utils/cookies.ts b/apps/login/src/utils/cookies.ts index 526e5de4f..8275ee293 100644 --- a/apps/login/src/utils/cookies.ts +++ b/apps/login/src/utils/cookies.ts @@ -109,73 +109,63 @@ export async function removeSessionFromCookie( } } -export async function getMostRecentSessionCookie(): Promise { - const cookiesList = cookies(); - const stringifiedCookie = cookiesList.get("sessions"); - - if (stringifiedCookie?.value) { - const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value); - - const latest = sessions.reduce((prev, current) => { - return new Date(prev.changeDate).getTime() > - new Date(current.changeDate).getTime() - ? prev - : current; - }); +export async function getMostRecentSessionCookie() { + return cookieSessions().sort(sortSessionCookie).at(0); +} - return latest; - } else { - return Promise.reject("no session cookie found"); - } +function cookieSessions(): SessionCookie[] { + const stringifiedCookie = cookies().get("sessions"); + return stringifiedCookie?.value ? JSON.parse(stringifiedCookie?.value) : []; } export async function getSessionCookieById( id: string, organization?: string, ): Promise { - const cookiesList = cookies(); - const stringifiedCookie = cookiesList.get("sessions"); + const sessions = cookieSessions(); - if (stringifiedCookie?.value) { - const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value); + const found = sessions.find((session) => { + if (session.id !== id) { + return false; + } - const found = sessions.find((s) => - organization - ? s.organization === organization && s.id === id - : s.id === id, - ); - if (found) { - return found; - } else { - return Promise.reject(); + if (organization) { + return session.organization === organization; } - } else { - return Promise.reject(); + + return true; + }); + + if (!found) { + throw new Error("No session cookie found"); } + + return found; } export async function getSessionCookieByLoginName( loginName: string, organization?: string, ): Promise { - const cookiesList = cookies(); - const stringifiedCookie = cookiesList.get("sessions"); + const sessions = cookieSessions(); - if (stringifiedCookie?.value) { - const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value); - const found = sessions.find((s) => - organization - ? s.organization === organization && s.loginName === loginName - : s.loginName === loginName, - ); - if (found) { - return found; - } else { - return Promise.reject("no cookie found with loginName: " + loginName); + const found = sessions.find((session) => { + if (session.loginName !== loginName) { + return false; } - } else { - return Promise.reject("no session cookie found"); + + if (organization) { + return session.organization === organization; + } + + return true; + }); + + if (!found) { + throw new Error("No session cookie found"); } + + return found; } /** @@ -215,70 +205,69 @@ export async function getAllSessionCookieIds( * @returns Session Cookies */ export async function getAllSessions( - cleanup: boolean = false, + cleanup: boolean = true, ): Promise { - const cookiesList = cookies(); - const stringifiedCookie = cookiesList.get("sessions"); - - if (stringifiedCookie?.value) { - const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value); + const sessions = cookieSessions(); - if (cleanup) { - const now = new Date(); - return sessions.filter((session) => - session.expirationDate ? new Date(session.expirationDate) > now : true, - ); - } else { - return sessions; - } - } else { - return []; + if (cleanup) { + const now = new Date(); + return sessions.filter(isAfterExpirationDate(now)); } + + return sessions; +} + +function isAfterExpirationDate(now: Date) { + return (session: SessionCookie) => { + return session.expirationDate + ? new Date(session.expirationDate) > now + : true; + }; +} + +function isLoginNameSessionCookie(loginName: string) { + return (cookie: SessionCookie) => { + return cookie.loginName === loginName; + }; +} + +function isOrganizationSessionCookie(orgId: string) { + return (cookie: SessionCookie) => { + return cookie.organization === orgId; + }; +} + +function sortSessionCookie(prev: SessionCookie, current: SessionCookie) { + return ( + new Date(current.changeDate).getTime() - new Date(prev.changeDate).getTime() + ); } /** - * Returns most recent session filtered by optinal loginName - * @param loginName + * Returns most recent session filtered + * @param loginName filter by loginName + * @param organization filter by organization * @returns most recent session */ -export async function getMostRecentCookieWithLoginname( +export async function getMostRecentCookieWithLoginName( loginName?: string, organization?: string, ): Promise { - const cookiesList = cookies(); - const stringifiedCookie = cookiesList.get("sessions"); + let sessions = cookieSessions(); - if (stringifiedCookie?.value) { - const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value); - let filtered = sessions.filter((cookie) => { - return !!loginName ? cookie.loginName === loginName : true; - }); + sessions = loginName + ? sessions.filter(isLoginNameSessionCookie(loginName)) + : sessions; - if (organization) { - filtered = filtered.filter((cookie) => { - return cookie.organization === organization; - }); - } + sessions = organization + ? sessions.filter(isOrganizationSessionCookie(organization)) + : sessions; - const latest = - filtered && filtered.length - ? filtered.reduce((prev, current) => { - return new Date(prev.changeDate).getTime() > - new Date(current.changeDate).getTime() - ? prev - : current; - }) - : undefined; - - if (latest) { - return latest; - } else { - console.error("sessions", sessions, loginName, organization); - return Promise.reject("Could not get the context or retrieve a session"); - } - } else { - return Promise.reject("Could not read session cookie"); + const latest = sessions.sort(sortSessionCookie).at(0); + + if (!latest) { + throw new Error("No session cookie found"); } -} -export async function clearSessions() {} + return latest; +} diff --git a/apps/login/src/utils/session.ts b/apps/login/src/utils/session.ts index 22f57f266..bad7ba1f7 100644 --- a/apps/login/src/utils/session.ts +++ b/apps/login/src/utils/session.ts @@ -1,23 +1,22 @@ "use server"; import { - createSessionFromChecks, + createSessionForLoginname, createSessionForUserIdAndIdpIntent, - getSession, - server, - setSession, + sessionService, } from "@/lib/zitadel"; import { SessionCookie, addSessionToCookie, updateSessionCookie, } from "./cookies"; +import { PlainMessage, PartialMessage } from "@zitadel/client"; 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 { CheckWebAuthN } from "@zitadel/proto/zitadel/session/v2beta/session_service_pb"; export async function createSessionAndUpdateCookie( loginName: string, @@ -26,50 +25,45 @@ export async function createSessionAndUpdateCookie( organization?: string, authRequestId?: string, ): Promise { - const createdSession = await createSessionFromChecks( - server, - password - ? { - user: { loginName }, - password: { password }, - // totp: { code: totpCode }, - } - : { user: { loginName } }, + const createdSession = await createSessionForLoginname( + loginName, + password, challenges, ); if (createdSession) { - return getSession( - server, - createdSession.sessionId, - createdSession.sessionToken, - ).then((response) => { - if (response?.session && response.session?.factors?.user?.loginName) { - const sessionCookie: SessionCookie = { - id: createdSession.sessionId, - token: createdSession.sessionToken, - creationDate: `${response.session.creationDate?.getTime() ?? ""}`, - expirationDate: `${response.session.expirationDate?.getTime() ?? ""}`, - changeDate: `${response.session.changeDate?.getTime() ?? ""}`, - loginName: response.session.factors.user.loginName ?? "", - organization: response.session.factors.user.organizationId ?? "", - }; - - if (authRequestId) { - sessionCookie.authRequestId = authRequestId; - } + return sessionService + .getSession({ + sessionId: createdSession.sessionId, + sessionToken: createdSession.sessionToken, + }) + .then((response) => { + if (response?.session && response.session?.factors?.user?.loginName) { + const sessionCookie: SessionCookie = { + id: createdSession.sessionId, + token: createdSession.sessionToken, + 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 ?? "", + }; + + if (authRequestId) { + sessionCookie.authRequestId = authRequestId; + } - if (organization) { - sessionCookie.organization = organization; - } + if (organization) { + sessionCookie.organization = organization; + } - return addSessionToCookie(sessionCookie).then(() => { - return response.session as Session; - }); - } else { - throw "could not get session or session does not have loginName"; - } - }); + return addSessionToCookie(sessionCookie).then(() => { + return response.session as Session; + }); + } else { + throw "could not get session or session does not have loginName"; + } + }); } else { throw "Could not create session"; } @@ -80,54 +74,59 @@ export async function createSessionForUserIdAndUpdateCookie( password: string | undefined, challenges: RequestChallenges | undefined, authRequestId: string | undefined, -): Promise { - const createdSession = await createSessionFromChecks( - server, - password - ? { - user: { userId }, - password: { password }, - // totp: { code: totpCode }, - } - : { user: { userId } }, +) { + const createdSession = await sessionService.createSession({ + checks: { + user: { + search: { + case: "userId", + value: userId, + }, + }, + password: password ? { password } : undefined, + }, challenges, - ); + lifetime: { + seconds: BigInt(300), + nanos: 0, + }, + }); - if (createdSession) { - return getSession( - server, - createdSession.sessionId, - createdSession.sessionToken, - ).then((response) => { - if (response?.session && response.session?.factors?.user?.loginName) { - const sessionCookie: SessionCookie = { - id: createdSession.sessionId, - token: createdSession.sessionToken, - creationDate: `${response.session.creationDate?.getTime() ?? ""}`, - expirationDate: `${response.session.expirationDate?.getTime() ?? ""}`, - changeDate: `${response.session.changeDate?.getTime() ?? ""}`, - loginName: response.session.factors.user.loginName ?? "", - }; - - if (authRequestId) { - sessionCookie.authRequestId = authRequestId; - } + if (!createdSession) { + throw "Could not create session"; + } - if (response.session.factors.user.organizationId) { - sessionCookie.organization = - response.session.factors.user.organizationId; - } + const response = await sessionService.getSession({ + sessionId: createdSession.sessionId, + sessionToken: createdSession.sessionToken, + }); - return addSessionToCookie(sessionCookie).then(() => { - return response.session as Session; - }); - } else { - throw "could not get session or session does not have loginName"; - } - }); - } else { - throw "Could not create session"; + if (!response.session?.factors?.user?.loginName) { + throw "could not get session or session does not have loginName"; } + + const sessionCookie: SessionCookie = { + id: createdSession.sessionId, + token: createdSession.sessionToken, + creationDate: `${response.session.creationDate?.toDate().getTime() ?? ""}`, + expirationDate: `${response.session.expirationDate?.toDate().getTime() ?? ""}`, + changeDate: `${response.session.changeDate?.toDate().getTime() ?? ""}`, + loginName: response.session.factors.user.loginName ?? "", + }; + + if (authRequestId) { + sessionCookie.authRequestId = authRequestId; + } + + if (response.session.factors.user.organizationId) { + sessionCookie.organization = response.session.factors.user.organizationId; + } + + await addSessionToCookie(sessionCookie); + + console.log(response.session); + + return response.session; } export async function createSessionForIdpAndUpdateCookie( @@ -140,108 +139,117 @@ export async function createSessionForIdpAndUpdateCookie( authRequestId: string | undefined, ): Promise { const createdSession = await createSessionForUserIdAndIdpIntent( - server, userId, idpIntent, ); if (createdSession) { - return getSession( - server, - createdSession.sessionId, - createdSession.sessionToken, - ).then((response) => { - if (response?.session && response.session?.factors?.user?.loginName) { - const sessionCookie: SessionCookie = { - id: createdSession.sessionId, - token: createdSession.sessionToken, - creationDate: `${response.session.creationDate?.getTime() ?? ""}`, - expirationDate: `${response.session.expirationDate?.getTime() ?? ""}`, - changeDate: `${response.session.changeDate?.getTime() ?? ""}`, - loginName: response.session.factors.user.loginName ?? "", - organization: response.session.factors.user.organizationId ?? "", - }; - - if (authRequestId) { - sessionCookie.authRequestId = authRequestId; - } + return sessionService + .getSession({ + sessionId: createdSession.sessionId, + sessionToken: createdSession.sessionToken, + }) + .then((response) => { + if (response?.session && response.session?.factors?.user?.loginName) { + const sessionCookie: SessionCookie = { + id: createdSession.sessionId, + token: createdSession.sessionToken, + 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 ?? "", + }; + + if (authRequestId) { + sessionCookie.authRequestId = authRequestId; + } - if (organization) { - sessionCookie.organization = organization; - } + if (organization) { + sessionCookie.organization = organization; + } - return addSessionToCookie(sessionCookie).then(() => { - return response.session as Session; - }); - } else { - throw "could not get session or session does not have loginName"; - } - }); + return addSessionToCookie(sessionCookie).then(() => { + return response.session as Session; + }); + } else { + throw "could not get session or session does not have loginName"; + } + }); } else { throw "Could not create session"; } } -export type SessionWithChallenges = Session & { +export type SessionWithChallenges = PlainMessage & { challenges: Challenges | undefined; }; export async function setSessionAndUpdateCookie( recentCookie: SessionCookie, - checks: Checks, + password: string | undefined, + webAuthN: PartialMessage | undefined, challenges: RequestChallenges | undefined, authRequestId: string | undefined, ): Promise { - return setSession( - server, - recentCookie.id, - recentCookie.token, + const updatedSession = await sessionService.setSession({ + sessionId: recentCookie.id, + sessionToken: recentCookie.token, challenges, - checks, - ).then((updatedSession) => { - if (updatedSession) { - const sessionCookie: SessionCookie = { - id: recentCookie.id, + checks: { + password: password ? { password } : undefined, + webAuthN: webAuthN, + }, + }); + + if (updatedSession) { + const sessionCookie: SessionCookie = { + id: recentCookie.id, + token: updatedSession.sessionToken, + creationDate: recentCookie.creationDate, + expirationDate: recentCookie.expirationDate, + changeDate: `${updatedSession.details?.changeDate?.toDate().getTime() ?? ""}`, + loginName: recentCookie.loginName, + organization: recentCookie.organization, + }; + + if (authRequestId) { + sessionCookie.authRequestId = authRequestId; + } + + await new Promise((resolve) => setTimeout(resolve, 1000)); + + // TODO: remove + const response = await sessionService.getSession({ + sessionId: sessionCookie.id, + sessionToken: sessionCookie.token, + }); + + if (response?.session && response.session.factors?.user?.loginName) { + const { session } = response; + const newCookie: SessionCookie = { + id: sessionCookie.id, token: updatedSession.sessionToken, - creationDate: recentCookie.creationDate, - expirationDate: recentCookie.expirationDate, - changeDate: `${updatedSession.details?.changeDate?.getTime() ?? ""}`, - loginName: recentCookie.loginName, - organization: recentCookie.organization, + creationDate: sessionCookie.creationDate, + expirationDate: sessionCookie.expirationDate, + changeDate: `${session.changeDate?.toDate().getTime() ?? ""}`, + loginName: session.factors?.user?.loginName ?? "", + organization: session.factors?.user?.organizationId ?? "", }; - if (authRequestId) { - sessionCookie.authRequestId = authRequestId; + if (sessionCookie.authRequestId) { + newCookie.authRequestId = sessionCookie.authRequestId; } - return getSession(server, sessionCookie.id, sessionCookie.token).then( - (response) => { - if (response?.session && response.session.factors?.user?.loginName) { - const { session } = response; - const newCookie: SessionCookie = { - id: sessionCookie.id, - token: updatedSession.sessionToken, - creationDate: sessionCookie.creationDate, - expirationDate: sessionCookie.expirationDate, - changeDate: `${session.changeDate?.getTime() ?? ""}`, - loginName: session.factors?.user?.loginName ?? "", - organization: session.factors?.user?.organizationId ?? "", - }; - - if (sessionCookie.authRequestId) { - newCookie.authRequestId = sessionCookie.authRequestId; - } - - return updateSessionCookie(sessionCookie.id, newCookie).then(() => { - return { challenges: updatedSession.challenges, ...session }; - }); - } else { - throw "could not get session or session does not have loginName"; - } - }, - ); + await updateSessionCookie(sessionCookie.id, newCookie); + return { + challenges: updatedSession.challenges, + ...session, + }; } else { - throw "Session not be set"; + throw "could not get session or session does not have loginName"; } - }); + } else { + throw "Session not be set"; + } } diff --git a/apps/login/tsconfig.json b/apps/login/tsconfig.json index 161099e16..bf3a62f57 100755 --- a/apps/login/tsconfig.json +++ b/apps/login/tsconfig.json @@ -2,7 +2,6 @@ "extends": "@zitadel/tsconfig/nextjs.json", "compilerOptions": { "jsx": "preserve", - "rootDir": ".", "baseUrl": ".", "paths": { "@/*": ["./src/*"] diff --git a/apps/login/turbo.json b/apps/login/turbo.json index ff7aaf0a4..72787b037 100644 --- a/apps/login/turbo.json +++ b/apps/login/turbo.json @@ -6,16 +6,16 @@ "dependsOn": ["^build"] }, "test": { - "dependsOn": ["@zitadel/server#build", "@zitadel/react#build"] + "dependsOn": ["@zitadel/client#build", "@zitadel/react#build"] }, "test:integration": { - "dependsOn": ["@zitadel/server#build", "@zitadel/react#build"] + "dependsOn": ["@zitadel/client#build", "@zitadel/react#build"] }, "test:unit": { - "dependsOn": ["@zitadel/server#build"] + "dependsOn": ["@zitadel/client#build"] }, "test:watch": { - "dependsOn": ["@zitadel/server#build", "@zitadel/react#build"] + "dependsOn": ["@zitadel/client#build", "@zitadel/react#build"] } } } diff --git a/package.json b/package.json index 05ea53a3c..783df88cd 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "packageManager": "pnpm@9.1.2+sha256.19c17528f9ca20bd442e4ca42f00f1b9808a9cb419383cd04ba32ef19322aba7", "private": true, + "workspaces": ["packages/*"], "scripts": { "generate": "turbo run generate", "build": "turbo run build", @@ -19,11 +20,14 @@ }, "pnpm": { "overrides": { - "@typescript-eslint/parser": "^7.9.0" + "@typescript-eslint/parser": "^7.9.0", + "@bufbuild/protobuf": "^1.8.0", + "@connectrpc/connect": "^1.4.0", + "@connectrpc/connect-node": "^1.4.0" } }, "devDependencies": { - "@changesets/cli": "^2.22.0", + "@changesets/cli": "^2.27.1", "@vitejs/plugin-react": "^4.2.1", "eslint": "^8.57.0", "eslint-config-zitadel": "workspace:*", diff --git a/packages/eslint-config-zitadel/package.json b/packages/eslint-config-zitadel/package.json index d45f0f431..0bf9d54ea 100644 --- a/packages/eslint-config-zitadel/package.json +++ b/packages/eslint-config-zitadel/package.json @@ -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" } } diff --git a/packages/zitadel-client/.eslintrc.js b/packages/zitadel-client/.eslintrc.cjs similarity index 100% rename from packages/zitadel-client/.eslintrc.js rename to packages/zitadel-client/.eslintrc.cjs diff --git a/packages/zitadel-client/buf.gen.yaml b/packages/zitadel-client/buf.gen.yaml deleted file mode 100644 index 6f34a5154..000000000 --- a/packages/zitadel-client/buf.gen.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# buf.gen.yaml -version: v1 -managed: - enabled: true -plugins: - # - plugin: buf.build/protocolbuffers/js - # out: src/app/proto/generated - # opt: import_style=commonjs,binary - - plugin: buf.build/grpc/web - out: src/proto/client - opt: import_style=typescript,mode=grpcweb - # - plugin: buf.build/grpc-ecosystem/openapiv2 - # out: src/app/proto/generated - # opt: allow_delete_body diff --git a/packages/zitadel-client/package.json b/packages/zitadel-client/package.json index 4845ee252..cc2028f75 100644 --- a/packages/zitadel-client/package.json +++ b/packages/zitadel-client/package.json @@ -1,24 +1,51 @@ { "name": "@zitadel/client", "version": "0.0.0", - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "sideEffects": false, "license": "MIT", + "publishConfig": { + "access": "public" + }, + "type": "module", + "exports": { + ".": { + "import": "./dist/index.js", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + }, + "./v1": { + "import": "./dist/v1.js", + "require": "./dist/v1.cjs", + "types": "./dist/v1.d.ts" + }, + "./v2beta": { + "import": "./dist/v2beta.js", + "require": "./dist/v2beta.cjs", + "types": "./dist/v2beta.d.ts" + }, + "./v3alpha": { + "import": "./dist/v3alpha.js", + "require": "./dist/v3alpha.cjs", + "types": "./dist/v3alpha.d.ts" + } + }, "files": [ "dist/**" ], + "sideEffects": false, "scripts": { - "generate": "buf generate https://github.com/zitadel/zitadel.git --path ./proto/zitadel", - "build": "tsup --dts", + "build": "tsup", "test": "pnpm test:unit", "test:watch": "pnpm test:unit:watch", "test:unit": "vitest", "test:unit:watch": "vitest --watch", "dev": "tsup --watch --dts", "lint": "eslint \"src/**/*.ts*\"", - "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist && rm -rf src/proto" + "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" + }, + "dependencies": { + "@zitadel/proto": "workspace:*", + "@bufbuild/protobuf": "^1.8.0", + "@connectrpc/connect": "^1.4.0" }, "devDependencies": { "@bufbuild/buf": "^1.14.0", diff --git a/packages/zitadel-client/src/app.ts b/packages/zitadel-client/src/app.ts deleted file mode 100644 index 14816df02..000000000 --- a/packages/zitadel-client/src/app.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Return a slugified copy of a string. - * - * @param {CoreProps} str The ZITADEL client configuration - * @return {Core} The client implementation. - */ - -let apps: ZitadelApp[] = []; - -export interface ZitadelCoreProps { - clientId: string; - apiUrl: string; // process.env.ZITADEL_API_URL - token: string; - adminToken?: string; - managementToken?: string; -} - -export interface ZitadelOptions extends ZitadelCoreProps { - name?: string; -} - -export interface ZitadelApp { - name: string | undefined; - config: ZitadelCoreProps; -} - -export async function initializeApp( - config: ZitadelCoreProps, - name?: string, -): Promise { - const app = { config, name }; - return app; -} - -export function getApps(): ZitadelApp[] { - return apps; -} - -export function getApp(name?: string): ZitadelApp | undefined { - return name - ? apps.find((a) => a.name === name) - : apps.length === 1 - ? apps[0] - : undefined; -} diff --git a/packages/zitadel-client/src/auth.ts b/packages/zitadel-client/src/auth.ts deleted file mode 100644 index 5b4b1e103..000000000 --- a/packages/zitadel-client/src/auth.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ZitadelApp } from "./app"; -import { authMiddleware } from "./middleware"; - -// const createClient = ( -// definition: CompatServiceDefinition, -// accessToken: string -// ) => { -// const channel = createChannel(process.env.ZITADEL_API_URL ?? ""); -// return createClientFactory() -// .use(authMiddleware(accessToken)) -// .create(definition, channel) as Client; -// }; - -export async function getAuth(app?: ZitadelApp) { - // return createClient( - // AuthServiceDefinition as CompatServiceDefinition, - // "" - // ); -} diff --git a/packages/zitadel-client/src/helpers.ts b/packages/zitadel-client/src/helpers.ts new file mode 100644 index 000000000..fbae0ed0a --- /dev/null +++ b/packages/zitadel-client/src/helpers.ts @@ -0,0 +1,8 @@ +import { createPromiseClient, Transport } from "@connectrpc/connect"; +import type { ServiceType } from "@bufbuild/protobuf"; + +export function createClientFor( + service: TService, +) { + return (transport: Transport) => createPromiseClient(service, transport); +} diff --git a/packages/zitadel-client/src/index.ts b/packages/zitadel-client/src/index.ts index a116f088b..b1dcfa8fe 100644 --- a/packages/zitadel-client/src/index.ts +++ b/packages/zitadel-client/src/index.ts @@ -1,5 +1,2 @@ -export { initializeApp, getApps } from "./app"; - -export { getAuth } from "./auth"; - -export type { ZitadelOptions } from "./app"; +export { NewAuthorizationBearerInterceptor } from "./interceptors"; +export type { PartialMessage, PlainMessage } from "@bufbuild/protobuf"; diff --git a/packages/zitadel-client/src/interceptors.test.ts b/packages/zitadel-client/src/interceptors.test.ts new file mode 100644 index 000000000..dd70a2c3f --- /dev/null +++ b/packages/zitadel-client/src/interceptors.test.ts @@ -0,0 +1,80 @@ +import { describe, expect, test, vitest } from "vitest"; +import { Int32Value, MethodKind, StringValue } from "@bufbuild/protobuf"; +import { createRouterTransport, HandlerContext } from "@connectrpc/connect"; +import { NewAuthorizationBearerInterceptor } from "./interceptors"; + +const TestService = { + typeName: "handwritten.TestService", + methods: { + unary: { + name: "Unary", + I: Int32Value, + O: StringValue, + kind: MethodKind.Unary, + }, + }, +} as const; + +describe("NewAuthorizationBearerInterceptor", () => { + const transport = { + interceptors: [NewAuthorizationBearerInterceptor("mytoken")], + }; + + test("injects the authorization token", async () => { + const handler = vitest.fn( + (request: Int32Value, context: HandlerContext) => { + return { value: request.value.toString() }; + }, + ); + + const service = createRouterTransport( + ({ service }) => { + service(TestService, { unary: handler }); + }, + { transport }, + ); + + await service.unary( + TestService, + TestService.methods.unary, + undefined, + undefined, + {}, + { value: 9001 }, + ); + + expect(handler).toBeCalled(); + expect(handler.mock.calls[0][1].requestHeader.get("Authorization")).toBe( + "Bearer mytoken", + ); + }); + + test("do not overwrite the previous authorization token", async () => { + const handler = vitest.fn( + (request: Int32Value, context: HandlerContext) => { + return { value: request.value.toString() }; + }, + ); + + const service = createRouterTransport( + ({ service }) => { + service(TestService, { unary: handler }); + }, + { transport }, + ); + + await service.unary( + TestService, + TestService.methods.unary, + undefined, + undefined, + { Authorization: "Bearer somethingelse" }, + { value: 9001 }, + ); + + expect(handler).toBeCalled(); + expect(handler.mock.calls[0][1].requestHeader.get("Authorization")).toBe( + "Bearer somethingelse", + ); + }); +}); diff --git a/packages/zitadel-client/src/interceptors.ts b/packages/zitadel-client/src/interceptors.ts new file mode 100644 index 000000000..9d719c7d7 --- /dev/null +++ b/packages/zitadel-client/src/interceptors.ts @@ -0,0 +1,16 @@ +import type { Interceptor } from "@connectrpc/connect"; + +/** + * Creates an interceptor that adds an Authorization header with a Bearer token. + * @param token + */ +export function NewAuthorizationBearerInterceptor(token: string): Interceptor { + return (next) => (req) => { + // TODO: I am not what is the intent of checking for the Authorization header + // and setting it if it is not present. + if (!req.header.get("Authorization")) { + req.header.set("Authorization", `Bearer ${token}`); + } + return next(req); + }; +} diff --git a/packages/zitadel-client/src/middleware.test.ts b/packages/zitadel-client/src/middleware.test.ts deleted file mode 100644 index f3ddb6f36..000000000 --- a/packages/zitadel-client/src/middleware.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { describe, expect, test, vitest } from "vitest"; - -import { - CallOptions, - ClientMiddlewareCall, - Metadata, - MethodDescriptor, -} from "nice-grpc-web"; -import { authMiddleware } from "./middleware"; - -describe("authMiddleware", () => { - const scenarios = [ - { - name: "should add authorization if metadata is undefined", - initialMetadata: undefined, - expectedMetadata: new Metadata().set( - "authorization", - "Bearer mock-token", - ), - token: "mock-token", - }, - { - name: "should add authorization if metadata exists but no authorization", - initialMetadata: new Metadata().set("other-key", "other-value"), - expectedMetadata: new Metadata() - .set("other-key", "other-value") - .set("authorization", "Bearer mock-token"), - token: "mock-token", - }, - { - name: "should not modify authorization if it already exists", - initialMetadata: new Metadata().set( - "authorization", - "Bearer initial-token", - ), - expectedMetadata: new Metadata().set( - "authorization", - "Bearer initial-token", - ), - token: "mock-token", - }, - ]; - - scenarios.forEach(({ name, initialMetadata, expectedMetadata, token }) => { - test(name, async () => { - const mockNext = vitest.fn().mockImplementation(async function* () {}); - const mockRequest = {}; - - const mockMethodDescriptor: MethodDescriptor = { - options: { idempotencyLevel: undefined }, - path: "", - requestStream: false, - responseStream: false, - }; - - const mockCall: ClientMiddlewareCall = { - method: mockMethodDescriptor, - requestStream: false, - responseStream: false, - request: mockRequest, - next: mockNext, - }; - const options: CallOptions = { - metadata: initialMetadata, - }; - - await authMiddleware(token)(mockCall, options).next(); - - expect(mockNext).toHaveBeenCalledTimes(1); - const actualMetadata = mockNext.mock.calls[0][1].metadata; - expect(actualMetadata?.get("authorization")).toEqual( - expectedMetadata.get("authorization"), - ); - }); - }); -}); diff --git a/packages/zitadel-client/src/middleware.ts b/packages/zitadel-client/src/middleware.ts deleted file mode 100644 index 6474311ad..000000000 --- a/packages/zitadel-client/src/middleware.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CallOptions, ClientMiddlewareCall, Metadata } from "nice-grpc-web"; - -export const authMiddleware = (token: string) => - async function* ( - call: ClientMiddlewareCall, - options: CallOptions, - ) { - if (!options.metadata?.has("authorization")) { - options.metadata ??= new Metadata(); - options.metadata?.set("authorization", `Bearer ${token}`); - } - - return yield* call.next(call.request, options); - }; diff --git a/packages/zitadel-client/src/v1.ts b/packages/zitadel-client/src/v1.ts new file mode 100644 index 000000000..5aef45075 --- /dev/null +++ b/packages/zitadel-client/src/v1.ts @@ -0,0 +1,11 @@ +import { createClientFor } from "./helpers"; + +import { AdminService } from "@zitadel/proto/zitadel/admin_connect"; +import { AuthService } from "@zitadel/proto/zitadel/auth_connect"; +import { ManagementService } from "@zitadel/proto/zitadel/management_connect"; +import { SystemService } from "@zitadel/proto/zitadel/system_connect"; + +export const createAdminServiceClient = createClientFor(AdminService); +export const createAuthServiceClient = createClientFor(AuthService); +export const createManagementServiceClient = createClientFor(ManagementService); +export const createSystemServiceClient = createClientFor(SystemService); diff --git a/packages/zitadel-client/src/v2beta.ts b/packages/zitadel-client/src/v2beta.ts new file mode 100644 index 000000000..ba718764a --- /dev/null +++ b/packages/zitadel-client/src/v2beta.ts @@ -0,0 +1,28 @@ +import type { PartialMessage } from "@bufbuild/protobuf"; + +import { createClientFor } from "./helpers"; +import { UserService } from "@zitadel/proto/zitadel/user/v2beta/user_service_connect"; +import { SettingsService } from "@zitadel/proto/zitadel/settings/v2beta/settings_service_connect"; +import { SessionService } from "@zitadel/proto/zitadel/session/v2beta/session_service_connect"; +import { OIDCService } from "@zitadel/proto/zitadel/oidc/v2beta/oidc_service_connect"; +import { OrganizationService } from "@zitadel/proto/zitadel/org/v2beta/org_service_connect"; +import { FeatureService } from "@zitadel/proto/zitadel/feature/v2beta/feature_service_connect"; +import type { RequestContext } from "@zitadel/proto/zitadel/object/v2beta/object_pb"; + +export const createUserServiceClient = createClientFor(UserService); +export const createSettingsServiceClient = createClientFor(SettingsService); +export const createSessionServiceClient = createClientFor(SessionService); +export const createOIDCServiceClient = createClientFor(OIDCService); +export const createOrganizationServiceClient = + createClientFor(OrganizationService); +export const createFeatureServiceClient = createClientFor(FeatureService); + +export function makeReqCtx( + orgId: string | undefined, +): PartialMessage { + return { + resourceOwner: orgId + ? { case: "orgId", value: orgId } + : { case: "instance", value: true }, + }; +} diff --git a/packages/zitadel-client/src/v3alpha.ts b/packages/zitadel-client/src/v3alpha.ts new file mode 100644 index 000000000..4a547cdf9 --- /dev/null +++ b/packages/zitadel-client/src/v3alpha.ts @@ -0,0 +1,8 @@ +import { createClientFor } from "./helpers"; +import { UserSchemaService } from "@zitadel/proto/zitadel/user/schema/v3alpha/user_schema_service_connect"; +import { UserService } from "@zitadel/proto/zitadel/user/v3alpha/user_service_connect"; +import { ActionService } from "@zitadel/proto/zitadel/action/v3alpha/action_service_connect"; + +export const createUserSchemaServiceClient = createClientFor(UserSchemaService); +export const createUserServiceClient = createClientFor(UserService); +export const createActionServiceClient = createClientFor(ActionService); diff --git a/packages/zitadel-client/tsup.config.ts b/packages/zitadel-client/tsup.config.ts index 2341f37cd..7dfce27c9 100644 --- a/packages/zitadel-client/tsup.config.ts +++ b/packages/zitadel-client/tsup.config.ts @@ -1,13 +1,13 @@ import { defineConfig, Options } from "tsup"; export default defineConfig((options: Options) => ({ - treeshake: true, - splitting: true, - publicDir: true, - entry: ["src/index.ts", "src/**/index.ts"], + entry: ["src/index.ts", "src/v1.ts", "src/v2beta.ts", "src/v3alpha.ts"], format: ["esm", "cjs"], + treeshake: false, + splitting: true, dts: true, - minify: true, + minify: false, clean: true, + sourcemap: true, ...options, })); diff --git a/packages/zitadel-next/package.json b/packages/zitadel-next/package.json index 3c84820b9..753ba264e 100644 --- a/packages/zitadel-next/package.json +++ b/packages/zitadel-next/package.json @@ -9,6 +9,9 @@ "files": [ "dist/**" ], + "publishConfig": { + "access": "public" + }, "scripts": { "build": "tsup", "test": "pnpm test:unit", @@ -19,18 +22,25 @@ "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.1", + "react": "^18.2.0" + }, + "dependencies": { + "next": "^14.2.1" + }, "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:*" + "zitadel-tailwind-config": "workspace:*" }, "peerDependencies": { "@zitadel/react": "workspace:*", - "@zitadel/server": "workspace:*", "next": "^14.2.3", "react": "18.2.0" }, diff --git a/packages/zitadel-next/turbo.json b/packages/zitadel-next/turbo.json index 9f5409262..44e5e99f1 100644 --- a/packages/zitadel-next/turbo.json +++ b/packages/zitadel-next/turbo.json @@ -6,7 +6,7 @@ }, "build": { "outputs": ["dist/**"], - "dependsOn": ["@zitadel/react#build", "@zitadel/server#build"] + "dependsOn": ["@zitadel/react#build"] } } } diff --git a/packages/zitadel-server/.eslintrc.js b/packages/zitadel-node/.eslintrc.cjs similarity index 54% rename from packages/zitadel-server/.eslintrc.js rename to packages/zitadel-node/.eslintrc.cjs index 8e247ab3c..51720b7c3 100644 --- a/packages/zitadel-server/.eslintrc.js +++ b/packages/zitadel-node/.eslintrc.cjs @@ -1,4 +1,5 @@ module.exports = { root: true, + // TODO: React is not used in the server package extends: ["zitadel"], }; diff --git a/packages/zitadel-server/.gitignore b/packages/zitadel-node/.gitignore similarity index 100% rename from packages/zitadel-server/.gitignore rename to packages/zitadel-node/.gitignore diff --git a/packages/zitadel-server/examples/app.ts b/packages/zitadel-node/examples/app.ts similarity index 100% rename from packages/zitadel-server/examples/app.ts rename to packages/zitadel-node/examples/app.ts diff --git a/packages/zitadel-node/package.json b/packages/zitadel-node/package.json new file mode 100644 index 000000000..1c8e4f870 --- /dev/null +++ b/packages/zitadel-node/package.json @@ -0,0 +1,61 @@ +{ + "name": "@zitadel/node", + "version": "0.0.0", + "type": "module", + "sideEffects": false, + "license": "MIT", + "exports": { + ".": { + "import": "./dist/index.js", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + }, + "./v1": { + "import": "./dist/v1.js", + "require": "./dist/v1.cjs", + "types": "./dist/v1.d.ts" + }, + "./v2beta": { + "import": "./dist/v2beta.js", + "require": "./dist/v2beta.cjs", + "types": "./dist/v2beta.d.ts" + }, + "./v3alpha": { + "import": "./dist/v3alpha.js", + "require": "./dist/v3alpha.cjs", + "types": "./dist/v3alpha.d.ts" + } + }, + "files": [ + "dist/**" + ], + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "tsup", + "test": "pnpm test:unit", + "test:watch": "pnpm test:unit:watch", + "test:unit": "vitest", + "test:unit:watch": "vitest --watch", + "dev": "tsup --watch", + "lint": "eslint \"src/**/*.ts*\"", + "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist && rm -rf src/proto" + }, + "peerDependencies": { + "@zitadel/client": "workspace:*" + }, + "dependencies": { + "@connectrpc/connect-node": "^1.4.0", + "jose": "^5.2.4" + }, + "devDependencies": { + "@zitadel/client": "workspace:*", + "@zitadel/tsconfig": "workspace:*", + "eslint": "^8.57.0", + "eslint-config-zitadel": "workspace:*", + "tsup": "^8.0.2", + "typescript": "^5.4.5", + "vitest": "^1.5.0" + } +} diff --git a/packages/zitadel-node/src/index.ts b/packages/zitadel-node/src/index.ts new file mode 100644 index 000000000..cd8c1d6cd --- /dev/null +++ b/packages/zitadel-node/src/index.ts @@ -0,0 +1,35 @@ +import { NewAuthorizationBearerInterceptor } from "@zitadel/client"; +import { + createGrpcWebTransport, + GrpcTransportOptions, +} from "@connectrpc/connect-node"; +import { importPKCS8, SignJWT } from "jose"; + +/** + * Create a server transport with the given token and configuration options. + * @param token + * @param opts + */ +export function createServerTransport( + token: string, + opts: GrpcTransportOptions, +) { + return createGrpcWebTransport({ + ...opts, + interceptors: [ + ...(opts.interceptors || []), + NewAuthorizationBearerInterceptor(token), + ], + }); +} + +export async function newSystemToken() { + return await new SignJWT({}) + .setProtectedHeader({ alg: "RS256" }) + .setIssuedAt() + .setExpirationTime("1h") + .setIssuer(process.env.ZITADEL_SYSTEM_API_USERID ?? "") + .setSubject(process.env.ZITADEL_SYSTEM_API_USERID ?? "") + .setAudience(process.env.ZITADEL_ISSUER ?? "") + .sign(await importPKCS8(process.env.ZITADEL_SYSTEM_API_KEY ?? "", "RS256")); +} diff --git a/packages/zitadel-server/tsconfig.json b/packages/zitadel-node/tsconfig.json similarity index 100% rename from packages/zitadel-server/tsconfig.json rename to packages/zitadel-node/tsconfig.json diff --git a/packages/zitadel-server/tsup.config.ts b/packages/zitadel-node/tsup.config.ts similarity index 65% rename from packages/zitadel-server/tsup.config.ts rename to packages/zitadel-node/tsup.config.ts index 2341f37cd..b978211b1 100644 --- a/packages/zitadel-server/tsup.config.ts +++ b/packages/zitadel-node/tsup.config.ts @@ -1,13 +1,13 @@ import { defineConfig, Options } from "tsup"; export default defineConfig((options: Options) => ({ - treeshake: true, + treeshake: false, splitting: true, - publicDir: true, - entry: ["src/index.ts", "src/**/index.ts"], + entry: ["src/index.ts"], format: ["esm", "cjs"], dts: true, - minify: true, + minify: false, clean: true, + sourcemap: true, ...options, })); diff --git a/packages/zitadel-node/turbo.json b/packages/zitadel-node/turbo.json new file mode 100644 index 000000000..eb8aafcdd --- /dev/null +++ b/packages/zitadel-node/turbo.json @@ -0,0 +1,11 @@ +{ + "extends": [ + "//" + ], + "pipeline": { + "build": { + "outputs": ["dist/**"], + "dependsOn": ["@zitadel/client#build"] + } + } +} diff --git a/packages/zitadel-react/package.json b/packages/zitadel-react/package.json index c90f151f4..eb8592a53 100644 --- a/packages/zitadel-react/package.json +++ b/packages/zitadel-react/package.json @@ -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" } } diff --git a/packages/zitadel-react/tsconfig.json b/packages/zitadel-react/tsconfig.json index 460eef71f..2200a65a4 100644 --- a/packages/zitadel-react/tsconfig.json +++ b/packages/zitadel-react/tsconfig.json @@ -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"] + } } diff --git a/packages/zitadel-server/buf.gen.yaml b/packages/zitadel-server/buf.gen.yaml deleted file mode 100644 index 0dbd909c2..000000000 --- a/packages/zitadel-server/buf.gen.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# buf.gen.yaml -version: v1 -managed: - enabled: true -plugins: - - name: ts - strategy: all - path: node_modules/ts-proto/protoc-gen-ts_proto - out: src/proto/server - opt: - - esModuleInterop=true - - env=node - - outputServices=nice-grpc - - outputServices=generic-definitions - - useExactTypes=false - # - plugin: buf.build/protocolbuffers/js - # out: src/app/proto/generated - # opt: import_style=commonjs,binary \ No newline at end of file diff --git a/packages/zitadel-server/package.json b/packages/zitadel-server/package.json deleted file mode 100644 index d5be42061..000000000 --- a/packages/zitadel-server/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@zitadel/server", - "version": "0.0.0", - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "type": "commonjs", - "sideEffects": false, - "license": "MIT", - "files": [ - "dist/**" - ], - "scripts": { - "generate": "buf generate https://github.com/zitadel/zitadel.git --path ./proto/zitadel", - "build": "tsup --dts", - "test": "pnpm test:unit", - "test:watch": "pnpm test:unit:watch", - "test:unit": "vitest", - "test:unit:watch": "vitest --watch", - "dev": "tsup --dts --watch", - "lint": "eslint \"src/**/*.ts*\"", - "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist && rm -rf src/proto" - }, - "devDependencies": { - "@bufbuild/buf": "^1.14.0", - "@zitadel/tsconfig": "workspace:*", - "eslint-config-zitadel": "workspace:*", - "ts-proto": "^1.139.0" - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "jose": "^4.13.1", - "long": "^5.2.1", - "nice-grpc": "2.0.1", - "nice-grpc-common": "^2.0.2", - "protobufjs": "^7.2.3" - } -} diff --git a/packages/zitadel-server/src/admin/admin.ts b/packages/zitadel-server/src/admin/admin.ts deleted file mode 100644 index 4db1119c6..000000000 --- a/packages/zitadel-server/src/admin/admin.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -import { createChannel, createClientFactory } from "nice-grpc"; -import { - AdminServiceClient, - AdminServiceDefinition, -} from "../proto/server/zitadel/admin"; -import { authMiddleware } from "../middleware"; - -const createClient = ( - definition: CompatServiceDefinition, - accessToken: string, -) => { - const channel = createChannel(process.env.ZITADEL_API_URL ?? ""); - return createClientFactory() - .use(authMiddleware(accessToken)) - .create(definition, channel) as Client; -}; - -export const getAdmin = () => - createClient( - AdminServiceDefinition as CompatServiceDefinition, - process.env.ZITADEL_ADMIN_TOKEN ?? "", - ); diff --git a/packages/zitadel-server/src/admin/index.ts b/packages/zitadel-server/src/admin/index.ts deleted file mode 100644 index 2dc46f523..000000000 --- a/packages/zitadel-server/src/admin/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./admin"; diff --git a/packages/zitadel-server/src/auth/auth.ts b/packages/zitadel-server/src/auth/auth.ts deleted file mode 100644 index b5553917b..000000000 --- a/packages/zitadel-server/src/auth/auth.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; -import { createChannel, createClientFactory } from "nice-grpc"; -import { - AuthServiceClient, - AuthServiceDefinition, - GetMyUserResponse, -} from "../proto/server/zitadel/auth"; -import { ZitadelServer, getServers } from "../server"; -import { authMiddleware } from "../middleware"; - -const createClient = ( - definition: CompatServiceDefinition, - apiUrl: string, - token: string, -) => { - if (!apiUrl) { - throw Error("ZITADEL_API_URL not set"); - } - - const channel = createChannel(process.env.ZITADEL_API_URL ?? ""); - return createClientFactory() - .use(authMiddleware(token)) - .create(definition, channel) as Client; -}; - -export const getAuth = (app?: string | ZitadelServer) => { - let config; - if (app && typeof app === "string") { - const apps = getServers(); - config = apps.find((a) => a.name === app)?.config; - } else if (app && typeof app === "object") { - config = app.config; - } - - if (!config) { - throw Error("No ZITADEL app found"); - } - - return createClient( - AuthServiceDefinition as CompatServiceDefinition, - config.apiUrl, - config.token, - ); -}; - -export async function getMyUser(): Promise { - const auth = await getAuth(); - const response = await auth.getMyUser({}); - return response; -} diff --git a/packages/zitadel-server/src/auth/index.ts b/packages/zitadel-server/src/auth/index.ts deleted file mode 100644 index 88b9bbd1d..000000000 --- a/packages/zitadel-server/src/auth/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./auth"; -export * as auth from "../proto/server/zitadel/auth"; diff --git a/packages/zitadel-server/src/index.ts b/packages/zitadel-server/src/index.ts deleted file mode 100644 index 50b13f8db..000000000 --- a/packages/zitadel-server/src/index.ts +++ /dev/null @@ -1,142 +0,0 @@ -import * as settings from "./v2/settings"; -import * as session from "./v2/session"; -import * as user from "./v2/user"; -import * as oidc from "./v2/oidc"; -import * as management from "./management"; -import * as auth from "./auth"; - -import * as login from "./proto/server/zitadel/settings/v2beta/login_settings"; -import * as password from "./proto/server/zitadel/settings/v2beta/password_settings"; -import * as legal from "./proto/server/zitadel/settings/v2beta/legal_settings"; - -export { - BrandingSettings, - Theme, -} from "./proto/server/zitadel/settings/v2beta/branding_settings"; - -export { - LoginSettings, - IdentityProvider, - IdentityProviderType, -} from "./proto/server/zitadel/settings/v2beta/login_settings"; - -export { - RequestChallenges, - Challenges, - Challenges_WebAuthN, -} from "./proto/server/zitadel/session/v2beta/challenge"; - -export { - GetAuthRequestRequest, - GetAuthRequestResponse, - CreateCallbackRequest, - CreateCallbackResponse, -} from "./proto/server/zitadel/oidc/v2beta/oidc_service"; - -export { - AuthRequest, - Prompt, -} from "./proto/server/zitadel/oidc/v2beta/authorization"; - -export { - Session, - Factors, -} from "./proto/server/zitadel/session/v2beta/session"; -export { - IDPInformation, - IDPLink, -} from "./proto/server/zitadel/user/v2beta/idp"; -export { - ListSessionsResponse, - GetSessionResponse, - CreateSessionResponse, - SetSessionResponse, - SetSessionRequest, - Checks, - DeleteSessionResponse, -} from "./proto/server/zitadel/session/v2beta/session_service"; -export { - GetPasswordComplexitySettingsResponse, - GetBrandingSettingsResponse, - GetLegalAndSupportSettingsResponse, - GetGeneralSettingsResponse, - GetLoginSettingsResponse, - GetLoginSettingsRequest, - GetActiveIdentityProvidersResponse, - GetActiveIdentityProvidersRequest, -} from "./proto/server/zitadel/settings/v2beta/settings_service"; -export { TextQueryMethod } from "./proto/server/zitadel/object/v2beta/object"; -export { - AddHumanUserResponse, - AddHumanUserRequest, - GetUserByIDResponse, - VerifyEmailResponse, - VerifyPasskeyRegistrationRequest, - VerifyPasskeyRegistrationResponse, - RegisterPasskeyRequest, - RegisterPasskeyResponse, - CreatePasskeyRegistrationLinkResponse, - CreatePasskeyRegistrationLinkRequest, - ListAuthenticationMethodTypesResponse, - ListAuthenticationMethodTypesRequest, - AuthenticationMethodType, - StartIdentityProviderIntentRequest, - StartIdentityProviderIntentResponse, - RetrieveIdentityProviderIntentRequest, - RetrieveIdentityProviderIntentResponse, - ListUsersRequest, - ListUsersResponse, - AddOTPEmailResponse, - AddOTPEmailRequest, - AddOTPSMSResponse, - AddOTPSMSRequest, - RegisterTOTPRequest, - RegisterTOTPResponse, - VerifyTOTPRegistrationRequest, - VerifyTOTPRegistrationResponse, - VerifyU2FRegistrationRequest, - VerifyU2FRegistrationResponse, - RegisterU2FResponse, - RegisterU2FRequest, -} from "./proto/server/zitadel/user/v2beta/user_service"; - -export { AuthFactor } from "./proto/server/zitadel/user"; - -export { - SetHumanPasswordResponse, - SetHumanPasswordRequest, - GetOrgByDomainGlobalResponse, - ListHumanAuthFactorsResponse, -} from "./proto/server/zitadel/management"; - -export * from "./proto/server/zitadel/idp"; -export { type LegalAndSupportSettings } from "./proto/server/zitadel/settings/v2beta/legal_settings"; -export { type PasswordComplexitySettings } from "./proto/server/zitadel/settings/v2beta/password_settings"; -export { type ResourceOwnerType } from "./proto/server/zitadel/settings/v2beta/settings"; -export { - type VerifyMyAuthFactorOTPResponse, - AddMyAuthFactorOTPResponse, -} from "./proto/server/zitadel/auth"; -import { - getServers, - initializeServer, - ZitadelServer, - ZitadelServerOptions, -} from "./server"; -export * from "./middleware"; - -export { - getServers, - ZitadelServer, - type ZitadelServerOptions, - initializeServer, - user, - management, - session, - settings, - login, - password, - legal, - oidc, - auth, -}; diff --git a/packages/zitadel-server/src/internal.ts b/packages/zitadel-server/src/internal.ts deleted file mode 100644 index 34ba3eecb..000000000 --- a/packages/zitadel-server/src/internal.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ZitadelServer } from "./server"; - -export const _servers = new Map(); diff --git a/packages/zitadel-server/src/management/index.ts b/packages/zitadel-server/src/management/index.ts deleted file mode 100644 index 5df1ddd31..000000000 --- a/packages/zitadel-server/src/management/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./management"; -export * as management from "../proto/server/zitadel/management"; -export * as policy from "../proto/server/zitadel/policy"; diff --git a/packages/zitadel-server/src/management/management.ts b/packages/zitadel-server/src/management/management.ts deleted file mode 100644 index 9585bcb66..000000000 --- a/packages/zitadel-server/src/management/management.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -import { createChannel, createClientFactory } from "nice-grpc"; -import { - ManagementServiceClient, - ManagementServiceDefinition, -} from "../proto/server/zitadel/management"; - -import { authMiddleware } from "../middleware"; -import { ZitadelServer, getServers } from "../server"; - -const createClient = ( - definition: CompatServiceDefinition, - apiUrl: string, - token: string, -) => { - if (!apiUrl) { - throw Error("ZITADEL_API_URL not set"); - } - - const channel = createChannel(process.env.ZITADEL_API_URL ?? ""); - return createClientFactory() - .use(authMiddleware(token)) - .create(definition, channel) as Client; -}; - -export const getManagement = (app?: string | ZitadelServer) => { - let config; - if (app && typeof app === "string") { - const apps = getServers(); - config = apps.find((a) => a.name === app)?.config; - } else if (app && typeof app === "object") { - config = app.config; - } - - if (!config) { - throw Error("No ZITADEL app found"); - } - - return createClient( - ManagementServiceDefinition as CompatServiceDefinition, - config.apiUrl, - config.token, - ); -}; diff --git a/packages/zitadel-server/src/middleware.test.ts b/packages/zitadel-server/src/middleware.test.ts deleted file mode 100644 index 270f97d9d..000000000 --- a/packages/zitadel-server/src/middleware.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { describe, expect, test, vitest } from "vitest"; - -import { - CallOptions, - ClientMiddlewareCall, - Metadata, - MethodDescriptor, -} from "nice-grpc"; -import { authMiddleware } from "./middleware"; - -describe("authMiddleware", () => { - const scenarios = [ - { - name: "should add authorization if metadata is undefined", - initialMetadata: undefined, - expectedMetadata: new Metadata().set( - "authorization", - "Bearer mock-token", - ), - token: "mock-token", - }, - { - name: "should add authorization if metadata exists but no authorization", - initialMetadata: new Metadata().set("other-key", "other-value"), - expectedMetadata: new Metadata() - .set("other-key", "other-value") - .set("authorization", "Bearer mock-token"), - token: "mock-token", - }, - { - name: "should not modify authorization if it already exists", - initialMetadata: new Metadata().set( - "authorization", - "Bearer initial-token", - ), - expectedMetadata: new Metadata().set( - "authorization", - "Bearer initial-token", - ), - token: "mock-token", - }, - ]; - - scenarios.forEach(({ name, initialMetadata, expectedMetadata, token }) => { - test(name, async () => { - const mockNext = vitest.fn().mockImplementation(async function* () {}); - const mockRequest = {}; - - const mockMethodDescriptor: MethodDescriptor = { - options: { idempotencyLevel: undefined }, - path: "", - requestStream: false, - responseStream: false, - }; - - const mockCall: ClientMiddlewareCall = { - method: mockMethodDescriptor, - requestStream: false, - responseStream: false, - request: mockRequest, - next: mockNext, - }; - const options: CallOptions = { - metadata: initialMetadata, - }; - - await authMiddleware(token)(mockCall, options).next(); - - expect(mockNext).toHaveBeenCalledTimes(1); - const actualMetadata = mockNext.mock.calls[0][1].metadata; - expect(actualMetadata?.get("authorization")).toEqual( - expectedMetadata.get("authorization"), - ); - }); - }); -}); diff --git a/packages/zitadel-server/src/middleware.ts b/packages/zitadel-server/src/middleware.ts deleted file mode 100644 index 13f115cd2..000000000 --- a/packages/zitadel-server/src/middleware.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - CallOptions, - ClientMiddleware, - ClientMiddlewareCall, - Metadata, -} from "nice-grpc"; - -export function authMiddleware(token: string): ClientMiddleware { - return async function* ( - call: ClientMiddlewareCall, - options: CallOptions, - ) { - if (!options.metadata?.has("authorization")) { - options.metadata ??= new Metadata(); - options.metadata?.set("authorization", `Bearer ${token}`); - } - - return yield* call.next(call.request, options); - }; -} - -export const orgMetadata = (orgId: string) => - new Metadata({ "x-zitadel-orgid": orgId }); diff --git a/packages/zitadel-server/src/server.ts b/packages/zitadel-server/src/server.ts deleted file mode 100644 index 1da04e746..000000000 --- a/packages/zitadel-server/src/server.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { createChannel, createClientFactory } from "nice-grpc"; -import { authMiddleware } from "./middleware"; -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -let apps: ZitadelServer[] = []; - -export interface ZitadelServerProps { - apiUrl: string; // process.env.ZITADEL_API_URL - token: string; -} - -export interface ZitadelServerOptions extends ZitadelServerProps { - name?: string; -} - -export function initializeServer( - config: ZitadelServerProps, - name?: string, -): ZitadelServer { - const server = new ZitadelServer(config, name); - return server; -} - -export class ZitadelServer { - name: string | undefined; - config: ZitadelServerProps; - - constructor(config: ZitadelServerProps, name?: string) { - if (name) { - this.name = name; - } - this.config = config; - } -} - -export function getServers(): ZitadelServer[] { - return apps; -} - -export function getServer(name?: string): ZitadelServer { - if (name) { - const found = apps.find((a) => a.name === name); - if (found) { - return found; - } else { - throw new Error("No server found"); - } - } else { - if (apps.length) { - return apps[0]; - } else { - throw new Error("No server found"); - } - } -} - -export const createClient = ( - definition: CompatServiceDefinition, - apiUrl: string, - token: string, -) => { - if (!apiUrl) { - throw Error("ZITADEL_API_URL not set"); - } - - const channel = createChannel(process.env.ZITADEL_API_URL ?? ""); - return createClientFactory() - .use(authMiddleware(token)) - .create(definition, channel) as Client; -}; diff --git a/packages/zitadel-server/src/system/index.ts b/packages/zitadel-server/src/system/index.ts deleted file mode 100644 index 2217a9552..000000000 --- a/packages/zitadel-server/src/system/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./system"; diff --git a/packages/zitadel-server/src/system/system.ts b/packages/zitadel-server/src/system/system.ts deleted file mode 100644 index dcd5f3e47..000000000 --- a/packages/zitadel-server/src/system/system.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; -import { importPKCS8, SignJWT } from "jose"; - -import { createChannel, createClientFactory } from "nice-grpc"; -import { - SystemServiceClient, - SystemServiceDefinition, -} from "../proto/server/zitadel/system"; -import { authMiddleware } from "../middleware"; - -const createSystemClient = ( - definition: CompatServiceDefinition, - accessToken: string, -) => { - const channel = createChannel(process.env.ZITADEL_SYSTEM_API_URL ?? ""); - return createClientFactory() - .use(authMiddleware(accessToken)) - .create(definition, channel) as Client; -}; - -export const getSystem = async () => { - const token = await new SignJWT({}) - .setProtectedHeader({ alg: "RS256" }) - .setIssuedAt() - .setExpirationTime("1h") - .setIssuer(process.env.ZITADEL_SYSTEM_API_USERID ?? "") - .setSubject(process.env.ZITADEL_SYSTEM_API_USERID ?? "") - .setAudience(process.env.ZITADEL_ISSUER ?? "") - .sign(await importPKCS8(process.env.ZITADEL_SYSTEM_API_KEY ?? "", "RS256")); - - return createSystemClient( - SystemServiceDefinition as CompatServiceDefinition, - token, - ); -}; diff --git a/packages/zitadel-server/src/v2/oidc/index.ts b/packages/zitadel-server/src/v2/oidc/index.ts deleted file mode 100644 index 11bff5c4c..000000000 --- a/packages/zitadel-server/src/v2/oidc/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./oidc"; -export * from "../../proto/server/zitadel/oidc/v2beta/oidc_service"; diff --git a/packages/zitadel-server/src/v2/oidc/oidc.ts b/packages/zitadel-server/src/v2/oidc/oidc.ts deleted file mode 100644 index d8a1adcb7..000000000 --- a/packages/zitadel-server/src/v2/oidc/oidc.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -import { ZitadelServer, createClient, getServers } from "../../server"; -import { OIDCServiceClient, OIDCServiceDefinition } from "."; - -export const getOidc = (server?: string | ZitadelServer) => { - let config; - if (server && typeof server === "string") { - const apps = getServers(); - config = apps.find((a) => a.name === server)?.config; - } else if (server && typeof server === "object") { - config = server.config; - } - - if (!config) { - throw Error("No ZITADEL server found"); - } - - return createClient( - OIDCServiceDefinition as CompatServiceDefinition, - config.apiUrl, - config.token, - ); -}; diff --git a/packages/zitadel-server/src/v2/session/index.ts b/packages/zitadel-server/src/v2/session/index.ts deleted file mode 100644 index c11476a6c..000000000 --- a/packages/zitadel-server/src/v2/session/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./session"; -export * from "../../proto/server/zitadel/session/v2beta/session"; diff --git a/packages/zitadel-server/src/v2/session/session.ts b/packages/zitadel-server/src/v2/session/session.ts deleted file mode 100644 index 2a4a3602c..000000000 --- a/packages/zitadel-server/src/v2/session/session.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -import { - SessionServiceClient, - SessionServiceDefinition, -} from "../../proto/server/zitadel/session/v2beta/session_service"; - -import { ZitadelServer, createClient, getServers } from "../../server"; - -export const getSession = (server?: string | ZitadelServer) => { - let config; - if (server && typeof server === "string") { - const apps = getServers(); - config = apps.find((a) => a.name === server)?.config; - } else if (server && typeof server === "object") { - config = server.config; - } - - if (!config) { - throw Error("No ZITADEL server found"); - } - - return createClient( - SessionServiceDefinition as CompatServiceDefinition, - config.apiUrl, - config.token, - ); -}; diff --git a/packages/zitadel-server/src/v2/settings/index.ts b/packages/zitadel-server/src/v2/settings/index.ts deleted file mode 100644 index 7fdbfd0f9..000000000 --- a/packages/zitadel-server/src/v2/settings/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./settings"; -export * from "../../proto/server/zitadel/settings/v2beta/settings"; diff --git a/packages/zitadel-server/src/v2/settings/settings.ts b/packages/zitadel-server/src/v2/settings/settings.ts deleted file mode 100644 index 4305b38ee..000000000 --- a/packages/zitadel-server/src/v2/settings/settings.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -import { - SettingsServiceClient, - SettingsServiceDefinition, -} from "../../proto/server/zitadel/settings/v2beta/settings_service"; - -import { ZitadelServer, createClient, getServers } from "../../server"; - -export const getSettings = (server?: string | ZitadelServer) => { - let config; - if (server && typeof server === "string") { - const apps = getServers(); - config = apps.find((a) => a.name === server)?.config; - } else if (server && typeof server === "object") { - config = server.config; - } - - if (!config) { - throw Error("No ZITADEL server found"); - } - - return createClient( - SettingsServiceDefinition as CompatServiceDefinition, - config.apiUrl, - config.token, - ); -}; diff --git a/packages/zitadel-server/src/v2/user/index.ts b/packages/zitadel-server/src/v2/user/index.ts deleted file mode 100644 index 75d422bcf..000000000 --- a/packages/zitadel-server/src/v2/user/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./user"; -export * from "../../proto/server/zitadel/user/v2beta/user"; diff --git a/packages/zitadel-server/src/v2/user/user.ts b/packages/zitadel-server/src/v2/user/user.ts deleted file mode 100644 index 211b07788..000000000 --- a/packages/zitadel-server/src/v2/user/user.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions"; - -import { - UserServiceClient, - UserServiceDefinition, -} from "../../proto/server/zitadel/user/v2beta/user_service"; - -import { ZitadelServer, createClient, getServers } from "../../server"; - -export const getUser = (server?: string | ZitadelServer) => { - let config; - if (server && typeof server === "string") { - const apps = getServers(); - config = apps.find((a) => a.name === server)?.config; - } else if (server && typeof server === "object") { - config = server.config; - } - - if (!config) { - throw Error("No ZITADEL server found"); - } - - return createClient( - UserServiceDefinition as CompatServiceDefinition, - config.apiUrl, - config.token, - ); -}; diff --git a/packages/zitadel-server/turbo.json b/packages/zitadel-server/turbo.json deleted file mode 100644 index f2c9bca63..000000000 --- a/packages/zitadel-server/turbo.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "extends": [ - "//" - ], - "pipeline": { - "generate": { - "outputs": [ - "src/proto/**" - ], - "cache": true - }, - "build": { - "outputs": [ - "dist/**" - ], - "dependsOn": [ - "generate" - ] - } - } -} \ No newline at end of file diff --git a/packages/zitadel-tailwind-config/package.json b/packages/zitadel-tailwind-config/package.json index fcb92a7b8..157e7d984 100644 --- a/packages/zitadel-tailwind-config/package.json +++ b/packages/zitadel-tailwind-config/package.json @@ -4,7 +4,7 @@ "private": true, "main": "index.js", "devDependencies": { - "tailwindcss": "^3.2.4", - "@tailwindcss/forms": "0.5.3" + "tailwindcss": "^3.4.3", + "@tailwindcss/forms": "^0.5.7" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51e52a690..07ef69157 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,14 +6,17 @@ settings: overrides: '@typescript-eslint/parser': ^7.9.0 + '@bufbuild/protobuf': ^1.8.0 + '@connectrpc/connect': ^1.4.0 + '@connectrpc/connect-node': ^1.4.0 importers: .: devDependencies: '@changesets/cli': - specifier: ^2.22.0 - version: 2.25.2 + specifier: ^2.27.1 + version: 2.27.4 '@vitejs/plugin-react': specifier: ^4.2.1 version: 4.2.1(vite@5.2.11(@types/node@18.11.9)(sass@1.77.1)) @@ -45,26 +48,26 @@ importers: apps/login: dependencies: '@headlessui/react': - specifier: ^1.7.14 - version: 1.7.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.7.18 + version: 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@heroicons/react': - specifier: 2.0.13 - version: 2.0.13(react@18.3.1) + specifier: 2.1.3 + version: 2.1.3(react@18.3.1) '@tailwindcss/forms': - specifier: 0.5.3 - version: 0.5.3(tailwindcss@3.2.4(postcss@8.4.21)) + specifier: 0.5.7 + version: 0.5.7(tailwindcss@3.2.4(postcss@8.4.21)) '@vercel/analytics': - specifier: ^1.0.0 - version: 1.0.0(react@18.3.1) + specifier: ^1.2.2 + version: 1.3.1(next@14.2.3(@babel/core@7.24.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.1))(react@18.3.1) '@zitadel/client': specifier: workspace:* version: link:../../packages/zitadel-client + '@zitadel/proto': + specifier: workspace:* + version: link:../../packages/zitadel-proto '@zitadel/react': specifier: workspace:* version: link:../../packages/zitadel-react - '@zitadel/server': - specifier: workspace:* - version: link:../../packages/zitadel-server clsx: specifier: 1.2.1 version: 1.2.1 @@ -270,9 +273,6 @@ importers: '@types/react': specifier: ^17.0.13 version: 17.0.52 - '@zitadel/server': - specifier: workspace:* - version: link:../zitadel-server '@zitadel/tsconfig': specifier: workspace:* version: link:../zitadel-tsconfig @@ -289,12 +289,43 @@ importers: specifier: workspace:* version: link:../zitadel-tailwind-config + packages/zitadel-node: + dependencies: + '@connectrpc/connect-node': + specifier: ^1.4.0 + version: 1.4.0(@bufbuild/protobuf@1.9.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.9.0)) + jose: + specifier: ^5.2.4 + version: 5.3.0 + devDependencies: + '@zitadel/client': + specifier: workspace:* + version: link:../zitadel-client + '@zitadel/tsconfig': + specifier: workspace:* + version: link:../zitadel-tsconfig + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-config-zitadel: + specifier: workspace:* + version: link:../eslint-config-zitadel + tsup: + specifier: ^8.0.2 + version: 8.0.2(postcss@8.4.38)(typescript@5.4.5) + typescript: + specifier: ^5.4.5 + version: 5.4.5 + vitest: + specifier: ^1.5.0 + version: 1.6.0(@types/node@18.11.9)(jsdom@24.0.0)(sass@1.77.1) + packages/zitadel-prettier-config: {} packages/zitadel-proto: dependencies: '@bufbuild/protobuf': - specifier: ^1.9.0 + specifier: ^1.8.0 version: 1.9.0 devDependencies: '@bufbuild/buf': @@ -304,15 +335,15 @@ importers: packages/zitadel-react: dependencies: react: - specifier: 18.2.0 - version: 18.2.0 + specifier: ^18.2.0 + version: 18.3.1 devDependencies: '@testing-library/jest-dom': specifier: ^6.4.5 version: 6.4.5(vitest@1.6.0(@types/node@18.11.9)(jsdom@24.0.0)(sass@1.77.1)) '@testing-library/react': specifier: ^14.0.0 - version: 14.0.0(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + version: 14.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react': specifier: ^18.2.17 version: 18.2.17 @@ -344,45 +375,14 @@ importers: specifier: workspace:* version: link:../zitadel-tailwind-config - packages/zitadel-server: - dependencies: - jose: - specifier: ^4.13.1 - version: 4.13.1 - long: - specifier: ^5.2.1 - version: 5.2.1 - nice-grpc: - specifier: 2.0.1 - version: 2.0.1 - nice-grpc-common: - specifier: ^2.0.2 - version: 2.0.2 - protobufjs: - specifier: ^7.2.3 - version: 7.2.3 - devDependencies: - '@bufbuild/buf': - specifier: ^1.14.0 - version: 1.15.0 - '@zitadel/tsconfig': - specifier: workspace:* - version: link:../zitadel-tsconfig - eslint-config-zitadel: - specifier: workspace:* - version: link:../eslint-config-zitadel - ts-proto: - specifier: ^1.139.0 - version: 1.146.0 - packages/zitadel-tailwind-config: devDependencies: '@tailwindcss/forms': - specifier: 0.5.3 - version: 0.5.3(tailwindcss@3.2.4(postcss@8.4.38)) + specifier: ^0.5.7 + version: 0.5.7(tailwindcss@3.4.3) tailwindcss: - specifier: ^3.2.4 - version: 3.2.4(postcss@8.4.38) + specifier: ^3.4.3 + version: 3.4.3 packages/zitadel-tsconfig: {} @@ -391,6 +391,10 @@ packages: '@adobe/css-tools@4.3.3': resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==, tarball: https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==, tarball: https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz} + engines: {node: '>=10'} + '@ampproject/remapping@2.2.1': resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==, tarball: https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz} engines: {node: '>=6.0.0'} @@ -616,66 +620,76 @@ packages: '@bufbuild/protobuf@1.9.0': resolution: {integrity: sha512-W7gp8Q/v1NlCZLsv8pQ3Y0uCu/SHgXOVFK+eUluUKWXmsb6VHkpNx0apdOWWcDbB9sJoKeP8uPrjmehJz6xETQ==, tarball: https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.9.0.tgz} - '@changesets/apply-release-plan@6.1.2': - resolution: {integrity: sha512-H8TV9E/WtJsDfoDVbrDGPXmkZFSv7W2KLqp4xX4MKZXshb0hsQZUNowUa8pnus9qb/5OZrFFRVsUsDCVHNW/AQ==} + '@changesets/apply-release-plan@7.0.2': + resolution: {integrity: sha512-lRdN9c8e2zbzSWTGK3HzlNATPWETBy6tMvf4MENUzb7OQD3kFQ+dVKCJtj42pLWRjLn2flbLofEK04k92GEttg==, tarball: https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.2.tgz} - '@changesets/assemble-release-plan@5.2.2': - resolution: {integrity: sha512-B1qxErQd85AeZgZFZw2bDKyOfdXHhG+X5S+W3Da2yCem8l/pRy4G/S7iOpEcMwg6lH8q2ZhgbZZwZ817D+aLuQ==} + '@changesets/assemble-release-plan@6.0.1': + resolution: {integrity: sha512-VXKjqGomnj4evJ/B6ENUFMxV+EV/LDkdWl2+8NjCcGo4Rn/aogjofCDLWbWEhtjtgLUdwvlsoydibIDOf/abvA==, tarball: https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.1.tgz} - '@changesets/changelog-git@0.1.13': - resolution: {integrity: sha512-zvJ50Q+EUALzeawAxax6nF2WIcSsC5PwbuLeWkckS8ulWnuPYx8Fn/Sjd3rF46OzeKA8t30loYYV6TIzp4DIdg==} + '@changesets/changelog-git@0.2.0': + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==, tarball: https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz} - '@changesets/cli@2.25.2': - resolution: {integrity: sha512-ACScBJXI3kRyMd2R8n8SzfttDHi4tmKSwVwXBazJOylQItSRSF4cGmej2E4FVf/eNfGy6THkL9GzAahU9ErZrA==} + '@changesets/cli@2.27.4': + resolution: {integrity: sha512-X3Nd9cBoyuykjmMJnRFHik26UoA5y4ikhds4BJE0IGKpnIvkV8gRqyZE6Tcmc3zuS5GXfCmGnyJXVwxe89uX5A==, tarball: https://registry.npmjs.org/@changesets/cli/-/cli-2.27.4.tgz} hasBin: true - '@changesets/config@2.2.0': - resolution: {integrity: sha512-GGaokp3nm5FEDk/Fv2PCRcQCOxGKKPRZ7prcMqxEr7VSsG75MnChQE8plaW1k6V8L2bJE+jZWiRm19LbnproOw==} + '@changesets/config@3.0.0': + resolution: {integrity: sha512-o/rwLNnAo/+j9Yvw9mkBQOZySDYyOr/q+wptRLcAVGlU6djOeP9v1nlalbL9MFsobuBVQbZCTp+dIzdq+CLQUA==, tarball: https://registry.npmjs.org/@changesets/config/-/config-3.0.0.tgz} - '@changesets/errors@0.1.4': - resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==, tarball: https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz} - '@changesets/get-dependents-graph@1.3.4': - resolution: {integrity: sha512-+C4AOrrFY146ydrgKOo5vTZfj7vetNu1tWshOID+UjPUU9afYGDXI8yLnAeib1ffeBXV3TuGVcyphKpJ3cKe+A==} + '@changesets/get-dependents-graph@2.0.0': + resolution: {integrity: sha512-cafUXponivK4vBgZ3yLu944mTvam06XEn2IZGjjKc0antpenkYANXiiE6GExV/yKdsCnE8dXVZ25yGqLYZmScA==, tarball: https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.0.0.tgz} - '@changesets/get-release-plan@3.0.15': - resolution: {integrity: sha512-W1tFwxE178/en+zSj/Nqbc3mvz88mcdqUMJhRzN1jDYqN3QI4ifVaRF9mcWUU+KI0gyYEtYR65tour690PqTcA==} + '@changesets/get-release-plan@4.0.1': + resolution: {integrity: sha512-1zojjyxeIzIHA/zWXZ3XYxKySBDtbTP9PS6EZLrM0r1luq8Oy7U0zBq/I9NX77qVJV9EF3cO4KP5pfRHorSLTg==, tarball: https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.1.tgz} - '@changesets/get-version-range-type@0.3.2': - resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==, tarball: https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz} - '@changesets/git@1.5.0': - resolution: {integrity: sha512-Xo8AT2G7rQJSwV87c8PwMm6BAc98BnufRMsML7m7Iw8Or18WFvFmxqG5aOL5PBvhgq9KrKvaeIBNIymracSuHg==} + '@changesets/git@3.0.0': + resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==, tarball: https://registry.npmjs.org/@changesets/git/-/git-3.0.0.tgz} - '@changesets/logger@0.0.5': - resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + '@changesets/logger@0.1.0': + resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==, tarball: https://registry.npmjs.org/@changesets/logger/-/logger-0.1.0.tgz} - '@changesets/parse@0.3.15': - resolution: {integrity: sha512-3eDVqVuBtp63i+BxEWHPFj2P1s3syk0PTrk2d94W9JD30iG+OER0Y6n65TeLlY8T2yB9Fvj6Ev5Gg0+cKe/ZUA==} + '@changesets/parse@0.4.0': + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==, tarball: https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz} - '@changesets/pre@1.0.13': - resolution: {integrity: sha512-jrZc766+kGZHDukjKhpBXhBJjVQMied4Fu076y9guY1D3H622NOw8AQaLV3oQsDtKBTrT2AUFjt9Z2Y9Qx+GfA==} + '@changesets/pre@2.0.0': + resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==, tarball: https://registry.npmjs.org/@changesets/pre/-/pre-2.0.0.tgz} - '@changesets/read@0.5.8': - resolution: {integrity: sha512-eYaNfxemgX7f7ELC58e7yqQICW5FB7V+bd1lKt7g57mxUrTveYME+JPaBPpYx02nP53XI6CQp6YxnR9NfmFPKw==} + '@changesets/read@0.6.0': + resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==, tarball: https://registry.npmjs.org/@changesets/read/-/read-0.6.0.tgz} + + '@changesets/should-skip-package@0.1.0': + resolution: {integrity: sha512-FxG6Mhjw7yFStlSM7Z0Gmg3RiyQ98d/9VpQAZ3Fzr59dCOM9G6ZdYbjiSAt0XtFr9JR5U2tBaJWPjrkGGc618g==, tarball: https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.0.tgz} '@changesets/types@4.1.0': - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==, tarball: https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz} - '@changesets/types@5.2.0': - resolution: {integrity: sha512-km/66KOqJC+eicZXsm2oq8A8bVTSpkZJ60iPV/Nl5Z5c7p9kk8xxh6XGRTlnludHldxOOfudhnDN2qPxtHmXzA==} + '@changesets/types@6.0.0': + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==, tarball: https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz} - '@changesets/write@0.2.2': - resolution: {integrity: sha512-kCYNHyF3xaId1Q/QE+DF3UTrHTyg3Cj/f++T8S8/EkC+jh1uK2LFnM9h+EzV+fsmnZDrs7r0J4LLpeI/VWC5Hg==} + '@changesets/write@0.3.1': + resolution: {integrity: sha512-SyGtMXzH3qFqlHKcvFY2eX+6b0NGiFcNav8AFsYwy5l8hejOeoeTDemu5Yjmke2V5jpzY+pBvM0vCCQ3gdZpfw==, tarball: https://registry.npmjs.org/@changesets/write/-/write-0.3.1.tgz} '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==, tarball: https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz} engines: {node: '>=0.1.90'} + '@connectrpc/connect-node@1.4.0': + resolution: {integrity: sha512-0ANnrr6SvsjevsWEgdzHy7BaHkluZyS6s4xNoVt7RBHFR5V/kT9lPokoIbYUOU9JHzdRgTaS3x5595mwUsu15g==, tarball: https://registry.npmjs.org/@connectrpc/connect-node/-/connect-node-1.4.0.tgz} + engines: {node: '>=16.0.0'} + peerDependencies: + '@bufbuild/protobuf': ^1.8.0 + '@connectrpc/connect': ^1.4.0 + '@connectrpc/connect@1.4.0': resolution: {integrity: sha512-vZeOkKaAjyV4+RH3+rJZIfDFJAfr+7fyYr6sLDKbYX3uuTVszhFe9/YKf5DNqrDb5cKdKVlYkGn6DTDqMitAnA==, tarball: https://registry.npmjs.org/@connectrpc/connect/-/connect-1.4.0.tgz} peerDependencies: - '@bufbuild/protobuf': ^1.4.2 + '@bufbuild/protobuf': ^1.8.0 '@cypress/request@3.0.1': resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==, tarball: https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz} @@ -978,6 +992,10 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==, tarball: https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==, tarball: https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz} + engines: {node: '>=14'} + '@grpc/grpc-js@1.8.13': resolution: {integrity: sha512-iY3jsdfbc0ARoCLFvbvUB8optgyb0r1XLPb142u+QtgBcKJYkCIFt3Fd/881KqjLYWjsBJF57N3b8Eop9NDfUA==} engines: {node: ^8.13.0 || >=10.10.0} @@ -993,15 +1011,15 @@ packages: '@hapi/topo@5.1.0': resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - '@headlessui/react@1.7.14': - resolution: {integrity: sha512-znzdq9PG8rkwcu9oQ2FwIy0ZFtP9Z7ycS+BAqJ3R5EIqC/0bJGvhT7193rFf+45i9nnPsYvCQVW4V/bB9Xc+gA==} + '@headlessui/react@1.7.19': + resolution: {integrity: sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==, tarball: https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz} engines: {node: '>=10'} peerDependencies: react: ^16 || ^17 || ^18 react-dom: ^16 || ^17 || ^18 - '@heroicons/react@2.0.13': - resolution: {integrity: sha512-iSN5XwmagrnirWlYEWNPdCDj9aRYVD/lnK3JlsC9/+fqGF80k8C7rl+1HCvBX0dBoagKqOFBs6fMhJJ1hOg1EQ==} + '@heroicons/react@2.1.3': + resolution: {integrity: sha512-fEcPfo4oN345SoqdlCDdSa4ivjaKbk0jTd+oubcgNxnNgAfzysfwWfQUr+51wigiWHQQRiZNd1Ao0M5Y3M2EGg==, tarball: https://registry.npmjs.org/@heroicons/react/-/react-2.1.3.tgz} peerDependencies: react: '>= 16' @@ -1061,10 +1079,10 @@ packages: resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, tarball: https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz} '@manypkg/find-root@1.1.0': - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==, tarball: https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz} '@manypkg/get-packages@1.1.3': - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==, tarball: https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz} '@mapbox/node-pre-gyp@1.0.10': resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==} @@ -1281,11 +1299,20 @@ packages: '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==, tarball: https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz} - '@tailwindcss/forms@0.5.3': - resolution: {integrity: sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==} + '@tailwindcss/forms@0.5.7': + resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==, tarball: https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz} peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' + '@tanstack/react-virtual@3.5.0': + resolution: {integrity: sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==, tarball: https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@tanstack/virtual-core@3.5.0': + resolution: {integrity: sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==, tarball: https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz} + '@testing-library/dom@10.1.0': resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==, tarball: https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz} engines: {node: '>=18'} @@ -1351,9 +1378,6 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==, tarball: https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz} - '@types/is-ci@3.0.0': - resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} - '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==, tarball: https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz} @@ -1367,7 +1391,7 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} '@types/node@12.20.55': - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==, tarball: https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz} '@types/node@18.11.9': resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} @@ -1399,8 +1423,8 @@ packages: '@types/scheduler@0.16.2': resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - '@types/semver@6.2.3': - resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==, tarball: https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz} '@types/sinonjs__fake-timers@8.1.1': resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==, tarball: https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz} @@ -1451,10 +1475,16 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==, tarball: https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz} - '@vercel/analytics@1.0.0': - resolution: {integrity: sha512-RQmj7pv82JwGDHrnKeRc6TtSw2U7rWNubc2IH0ernTzWTj02yr9zvIYiYJeztsBzrJtWv7m8Nz6vxxb+cdEtJw==} + '@vercel/analytics@1.3.1': + resolution: {integrity: sha512-xhSlYgAuJ6Q4WQGkzYTLmXwhYl39sWjoMA3nHxfkvG+WdBT25c563a7QhwwKivEOZtPJXifYHR1m2ihoisbWyA==, tarball: https://registry.npmjs.org/@vercel/analytics/-/analytics-1.3.1.tgz} peerDependencies: - react: ^16.8||^17||^18 + next: '>= 13' + react: ^18 || ^19 + peerDependenciesMeta: + next: + optional: true + react: + optional: true '@vercel/git-hooks@1.0.0': resolution: {integrity: sha512-OxDFAAdyiJ/H0b8zR9rFCu3BIb78LekBXOphOYG3snV4ULhKFX387pBPpqZ9HLiRTejBWBxYEahkw79tuIgdAA==} @@ -1544,11 +1574,11 @@ packages: engines: {node: '>=8'} ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, tarball: https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz} engines: {node: '>=12'} ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, tarball: https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz} engines: {node: '>=4'} ansi-styles@4.3.0: @@ -1584,7 +1614,7 @@ packages: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, tarball: https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz} @@ -1712,7 +1742,7 @@ packages: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==, tarball: https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz} better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==, tarball: https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz} engines: {node: '>=4'} binary-extensions@2.2.0: @@ -1736,7 +1766,7 @@ packages: engines: {node: '>=8'} breakword@1.0.5: - resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==} + resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==, tarball: https://registry.npmjs.org/breakword/-/breakword-1.0.5.tgz} browserslist@4.21.5: resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} @@ -1788,7 +1818,7 @@ packages: engines: {node: '>= 6'} camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==, tarball: https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz} engines: {node: '>=8'} camelcase-keys@7.0.2: @@ -1796,7 +1826,7 @@ packages: engines: {node: '>=12'} camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, tarball: https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz} engines: {node: '>=6'} camelcase@6.3.0: @@ -1821,7 +1851,7 @@ packages: engines: {node: '>=4'} chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, tarball: https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz} engines: {node: '>=4'} chalk@3.0.0: @@ -1833,7 +1863,7 @@ packages: engines: {node: '>=10'} chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==, tarball: https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz} check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==, tarball: https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz} @@ -1854,6 +1884,10 @@ packages: resolution: {integrity: sha512-lVZdhvbEudris15CLytp2u6Y0p5EKfztae9Fqa189MfNmln9F33XuH69v5fvNfiRN5/0eAUz2yJL3mo+nhaRKg==} engines: {node: '>=8'} + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, tarball: https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz} + engines: {node: '>=8'} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -1879,10 +1913,10 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==, tarball: https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz} cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==, tarball: https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz} cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -1892,7 +1926,7 @@ packages: engines: {node: '>=12'} clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, tarball: https://registry.npmjs.org/clone/-/clone-1.0.4.tgz} engines: {node: '>=0.8'} clsx@1.2.1: @@ -1963,7 +1997,7 @@ packages: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==, tarball: https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz} cross-spawn@5.1.0: - resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==, tarball: https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz} cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -1985,16 +2019,16 @@ packages: resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} csv-generate@3.4.3: - resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} + resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==, tarball: https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz} csv-parse@4.16.3: - resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} + resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==, tarball: https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz} csv-stringify@5.6.5: - resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} + resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==, tarball: https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz} csv@5.5.3: - resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} + resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==, tarball: https://registry.npmjs.org/csv/-/csv-5.5.3.tgz} engines: {node: '>= 0.1.90'} cypress@13.9.0: @@ -2078,7 +2112,7 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==, tarball: https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz} define-data-property@1.1.0: resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==, tarball: https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz} @@ -2120,7 +2154,7 @@ packages: engines: {node: '>=6'} detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==, tarball: https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz} engines: {node: '>=8'} detect-libc@1.0.3: @@ -2393,7 +2427,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, tarball: https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz} engines: {node: '>=4'} hasBin: true @@ -2446,10 +2480,10 @@ packages: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==, tarball: https://registry.npmjs.org/extend/-/extend-3.0.2.tgz} extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==, tarball: https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz} external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==, tarball: https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz} engines: {node: '>=4'} extract-zip@2.0.1: @@ -2468,6 +2502,10 @@ packages: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==, tarball: https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz} + engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -2501,7 +2539,7 @@ packages: engines: {node: '>=10'} find-yarn-workspace-root2@1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==, tarball: https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz} flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} @@ -2544,11 +2582,11 @@ packages: resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz} engines: {node: '>=6 <7 || >=8'} fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz} engines: {node: '>=6 <7 || >=8'} fs-extra@9.1.0: @@ -2690,7 +2728,7 @@ packages: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz} grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==, tarball: https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz} graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, tarball: https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz} @@ -2752,7 +2790,7 @@ packages: engines: {node: '>= 0.4'} hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==, tarball: https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz} hosted-git-info@4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} @@ -2779,7 +2817,7 @@ packages: engines: {node: '>= 14'} human-id@1.0.2: - resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==, tarball: https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz} human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==, tarball: https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz} @@ -2798,7 +2836,7 @@ packages: engines: {node: '>=16.17.0'} iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, tarball: https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz} engines: {node: '>=0.10.0'} iconv-lite@0.6.3: @@ -2997,7 +3035,7 @@ packages: engines: {node: '>= 0.4'} is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==, tarball: https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz} engines: {node: '>=4'} is-symbol@1.0.4: @@ -3029,7 +3067,7 @@ packages: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==, tarball: https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz} engines: {node: '>=0.10.0'} is-wsl@2.2.0: @@ -3057,14 +3095,21 @@ packages: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==, tarball: https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz} engines: {node: '>=14'} + jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==, tarball: https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz} + hasBin: true + joi@17.9.2: resolution: {integrity: sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==} jose@4.13.1: resolution: {integrity: sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==} + jose@5.3.0: + resolution: {integrity: sha512-IChe9AtAE79ru084ow8jzkN2lNrG3Ntfiv65Cvj9uOCE2m5LNsdHG+9EbxWxAoWRF9TgDOqLN5jm08++owDVRg==, tarball: https://registry.npmjs.org/jose/-/jose-5.3.0.tgz} + joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==, tarball: https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz} engines: {node: '>=10'} js-base64@3.7.5: @@ -3077,7 +3122,7 @@ packages: resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==, tarball: https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz} js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, tarball: https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz} hasBin: true js-yaml@4.1.0: @@ -3126,7 +3171,7 @@ packages: hasBin: true jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, tarball: https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz} jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, tarball: https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz} @@ -3144,7 +3189,7 @@ packages: engines: {node: '>=0.10.0'} kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==, tarball: https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz} engines: {node: '>=6'} language-subtag-registry@0.3.22: @@ -3169,6 +3214,10 @@ packages: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==, tarball: https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz} + engines: {node: '>=10'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -3200,7 +3249,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} load-yaml-file@0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==, tarball: https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz} engines: {node: '>=6'} local-pkg@0.5.0: @@ -3228,7 +3277,7 @@ packages: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, tarball: https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz} lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -3259,7 +3308,7 @@ packages: engines: {node: 14 || >=16.14} lru-cache@4.1.5: - resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==, tarball: https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz} lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, tarball: https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz} @@ -3300,7 +3349,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} meow@6.1.1: - resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} + resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==, tarball: https://registry.npmjs.org/meow/-/meow-6.1.1.tgz} engines: {node: '>=8'} merge-stream@2.0.0: @@ -3335,7 +3384,7 @@ packages: engines: {node: '>=4'} mini-svg-data-uri@1.4.4: - resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==, tarball: https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz} hasBin: true minimatch@3.1.2: @@ -3369,7 +3418,7 @@ packages: engines: {node: '>= 8'} mixme@0.5.4: - resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} + resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==, tarball: https://registry.npmjs.org/mixme/-/mixme-0.5.4.tgz} engines: {node: '>= 8.0.0'} mkdirp@1.0.4: @@ -3469,7 +3518,7 @@ packages: hasBin: true normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==, tarball: https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz} normalize-package-data@3.0.3: resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} @@ -3573,21 +3622,21 @@ packages: engines: {node: '>= 0.8.0'} os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==, tarball: https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz} engines: {node: '>=0.10.0'} ospath@1.2.2: resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==, tarball: https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz} outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==, tarball: https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz} p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==, tarball: https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz} engines: {node: '>=8'} p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, tarball: https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz} engines: {node: '>=6'} p-limit@3.1.0: @@ -3599,7 +3648,7 @@ packages: engines: {node: '>=18'} p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, tarball: https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz} engines: {node: '>=8'} p-locate@5.0.0: @@ -3607,7 +3656,7 @@ packages: engines: {node: '>=10'} p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==, tarball: https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz} engines: {node: '>=6'} p-map@4.0.0: @@ -3619,7 +3668,7 @@ packages: engines: {node: '>=12'} p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, tarball: https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz} engines: {node: '>=6'} parent-module@1.0.1: @@ -3695,7 +3744,7 @@ packages: engines: {node: '>=0.10.0'} pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==, tarball: https://registry.npmjs.org/pify/-/pify-4.0.1.tgz} engines: {node: '>=6'} pirates@4.0.5: @@ -3703,7 +3752,7 @@ packages: engines: {node: '>= 6'} pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, tarball: https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz} engines: {node: '>=8'} pkg-types@1.1.1: @@ -3719,6 +3768,12 @@ packages: peerDependencies: postcss: ^8.0.0 + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==, tarball: https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + postcss-js@4.0.1: resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} @@ -3755,6 +3810,12 @@ packages: peerDependencies: postcss: ^8.2.14 + postcss-nested@6.0.1: + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==, tarball: https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + postcss-selector-parser@6.0.11: resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} engines: {node: '>=4'} @@ -3775,7 +3836,7 @@ packages: engines: {node: ^10 || ^12 || >=14} preferred-pm@3.0.3: - resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} + resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==, tarball: https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.0.3.tgz} engines: {node: '>=10'} prelude-ls@1.2.1: @@ -3834,7 +3895,7 @@ packages: hasBin: true pseudomap@1.0.2: - resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==, tarball: https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz} psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} @@ -3869,7 +3930,7 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==, tarball: https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz} engines: {node: '>=8'} quick-lru@5.1.1: @@ -3912,7 +3973,7 @@ packages: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==, tarball: https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz} engines: {node: '>=8'} read-pkg-up@8.0.0: @@ -3920,7 +3981,7 @@ packages: engines: {node: '>=12'} read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==, tarball: https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz} engines: {node: '>=8'} read-pkg@6.0.0: @@ -3928,7 +3989,7 @@ packages: engines: {node: '>=12'} read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==, tarball: https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz} engines: {node: '>=6'} readable-stream@3.6.2: @@ -3970,7 +4031,7 @@ packages: engines: {node: '>=0.10.0'} require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==, tarball: https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz} requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, tarball: https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz} @@ -3980,7 +4041,7 @@ packages: engines: {node: '>=4'} resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, tarball: https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz} engines: {node: '>=8'} resolve@1.22.1: @@ -4082,6 +4143,9 @@ packages: engines: {node: '>=10'} hasBin: true + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==, tarball: https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz} + set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -4098,7 +4162,7 @@ packages: engines: {node: '>= 0.4'} shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==, tarball: https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz} engines: {node: '>=0.10.0'} shebang-command@2.0.0: @@ -4106,7 +4170,7 @@ packages: engines: {node: '>=8'} shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==, tarball: https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz} engines: {node: '>=0.10.0'} shebang-regex@3.0.0: @@ -4158,7 +4222,7 @@ packages: engines: {node: '>=12'} smartwrap@2.0.2: - resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} + resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==, tarball: https://registry.npmjs.org/smartwrap/-/smartwrap-2.0.2.tgz} engines: {node: '>=6'} hasBin: true @@ -4178,7 +4242,7 @@ packages: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} spawndamnit@2.0.0: - resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==, tarball: https://registry.npmjs.org/spawndamnit/-/spawndamnit-2.0.0.tgz} spdx-correct@3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} @@ -4196,7 +4260,7 @@ packages: resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, tarball: https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz} sshpk@1.17.0: resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==, tarball: https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz} @@ -4222,7 +4286,7 @@ packages: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} stream-transform@2.1.3: - resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} + resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==, tarball: https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz} streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, tarball: https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz} @@ -4273,7 +4337,7 @@ packages: engines: {node: '>=8'} strip-ansi@7.0.1: - resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==, tarball: https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz} engines: {node: '>=12'} strip-bom@3.0.0: @@ -4321,6 +4385,11 @@ packages: engines: {node: '>=8'} hasBin: true + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==, tarball: https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4356,6 +4425,11 @@ packages: peerDependencies: postcss: ^8.0.9 + tailwindcss@3.4.3: + resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==, tarball: https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz} + engines: {node: '>=14.0.0'} + hasBin: true + tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==, tarball: https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz} engines: {node: '>=6'} @@ -4365,7 +4439,7 @@ packages: engines: {node: '>=10'} term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==, tarball: https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz} engines: {node: '>=8'} text-table@0.2.0: @@ -4402,7 +4476,7 @@ packages: engines: {node: '>=14.0.0'} tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==, tarball: https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz} engines: {node: '>=0.6.0'} tmp@0.2.1: @@ -4443,7 +4517,7 @@ packages: hasBin: true trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==, tarball: https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz} engines: {node: '>=8'} trim-newlines@4.1.1: @@ -4508,7 +4582,7 @@ packages: optional: true tty-table@4.1.6: - resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==} + resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==, tarball: https://registry.npmjs.org/tty-table/-/tty-table-4.1.6.tgz} engines: {node: '>=8.0.0'} hasBin: true @@ -4561,7 +4635,7 @@ packages: engines: {node: '>=4'} type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==, tarball: https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz} engines: {node: '>=10'} type-fest@0.20.2: @@ -4573,11 +4647,11 @@ packages: engines: {node: '>=10'} type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==, tarball: https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz} engines: {node: '>=8'} type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==, tarball: https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz} engines: {node: '>=8'} type-fest@1.4.0: @@ -4629,8 +4703,12 @@ packages: undefsafe@2.0.5: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==, tarball: https://registry.npmjs.org/undici/-/undici-5.28.4.tgz} + engines: {node: '>=14.0'} + universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, tarball: https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz} engines: {node: '>= 4.0.0'} universalify@0.2.0: @@ -4758,7 +4836,7 @@ packages: hasBin: true wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, tarball: https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz} webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, tarball: https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz} @@ -4799,10 +4877,10 @@ packages: resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==, tarball: https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz} which-module@2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==, tarball: https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz} which-pm@2.0.0: - resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} + resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==, tarball: https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz} engines: {node: '>=8.15'} which-typed-array@1.1.11: @@ -4814,7 +4892,7 @@ packages: engines: {node: '>= 0.4'} which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==, tarball: https://registry.npmjs.org/which/-/which-1.3.1.tgz} hasBin: true which@2.0.2: @@ -4873,14 +4951,14 @@ packages: engines: {node: '>=0.4'} y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==, tarball: https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz} y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} yallist@2.1.2: - resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==, tarball: https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz} yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, tarball: https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz} @@ -4897,7 +4975,7 @@ packages: engines: {node: '>= 14'} yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==, tarball: https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz} engines: {node: '>=6'} yargs-parser@20.2.9: @@ -4909,7 +4987,7 @@ packages: engines: {node: '>=12'} yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==, tarball: https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz} engines: {node: '>=8'} yargs@16.2.0: @@ -4935,6 +5013,8 @@ snapshots: '@adobe/css-tools@4.3.3': {} + '@alloc/quick-lru@5.2.0': {} + '@ampproject/remapping@2.2.1': dependencies: '@jridgewell/gen-mapping': 0.3.3 @@ -5166,13 +5246,14 @@ snapshots: '@bufbuild/protobuf@1.9.0': {} - '@changesets/apply-release-plan@6.1.2': + '@changesets/apply-release-plan@7.0.2': dependencies: '@babel/runtime': 7.22.3 - '@changesets/config': 2.2.0 - '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 1.5.0 - '@changesets/types': 5.2.0 + '@changesets/config': 3.0.0 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.0 + '@changesets/should-skip-package': 0.1.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -5180,136 +5261,144 @@ snapshots: outdent: 0.5.0 prettier: 2.8.0 resolve-from: 5.0.0 - semver: 5.7.1 + semver: 7.6.2 - '@changesets/assemble-release-plan@5.2.2': + '@changesets/assemble-release-plan@6.0.1': dependencies: '@babel/runtime': 7.22.3 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/types': 5.2.0 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/should-skip-package': 0.1.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - semver: 5.7.1 + semver: 7.6.2 - '@changesets/changelog-git@0.1.13': + '@changesets/changelog-git@0.2.0': dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 6.0.0 - '@changesets/cli@2.25.2': + '@changesets/cli@2.27.4': dependencies: - '@babel/runtime': 7.20.1 - '@changesets/apply-release-plan': 6.1.2 - '@changesets/assemble-release-plan': 5.2.2 - '@changesets/changelog-git': 0.1.13 - '@changesets/config': 2.2.0 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/get-release-plan': 3.0.15 - '@changesets/git': 1.5.0 - '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 - '@changesets/write': 0.2.2 + '@babel/runtime': 7.22.3 + '@changesets/apply-release-plan': 7.0.2 + '@changesets/assemble-release-plan': 6.0.1 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.0 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/get-release-plan': 4.0.1 + '@changesets/git': 3.0.0 + '@changesets/logger': 0.1.0 + '@changesets/pre': 2.0.0 + '@changesets/read': 0.6.0 + '@changesets/should-skip-package': 0.1.0 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.1 '@manypkg/get-packages': 1.1.3 - '@types/is-ci': 3.0.0 - '@types/semver': 6.2.3 + '@types/semver': 7.5.8 ansi-colors: 4.1.3 chalk: 2.4.2 + ci-info: 3.9.0 enquirer: 2.3.6 external-editor: 3.1.0 fs-extra: 7.0.1 human-id: 1.0.2 - is-ci: 3.0.1 meow: 6.1.1 outdent: 0.5.0 p-limit: 2.3.0 preferred-pm: 3.0.3 resolve-from: 5.0.0 - semver: 5.7.1 + semver: 7.6.2 spawndamnit: 2.0.0 term-size: 2.2.1 tty-table: 4.1.6 - '@changesets/config@2.2.0': + '@changesets/config@3.0.0': dependencies: - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/logger': 0.0.5 - '@changesets/types': 5.2.0 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/logger': 0.1.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.5 - '@changesets/errors@0.1.4': + '@changesets/errors@0.2.0': dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@1.3.4': + '@changesets/get-dependents-graph@2.0.0': dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 - semver: 5.7.1 + semver: 7.6.2 - '@changesets/get-release-plan@3.0.15': + '@changesets/get-release-plan@4.0.1': dependencies: '@babel/runtime': 7.22.3 - '@changesets/assemble-release-plan': 5.2.2 - '@changesets/config': 2.2.0 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 + '@changesets/assemble-release-plan': 6.0.1 + '@changesets/config': 3.0.0 + '@changesets/pre': 2.0.0 + '@changesets/read': 0.6.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - '@changesets/get-version-range-type@0.3.2': {} + '@changesets/get-version-range-type@0.4.0': {} - '@changesets/git@1.5.0': + '@changesets/git@3.0.0': dependencies: '@babel/runtime': 7.22.3 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 + micromatch: 4.0.5 spawndamnit: 2.0.0 - '@changesets/logger@0.0.5': + '@changesets/logger@0.1.0': dependencies: chalk: 2.4.2 - '@changesets/parse@0.3.15': + '@changesets/parse@0.4.0': dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 6.0.0 js-yaml: 3.14.1 - '@changesets/pre@1.0.13': + '@changesets/pre@2.0.0': dependencies: '@babel/runtime': 7.22.3 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.5.8': + '@changesets/read@0.6.0': dependencies: '@babel/runtime': 7.22.3 - '@changesets/git': 1.5.0 - '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.15 - '@changesets/types': 5.2.0 + '@changesets/git': 3.0.0 + '@changesets/logger': 0.1.0 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 + '@changesets/should-skip-package@0.1.0': + dependencies: + '@babel/runtime': 7.22.3 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + '@changesets/types@4.1.0': {} - '@changesets/types@5.2.0': {} + '@changesets/types@6.0.0': {} - '@changesets/write@0.2.2': + '@changesets/write@0.3.1': dependencies: '@babel/runtime': 7.22.3 - '@changesets/types': 5.2.0 + '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 prettier: 2.8.0 @@ -5317,6 +5406,12 @@ snapshots: '@colors/colors@1.5.0': optional: true + '@connectrpc/connect-node@1.4.0(@bufbuild/protobuf@1.9.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.9.0))': + dependencies: + '@bufbuild/protobuf': 1.9.0 + '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.9.0) + undici: 5.28.4 + '@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.9.0)': dependencies: '@bufbuild/protobuf': 1.9.0 @@ -5510,6 +5605,8 @@ snapshots: '@eslint/js@8.57.0': {} + '@fastify/busboy@2.1.1': {} + '@grpc/grpc-js@1.8.13': dependencies: '@grpc/proto-loader': 0.7.6 @@ -5529,13 +5626,14 @@ snapshots: dependencies: '@hapi/hoek': 9.3.0 - '@headlessui/react@1.7.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@headlessui/react@1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: + '@tanstack/react-virtual': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) client-only: 0.0.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@heroicons/react@2.0.13(react@18.3.1)': + '@heroicons/react@2.1.3(react@18.3.1)': dependencies: react: 18.3.1 @@ -5776,15 +5874,23 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.4.1 - '@tailwindcss/forms@0.5.3(tailwindcss@3.2.4(postcss@8.4.21))': + '@tailwindcss/forms@0.5.7(tailwindcss@3.2.4(postcss@8.4.21))': dependencies: mini-svg-data-uri: 1.4.4 tailwindcss: 3.2.4(postcss@8.4.21) - '@tailwindcss/forms@0.5.3(tailwindcss@3.2.4(postcss@8.4.38))': + '@tailwindcss/forms@0.5.7(tailwindcss@3.4.3)': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.2.4(postcss@8.4.38) + tailwindcss: 3.4.3 + + '@tanstack/react-virtual@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/virtual-core': 3.5.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/virtual-core@3.5.0': {} '@testing-library/dom@10.1.0': dependencies: @@ -5821,13 +5927,13 @@ snapshots: optionalDependencies: vitest: 1.6.0(@types/node@18.11.9)(jsdom@24.0.0)(sass@1.77.1) - '@testing-library/react@14.0.0(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + '@testing-library/react@14.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.20.1 '@testing-library/dom': 9.3.0 '@types/react-dom': 18.2.7 - react: 18.2.0 - react-dom: 18.3.1(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) '@testing-library/react@15.0.7(@types/react@18.2.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -5864,10 +5970,6 @@ snapshots: '@types/estree@1.0.5': {} - '@types/is-ci@3.0.0': - dependencies: - ci-info: 3.6.2 - '@types/json5@0.0.29': {} '@types/long@4.0.2': {} @@ -5914,7 +6016,7 @@ snapshots: '@types/scheduler@0.16.2': {} - '@types/semver@6.2.3': {} + '@types/semver@7.5.8': {} '@types/sinonjs__fake-timers@8.1.1': {} @@ -5971,8 +6073,11 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vercel/analytics@1.0.0(react@18.3.1)': + '@vercel/analytics@1.3.1(next@14.2.3(@babel/core@7.24.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.1))(react@18.3.1)': dependencies: + server-only: 0.0.1 + optionalDependencies: + next: 14.2.3(@babel/core@7.24.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.1) react: 18.3.1 '@vercel/git-hooks@1.0.0': {} @@ -6424,6 +6529,8 @@ snapshots: ci-info@3.6.2: {} + ci-info@3.9.0: {} + clean-stack@2.2.0: {} clean-stack@4.2.0: @@ -7356,6 +7463,14 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.5 + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -7943,6 +8058,8 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jiti@1.21.0: {} + joi@17.9.2: dependencies: '@hapi/hoek': 9.3.0 @@ -7953,6 +8070,8 @@ snapshots: jose@4.13.1: {} + jose@5.3.0: {} + joycon@3.1.1: {} js-base64@3.7.5: {} @@ -8061,6 +8180,8 @@ snapshots: lilconfig@2.0.6: {} + lilconfig@2.1.0: {} + lines-and-columns@1.2.4: {} lint-staged@13.0.3(enquirer@2.3.6): @@ -8664,7 +8785,7 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.6 - postcss-import@14.1.0(postcss@8.4.38): + postcss-import@15.1.0(postcss@8.4.38): dependencies: postcss: 8.4.38 postcss-value-parser: 4.2.0 @@ -8688,13 +8809,6 @@ snapshots: optionalDependencies: postcss: 8.4.21 - postcss-load-config@3.1.4(postcss@8.4.38): - dependencies: - lilconfig: 2.0.6 - yaml: 1.10.2 - optionalDependencies: - postcss: 8.4.38 - postcss-load-config@4.0.1(postcss@8.4.38): dependencies: lilconfig: 2.0.6 @@ -8707,7 +8821,7 @@ snapshots: postcss: 8.4.21 postcss-selector-parser: 6.0.11 - postcss-nested@6.0.0(postcss@8.4.38): + postcss-nested@6.0.1(postcss@8.4.38): dependencies: postcss: 8.4.38 postcss-selector-parser: 6.0.11 @@ -9094,6 +9208,8 @@ snapshots: semver@7.6.2: {} + server-only@0.0.1: {} + set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -9384,6 +9500,16 @@ snapshots: pirates: 4.0.5 ts-interface-checker: 0.1.13 + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.3.10 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.5 + ts-interface-checker: 0.1.13 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -9438,31 +9564,30 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.2.4(postcss@8.4.38): + tailwindcss@3.4.3: dependencies: + '@alloc/quick-lru': 5.2.0 arg: 5.0.2 chokidar: 3.5.3 - color-name: 1.1.4 - detective: 5.2.1 didyoumean: 1.2.2 dlv: 1.1.3 - fast-glob: 3.2.12 + fast-glob: 3.3.2 glob-parent: 6.0.2 is-glob: 4.0.3 - lilconfig: 2.0.6 + jiti: 1.21.0 + lilconfig: 2.1.0 micromatch: 4.0.5 normalize-path: 3.0.0 object-hash: 3.0.0 - picocolors: 1.0.0 + picocolors: 1.0.1 postcss: 8.4.38 - postcss-import: 14.1.0(postcss@8.4.38) + postcss-import: 15.1.0(postcss@8.4.38) postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 3.1.4(postcss@8.4.38) - postcss-nested: 6.0.0(postcss@8.4.38) + postcss-load-config: 4.0.1(postcss@8.4.38) + postcss-nested: 6.0.1(postcss@8.4.38) postcss-selector-parser: 6.0.11 - postcss-value-parser: 4.2.0 - quick-lru: 5.1.1 - resolve: 1.22.1 + resolve: 1.22.6 + sucrase: 3.35.0 transitivePeerDependencies: - ts-node @@ -9745,6 +9870,10 @@ snapshots: undefsafe@2.0.5: {} + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + universalify@0.1.2: {} universalify@0.2.0: {}