command adr, prettier import config

This commit is contained in:
peintnermax
2024-09-05 13:48:33 +02:00
parent 7549f6819f
commit 28dde6d696
53 changed files with 234 additions and 225 deletions

View File

@@ -1,5 +0,0 @@
{
"printWidth": 125,
"trailingComma": "all",
"plugins": ["prettier-plugin-organize-imports"]
}

View File

@@ -1,9 +1,9 @@
import { getAllSessionCookieIds } from "@/lib/cookies";
import { getBrandingSettings, listSessions } from "@/lib/zitadel"; import { getBrandingSettings, listSessions } from "@/lib/zitadel";
import DynamicTheme from "@/ui/DynamicTheme";
import SessionsList from "@/ui/SessionsList";
import { UserPlusIcon } from "@heroicons/react/24/outline"; import { UserPlusIcon } from "@heroicons/react/24/outline";
import Link from "next/link"; import Link from "next/link";
import SessionsList from "@/ui/SessionsList";
import DynamicTheme from "@/ui/DynamicTheme";
import { getAllSessionCookieIds } from "@/lib/cookies";
async function loadSessions() { async function loadSessions() {
const ids = await getAllSessionCookieIds(); const ids = await getAllSessionCookieIds();

View File

@@ -4,7 +4,6 @@ import {
getBrandingSettings, getBrandingSettings,
getSession, getSession,
listAuthenticationMethodTypes, listAuthenticationMethodTypes,
sessionService,
} from "@/lib/zitadel"; } from "@/lib/zitadel";
import Alert from "@/ui/Alert"; import Alert from "@/ui/Alert";
import BackButton from "@/ui/BackButton"; import BackButton from "@/ui/BackButton";
@@ -28,7 +27,7 @@ export default async function Page({
loginName?: string, loginName?: string,
organization?: string, organization?: string,
) { ) {
return loadMostRecentSession(sessionService, { return loadMostRecentSession({
loginName, loginName,
organization, organization,
}).then((session) => { }).then((session) => {

View File

@@ -6,7 +6,6 @@ import {
getSession, getSession,
getUserByID, getUserByID,
listAuthenticationMethodTypes, listAuthenticationMethodTypes,
sessionService,
} from "@/lib/zitadel"; } from "@/lib/zitadel";
import Alert from "@/ui/Alert"; import Alert from "@/ui/Alert";
import BackButton from "@/ui/BackButton"; import BackButton from "@/ui/BackButton";
@@ -30,7 +29,7 @@ export default async function Page({
loginName?: string, loginName?: string,
organization?: string, organization?: string,
) { ) {
return loadMostRecentSession(sessionService, { return loadMostRecentSession({
loginName, loginName,
organization, organization,
}).then((session) => { }).then((session) => {

View File

@@ -1,3 +1,4 @@
import { loadMostRecentSession } from "@/lib/session";
import { import {
addOTPEmail, addOTPEmail,
addOTPSMS, addOTPSMS,
@@ -11,9 +12,8 @@ import { Button, ButtonVariants } from "@/ui/Button";
import DynamicTheme from "@/ui/DynamicTheme"; import DynamicTheme from "@/ui/DynamicTheme";
import TOTPRegister from "@/ui/TOTPRegister"; import TOTPRegister from "@/ui/TOTPRegister";
import UserAvatar from "@/ui/UserAvatar"; import UserAvatar from "@/ui/UserAvatar";
import Link from "next/link";
import { RegisterTOTPResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { RegisterTOTPResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { loadMostRecentSession } from "@/lib/session"; import Link from "next/link";
export default async function Page({ export default async function Page({
searchParams, searchParams,

View File

@@ -1,13 +1,13 @@
import { getMostRecentCookieWithLoginname } from "@/lib/cookies";
import { createCallback, getBrandingSettings, getSession } from "@/lib/zitadel"; import { createCallback, getBrandingSettings, getSession } from "@/lib/zitadel";
import DynamicTheme from "@/ui/DynamicTheme"; import DynamicTheme from "@/ui/DynamicTheme";
import UserAvatar from "@/ui/UserAvatar"; import UserAvatar from "@/ui/UserAvatar";
import { create } from "@zitadel/client"; import { create } from "@zitadel/client";
import { redirect } from "next/navigation";
import { import {
CreateCallbackRequestSchema, CreateCallbackRequestSchema,
SessionSchema, SessionSchema,
} from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb"; } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
import { getMostRecentCookieWithLoginname } from "@/lib/cookies"; import { redirect } from "next/navigation";
async function loadSession(loginName: string, authRequestId?: string) { async function loadSession(loginName: string, authRequestId?: string) {
const recent = await getMostRecentCookieWithLoginname({ loginName }); const recent = await getMostRecentCookieWithLoginname({ loginName });

View File

@@ -1,13 +1,10 @@
import "@/styles/globals.scss"; import "@/styles/globals.scss";
import { AddressBar } from "@/ui/AddressBar"; import { AddressBar } from "@/ui/AddressBar";
import { GlobalNav } from "@/ui/GlobalNav"; 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 ThemeProvider from "@/ui/ThemeProvider";
import Theme from "@/ui/Theme"; import Theme from "@/ui/Theme";
import ThemeProvider from "@/ui/ThemeProvider";
import { Analytics } from "@vercel/analytics/react";
import { Lato } from "next/font/google";
const lato = Lato({ const lato = Lato({
weight: ["400", "700", "900"], weight: ["400", "700", "900"],

View File

@@ -7,6 +7,8 @@ export const dynamic = "force-dynamic";
export const revalidate = false; export const revalidate = false;
export const fetchCache = "default-no-store"; export const fetchCache = "default-no-store";
import { getAllSessions } from "@/lib/cookies";
import { idpTypeToSlug } from "@/lib/idp";
import { import {
createCallback, createCallback,
getActiveIdentityProviders, getActiveIdentityProviders,
@@ -15,16 +17,13 @@ import {
listSessions, listSessions,
startIdentityProviderFlow, startIdentityProviderFlow,
} from "@/lib/zitadel"; } from "@/lib/zitadel";
import { NextRequest, NextResponse } from "next/server"; import { create } from "@zitadel/client";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { import {
AuthRequest, AuthRequest,
Prompt, Prompt,
} from "@zitadel/proto/zitadel/oidc/v2/authorization_pb"; } from "@zitadel/proto/zitadel/oidc/v2/authorization_pb";
import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { idpTypeToSlug } from "@/lib/idp"; import { NextRequest, NextResponse } from "next/server";
import { create } from "@zitadel/client";
import { getAllSessions } from "@/lib/cookies";
async function loadSessions(ids: string[]): Promise<Session[]> { async function loadSessions(ids: string[]): Promise<Session[]> {
const response = await listSessions( const response = await listSessions(

View File

@@ -26,13 +26,20 @@ function setSessionHttpOnlyCookie<T>(sessions: SessionCookie<T>[]) {
}); });
} }
export async function addSessionToCookie<T>(session: SessionCookie<T>, cleanup: boolean = false): Promise<any> { export async function addSessionToCookie<T>(
session: SessionCookie<T>,
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies(); const cookiesList = cookies();
const stringifiedCookie = cookiesList.get("sessions"); const stringifiedCookie = cookiesList.get("sessions");
let currentSessions: SessionCookie<T>[] = stringifiedCookie?.value ? JSON.parse(stringifiedCookie?.value) : []; let currentSessions: SessionCookie<T>[] = stringifiedCookie?.value
? JSON.parse(stringifiedCookie?.value)
: [];
const index = currentSessions.findIndex((s) => s.loginName === session.loginName); const index = currentSessions.findIndex(
(s) => s.loginName === session.loginName,
);
if (index > -1) { if (index > -1) {
currentSessions[index] = session; currentSessions[index] = session;
@@ -51,11 +58,17 @@ export async function addSessionToCookie<T>(session: SessionCookie<T>, cleanup:
} }
} }
export async function updateSessionCookie<T>(id: string, session: SessionCookie<T>, cleanup: boolean = false): Promise<any> { export async function updateSessionCookie<T>(
id: string,
session: SessionCookie<T>,
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies(); const cookiesList = cookies();
const stringifiedCookie = cookiesList.get("sessions"); const stringifiedCookie = cookiesList.get("sessions");
const sessions: SessionCookie<T>[] = stringifiedCookie?.value ? JSON.parse(stringifiedCookie?.value) : [session]; const sessions: SessionCookie<T>[] = stringifiedCookie?.value
? JSON.parse(stringifiedCookie?.value)
: [session];
const foundIndex = sessions.findIndex((session) => session.id === id); const foundIndex = sessions.findIndex((session) => session.id === id);
@@ -75,11 +88,16 @@ export async function updateSessionCookie<T>(id: string, session: SessionCookie<
} }
} }
export async function removeSessionFromCookie<T>(session: SessionCookie<T>, cleanup: boolean = false): Promise<any> { export async function removeSessionFromCookie<T>(
session: SessionCookie<T>,
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies(); const cookiesList = cookies();
const stringifiedCookie = cookiesList.get("sessions"); const stringifiedCookie = cookiesList.get("sessions");
const sessions: SessionCookie<T>[] = stringifiedCookie?.value ? JSON.parse(stringifiedCookie?.value) : [session]; const sessions: SessionCookie<T>[] = stringifiedCookie?.value
? JSON.parse(stringifiedCookie?.value)
: [session];
const reducedSessions = sessions.filter((s) => s.id !== session.id); const reducedSessions = sessions.filter((s) => s.id !== session.id);
if (cleanup) { if (cleanup) {
@@ -101,7 +119,10 @@ export async function getMostRecentSessionCookie<T>(): Promise<any> {
const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value); const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value);
const latest = sessions.reduce((prev, current) => { const latest = sessions.reduce((prev, current) => {
return new Date(prev.changeDate).getTime() > new Date(current.changeDate).getTime() ? prev : current; return new Date(prev.changeDate).getTime() >
new Date(current.changeDate).getTime()
? prev
: current;
}); });
return latest; return latest;
@@ -124,7 +145,9 @@ export async function getSessionCookieById<T>({
const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value); const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value);
const found = sessions.find((s) => const found = sessions.find((s) =>
organization ? s.organization === organization && s.id === sessionId : s.id === sessionId, organization
? s.organization === organization && s.id === sessionId
: s.id === sessionId,
); );
if (found) { if (found) {
return found; return found;
@@ -149,7 +172,9 @@ export async function getSessionCookieByLoginName<T>({
if (stringifiedCookie?.value) { if (stringifiedCookie?.value) {
const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value); const sessions: SessionCookie<T>[] = JSON.parse(stringifiedCookie?.value);
const found = sessions.find((s) => const found = sessions.find((s) =>
organization ? s.organization === organization && s.loginName === loginName : s.loginName === loginName, organization
? s.organization === organization && s.loginName === loginName
: s.loginName === loginName,
); );
if (found) { if (found) {
return found; return found;
@@ -166,7 +191,9 @@ export async function getSessionCookieByLoginName<T>({
* @param cleanup when true, removes all expired sessions, default true * @param cleanup when true, removes all expired sessions, default true
* @returns Session Cookies * @returns Session Cookies
*/ */
export async function getAllSessionCookieIds<T>(cleanup: boolean = false): Promise<any> { export async function getAllSessionCookieIds<T>(
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies(); const cookiesList = cookies();
const stringifiedCookie = cookiesList.get("sessions"); const stringifiedCookie = cookiesList.get("sessions");
@@ -176,7 +203,11 @@ export async function getAllSessionCookieIds<T>(cleanup: boolean = false): Promi
if (cleanup) { if (cleanup) {
const now = new Date(); const now = new Date();
return sessions return sessions
.filter((session) => (session.expirationDate ? new Date(session.expirationDate) > now : true)) .filter((session) =>
session.expirationDate
? new Date(session.expirationDate) > now
: true,
)
.map((session) => session.id); .map((session) => session.id);
} else { } else {
return sessions.map((session) => session.id); return sessions.map((session) => session.id);
@@ -191,7 +222,9 @@ export async function getAllSessionCookieIds<T>(cleanup: boolean = false): Promi
* @param cleanup when true, removes all expired sessions, default true * @param cleanup when true, removes all expired sessions, default true
* @returns Session Cookies * @returns Session Cookies
*/ */
export async function getAllSessions<T>(cleanup: boolean = false): Promise<SessionCookie<T>[]> { export async function getAllSessions<T>(
cleanup: boolean = false,
): Promise<SessionCookie<T>[]> {
const cookiesList = cookies(); const cookiesList = cookies();
const stringifiedCookie = cookiesList.get("sessions"); const stringifiedCookie = cookiesList.get("sessions");
@@ -200,7 +233,9 @@ export async function getAllSessions<T>(cleanup: boolean = false): Promise<Sessi
if (cleanup) { if (cleanup) {
const now = new Date(); const now = new Date();
return sessions.filter((session) => (session.expirationDate ? new Date(session.expirationDate) > now : true)); return sessions.filter((session) =>
session.expirationDate ? new Date(session.expirationDate) > now : true,
);
} else { } else {
return sessions; return sessions;
} }
@@ -240,7 +275,10 @@ export async function getMostRecentCookieWithLoginname<T>({
const latest = const latest =
filtered && filtered.length filtered && filtered.length
? filtered.reduce((prev, current) => { ? filtered.reduce((prev, current) => {
return new Date(prev.changeDate).getTime() > new Date(current.changeDate).getTime() ? prev : current; return new Date(prev.changeDate).getTime() >
new Date(current.changeDate).getTime()
? prev
: current;
}) })
: undefined; : undefined;

View File

@@ -1,10 +1,10 @@
import { create } from "@zitadel/client";
import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { IDPInformation } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import { import {
AddHumanUserRequest, AddHumanUserRequest,
AddHumanUserRequestSchema, AddHumanUserRequestSchema,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb"; } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { IDPInformation } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { create } from "@zitadel/client";
// This maps the IdentityProviderType to a slug which is used in the /success and /failure routes // This maps the IdentityProviderType to a slug which is used in the /success and /failure routes
export function idpTypeToSlug(idpType: IdentityProviderType) { export function idpTypeToSlug(idpType: IdentityProviderType) {

View File

@@ -1,6 +1,8 @@
"use server"; "use server";
import { headers } from "next/headers"; import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { createSessionForUserIdAndUpdateCookie } from "../../utils/session";
import { idpTypeToSlug } from "../idp"; import { idpTypeToSlug } from "../idp";
import { import {
getActiveIdentityProviders, getActiveIdentityProviders,
@@ -9,8 +11,6 @@ import {
listUsers, listUsers,
startIdentityProviderFlow, startIdentityProviderFlow,
} from "../zitadel"; } from "../zitadel";
import { createSessionForUserIdAndUpdateCookie } from "../../utils/session";
import { redirect } from "next/navigation";
export type SendLoginnameCommand = { export type SendLoginnameCommand = {
loginName: string; loginName: string;

View File

@@ -1,12 +1,12 @@
"use server"; "use server";
import { setSessionAndUpdateCookie } from "@/utils/session"; import { setSessionAndUpdateCookie } from "@/utils/session";
import { create } from "@zitadel/client";
import { import {
CheckOTPSchema, CheckOTPSchema,
ChecksSchema, ChecksSchema,
CheckTOTPSchema, CheckTOTPSchema,
} from "@zitadel/proto/zitadel/session/v2/session_service_pb"; } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { create } from "@zitadel/client";
import { import {
getMostRecentSessionCookie, getMostRecentSessionCookie,
getSessionCookieById, getSessionCookieById,

View File

@@ -6,11 +6,13 @@ import {
registerPasskey, registerPasskey,
verifyPasskeyRegistration, verifyPasskeyRegistration,
} from "@/lib/zitadel"; } from "@/lib/zitadel";
import { userAgent } from "next/server";
import { create } from "@zitadel/client"; import { create } from "@zitadel/client";
import { VerifyPasskeyRegistrationRequestSchema } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import {
RegisterPasskeyResponse,
VerifyPasskeyRegistrationRequestSchema,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { headers } from "next/headers"; import { headers } from "next/headers";
import { RegisterPasskeyResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { userAgent } from "next/server";
import { getSessionCookieById } from "../cookies"; import { getSessionCookieById } from "../cookies";
type VerifyPasskeyCommand = { type VerifyPasskeyCommand = {

View File

@@ -1,23 +1,14 @@
"use server"; "use server";
import { import { deleteSession, listAuthenticationMethodTypes } from "@/lib/zitadel";
deleteSession,
getSession,
getUserByID,
listAuthenticationMethodTypes,
} from "@/lib/zitadel";
import { import {
createSessionAndUpdateCookie, createSessionAndUpdateCookie,
createSessionForIdpAndUpdateCookie, createSessionForIdpAndUpdateCookie,
setSessionAndUpdateCookie, setSessionAndUpdateCookie,
} from "@/utils/session"; } from "@/utils/session";
import { headers } from "next/headers"; import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { import { headers } from "next/headers";
RequestChallenges,
RequestChallengesSchema,
} from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { create } from "@zitadel/client";
import { import {
getMostRecentSessionCookie, getMostRecentSessionCookie,
getSessionCookieById, getSessionCookieById,

View File

@@ -1,10 +1,10 @@
"use server"; "use server";
import { getSession, registerU2F, verifyU2FRegistration } from "@/lib/zitadel"; import { getSession, registerU2F, verifyU2FRegistration } from "@/lib/zitadel";
import { userAgent } from "next/server";
import { VerifyU2FRegistrationRequestSchema } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { create } from "@zitadel/client"; import { create } from "@zitadel/client";
import { VerifyU2FRegistrationRequestSchema } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { headers } from "next/headers"; import { headers } from "next/headers";
import { userAgent } from "next/server";
import { getSessionCookieById } from "../cookies"; import { getSessionCookieById } from "../cookies";
type RegisterU2FCommand = { type RegisterU2FCommand = {

View File

@@ -1,11 +1,12 @@
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { GetSessionResponse } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { GetSessionResponse } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { getMostRecentCookieWithLoginname } from "./cookies"; import { getMostRecentCookieWithLoginname } from "./cookies";
import { sessionService } from "./zitadel";
export async function loadMostRecentSession( export async function loadMostRecentSession(sessionParams: {
sessionService: any, // TODO: SessionServiceClient, loginName?: string;
sessionParams: { loginName?: string; organization?: string }, organization?: string;
): Promise<Session | undefined> { }): Promise<Session | undefined> {
const recent = await getMostRecentCookieWithLoginname({ const recent = await getMostRecentCookieWithLoginname({
loginName: sessionParams.loginName, loginName: sessionParams.loginName,
organization: sessionParams.organization, organization: sessionParams.organization,

View File

@@ -1,22 +1,24 @@
import { import {
createIdpServiceClient,
createOIDCServiceClient, createOIDCServiceClient,
createOrganizationServiceClient,
createSessionServiceClient, createSessionServiceClient,
createSettingsServiceClient, createSettingsServiceClient,
createUserServiceClient, createUserServiceClient,
createIdpServiceClient,
makeReqCtx, makeReqCtx,
createOrganizationServiceClient,
} from "@zitadel/client/v2"; } from "@zitadel/client/v2";
import { createServerTransport } from "@zitadel/node"; import { createServerTransport } from "@zitadel/node";
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb"; import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { IDPInformation } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import { import {
RetrieveIdentityProviderIntentRequest, RetrieveIdentityProviderIntentRequest,
VerifyPasskeyRegistrationRequest, VerifyPasskeyRegistrationRequest,
VerifyU2FRegistrationRequest, VerifyU2FRegistrationRequest,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb"; } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { IDPInformation } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import { create } from "@zitadel/client";
import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2/object_pb";
import { CreateCallbackRequest } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb"; import { CreateCallbackRequest } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
import type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb"; import type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import { import {
@@ -24,8 +26,6 @@ import {
SearchQuerySchema, SearchQuerySchema,
} from "@zitadel/proto/zitadel/user/v2/query_pb"; } from "@zitadel/proto/zitadel/user/v2/query_pb";
import { PROVIDER_MAPPING } from "./idp"; import { PROVIDER_MAPPING } from "./idp";
import { create } from "@zitadel/client";
import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2/object_pb";
const SESSION_LIFETIME_S = 3000; const SESSION_LIFETIME_S = 3000;

View File

@@ -1,5 +1,5 @@
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server"; import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export const config = { export const config = {
matcher: [ matcher: [

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import React from "react";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import React from "react";
type Props = { type Props = {
domain: string; domain: string;

View File

@@ -1,8 +1,8 @@
import { CheckIcon } from "@heroicons/react/24/solid";
import clsx from "clsx"; import clsx from "clsx";
import Link from "next/link"; import Link from "next/link";
import { BadgeState, StateBadge } from "./StateBadge";
import { CheckIcon } from "@heroicons/react/24/solid";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { BadgeState, StateBadge } from "./StateBadge";
const cardClasses = (alreadyAdded: boolean) => const cardClasses = (alreadyAdded: boolean) =>
clsx( clsx(

View File

@@ -1,10 +1,5 @@
import clsx from "clsx"; import clsx from "clsx";
import React, { import { ButtonHTMLAttributes, DetailedHTMLProps, forwardRef } from "react";
ButtonHTMLAttributes,
DetailedHTMLProps,
ReactNode,
forwardRef,
} from "react";
export enum ButtonSizes { export enum ButtonSizes {
Small = "Small", Small = "Small",

View File

@@ -1,5 +1,5 @@
import classNames from "clsx"; import classNames from "clsx";
import React, { import {
DetailedHTMLProps, DetailedHTMLProps,
forwardRef, forwardRef,
InputHTMLAttributes, InputHTMLAttributes,

View File

@@ -1,11 +1,7 @@
"use client"; "use client";
import Link from "next/link";
import { BadgeState, StateBadge } from "./StateBadge";
import clsx from "clsx";
import { CheckIcon } from "@heroicons/react/24/outline";
import { EMAIL, SMS, TOTP, U2F } from "./AuthMethods";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { EMAIL, SMS, TOTP, U2F } from "./AuthMethods";
type Props = { type Props = {
loginName?: string; loginName?: string;

View File

@@ -1,8 +1,8 @@
"use client"; "use client";
import { EMAIL, SMS, TOTP, U2F } from "./AuthMethods";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { EMAIL, SMS, TOTP, U2F } from "./AuthMethods";
type Props = { type Props = {
loginName?: string; loginName?: string;

View File

@@ -1,9 +1,9 @@
"use client"; "use client";
import React from "react";
import { Logo } from "@/ui/Logo"; import { Logo } from "@/ui/Logo";
import ThemeWrapper from "./ThemeWrapper";
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb"; import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb";
import React from "react";
import ThemeWrapper from "./ThemeWrapper";
export default function DynamicTheme({ export default function DynamicTheme({
branding, branding,

View File

@@ -2,10 +2,10 @@
import { demos, type Item } from "@/lib/demos"; import { demos, type Item } from "@/lib/demos";
import { ZitadelLogo } from "@/ui/ZitadelLogo"; import { ZitadelLogo } from "@/ui/ZitadelLogo";
import Link from "next/link";
import { useSelectedLayoutSegment, usePathname } from "next/navigation";
import clsx from "clsx";
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/solid"; import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/solid";
import clsx from "clsx";
import Link from "next/link";
import { usePathname, useSelectedLayoutSegment } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import Theme from "./Theme"; import Theme from "./Theme";

View File

@@ -1,10 +1,10 @@
"use client"; "use client";
import { useEffect, useState } from "react";
import { Spinner } from "./Spinner";
import Alert from "./Alert";
import { useRouter } from "next/navigation";
import { createNewSession } from "@/lib/server/session"; import { createNewSession } from "@/lib/server/session";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import Alert from "./Alert";
import { Spinner } from "./Spinner";
type Props = { type Props = {
userId: string; userId: string;

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { CheckCircleIcon } from "@heroicons/react/24/solid"; import { CheckCircleIcon } from "@heroicons/react/24/solid";
import clsx from "clsx"; import clsx from "clsx";
import React, { import {
ChangeEvent, ChangeEvent,
DetailedHTMLProps, DetailedHTMLProps,
forwardRef, forwardRef,

View File

@@ -1,15 +1,15 @@
"use client"; "use client";
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { Button, ButtonVariants } from "./Button";
import Alert, { AlertType } from "./Alert";
import { Spinner } from "./Spinner";
import { useForm } from "react-hook-form";
import { TextInput } from "./Input";
import BackButton from "./BackButton";
import { ChecksJson } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { ChallengesJson } from "@zitadel/proto/zitadel/session/v2/challenge_pb"; import { ChallengesJson } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { ChecksJson } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import Alert, { AlertType } from "./Alert";
import BackButton from "./BackButton";
import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input";
import { Spinner } from "./Spinner";
// either loginName or sessionId must be provided // either loginName or sessionId must be provided
type Props = { type Props = {

View File

@@ -1,19 +1,19 @@
"use client"; "use client";
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
import { Button, ButtonVariants } from "./Button";
import Alert from "./Alert";
import { Spinner } from "./Spinner";
import BackButton from "./BackButton";
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { updateSession } from "@/lib/server/session"; import { updateSession } from "@/lib/server/session";
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
import { create } from "@zitadel/client";
import { import {
RequestChallengesSchema, RequestChallengesSchema,
UserVerificationRequirement, UserVerificationRequirement,
} from "@zitadel/proto/zitadel/session/v2/challenge_pb"; } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { create } from "@zitadel/client"; import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import Alert from "./Alert";
import BackButton from "./BackButton";
import { Button, ButtonVariants } from "./Button";
import { Spinner } from "./Spinner";
// either loginName or sessionId must be provided // either loginName or sessionId must be provided
type Props = { type Props = {

View File

@@ -1,11 +1,11 @@
import { expect, describe, test, beforeEach, afterEach } from "vitest";
import { import {
render,
cleanup, cleanup,
render,
screen, screen,
waitFor, waitFor,
within, within,
} from "@testing-library/react"; } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, test } from "vitest";
import PasswordComplexity from "./PasswordComplexity"; import PasswordComplexity from "./PasswordComplexity";
const matchesTitle = `Matches`; const matchesTitle = `Matches`;

View File

@@ -1,23 +1,19 @@
"use client"; "use client";
import { useState } from "react"; import { resetPassword } from "@/lib/server/password";
import { Button, ButtonVariants } from "./Button"; import { updateSession } from "@/lib/server/session";
import { TextInput } from "./Input"; import { create } from "@zitadel/client";
import { useForm } from "react-hook-form"; import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner"; import { useState } from "react";
import { useForm } from "react-hook-form";
import Alert from "./Alert"; import Alert from "./Alert";
import BackButton from "./BackButton"; import BackButton from "./BackButton";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { Button, ButtonVariants } from "./Button";
import { import { TextInput } from "./Input";
CheckPassword, import { Spinner } from "./Spinner";
Checks,
ChecksSchema,
} from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { create } from "@zitadel/client";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { updateSession } from "@/lib/server/session";
import { resetPassword } from "@/lib/server/password";
type Inputs = { type Inputs = {
password: string; password: string;

View File

@@ -1,8 +1,8 @@
"use client"; "use client";
import React, { useState } from "react";
import Link from "next/link";
import { Checkbox } from "./Checkbox";
import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb"; import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb";
import Link from "next/link";
import { useState } from "react";
import { Checkbox } from "./Checkbox";
type Props = { type Props = {
legal: LegalAndSupportSettings; legal: LegalAndSupportSettings;

View File

@@ -1,19 +1,19 @@
"use client"; "use client";
import { useState } from "react"; import { registerUser } from "@/lib/server/register";
import { Button, ButtonVariants } from "./Button"; import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb";
import { TextInput } from "./Input";
import { PrivacyPolicyCheckboxes } from "./PrivacyPolicyCheckboxes";
import { FieldValues, useForm } from "react-hook-form";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner"; import { useState } from "react";
import { FieldValues, useForm } from "react-hook-form";
import Alert from "./Alert";
import AuthenticationMethodRadio, { import AuthenticationMethodRadio, {
methods, methods,
} from "./AuthenticationMethodRadio"; } from "./AuthenticationMethodRadio";
import Alert from "./Alert";
import BackButton from "./BackButton"; import BackButton from "./BackButton";
import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb"; import { Button, ButtonVariants } from "./Button";
import { registerUser } from "@/lib/server/register"; import { TextInput } from "./Input";
import { PrivacyPolicyCheckboxes } from "./PrivacyPolicyCheckboxes";
import { Spinner } from "./Spinner";
type Inputs = type Inputs =
| { | {

View File

@@ -1,15 +1,14 @@
"use client"; "use client";
import { useState } from "react";
import { Button, ButtonVariants } from "./Button";
import { useForm } from "react-hook-form";
import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner";
import Alert from "./Alert";
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
import BackButton from "./BackButton";
import { RegisterPasskeyResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { registerPasskeyLink, verifyPasskey } from "@/lib/server/passkeys"; import { registerPasskeyLink, verifyPasskey } from "@/lib/server/passkeys";
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useForm } from "react-hook-form";
import Alert from "./Alert";
import BackButton from "./BackButton";
import { Button, ButtonVariants } from "./Button";
import { Spinner } from "./Spinner";
type Inputs = {}; type Inputs = {};

View File

@@ -1,15 +1,13 @@
"use client"; "use client";
import { useState } from "react";
import { Button, ButtonVariants } from "./Button";
import { useForm } from "react-hook-form";
import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner";
import Alert from "./Alert";
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
import BackButton from "./BackButton";
import { RegisterU2FResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { addU2F, verifyU2F } from "@/lib/server/u2f"; import { addU2F, verifyU2F } from "@/lib/server/u2f";
import { coerceToArrayBuffer, coerceToBase64Url } from "@/utils/base64";
import { useRouter } from "next/navigation";
import { useState } from "react";
import Alert from "./Alert";
import BackButton from "./BackButton";
import { Button, ButtonVariants } from "./Button";
import { Spinner } from "./Spinner";
type Inputs = {}; type Inputs = {};

View File

@@ -1,14 +1,13 @@
"use client"; "use client";
import { cleanupSession } from "@/lib/server/session";
import { XCircleIcon } from "@heroicons/react/24/outline";
import { timestampDate } from "@zitadel/client";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import moment from "moment";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react"; import { useState } from "react";
import { Avatar } from "./Avatar"; import { Avatar } from "./Avatar";
import moment from "moment";
import { XCircleIcon } from "@heroicons/react/24/outline";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { timestampDate } from "@zitadel/client";
import { deleteSession } from "@/lib/zitadel";
import { cleanupSession } from "@/lib/server/session";
export default function SessionItem({ export default function SessionItem({
session, session,

View File

@@ -1,9 +1,9 @@
"use client"; "use client";
import SessionItem from "./SessionItem";
import Alert from "./Alert";
import { useEffect, useState } from "react";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { useState } from "react";
import Alert from "./Alert";
import SessionItem from "./SessionItem";
type Props = { type Props = {
sessions: Session[]; sessions: Session[];

View File

@@ -1,21 +1,21 @@
"use client"; "use client";
import PasswordComplexity from "./PasswordComplexity"; import { registerUser } from "@/lib/server/register";
import { useState } from "react";
import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input";
import { FieldValues, useForm } from "react-hook-form";
import { import {
lowerCaseValidator, lowerCaseValidator,
numberValidator, numberValidator,
symbolValidator, symbolValidator,
upperCaseValidator, upperCaseValidator,
} from "@/utils/validators"; } from "@/utils/validators";
import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner";
import Alert from "./Alert";
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb"; import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
import { registerUser } from "@/lib/server/register"; import { useRouter } from "next/navigation";
import { useState } from "react";
import { FieldValues, useForm } from "react-hook-form";
import Alert from "./Alert";
import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input";
import PasswordComplexity from "./PasswordComplexity";
import { Spinner } from "./Spinner";
type Inputs = type Inputs =
| { | {

View File

@@ -1,16 +1,18 @@
"use client"; "use client";
import { ReactNode, useState } from "react";
import { useRouter } from "next/navigation";
import Alert from "./Alert";
import { IdentityProvider } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { idpTypeToSlug } from "@/lib/idp"; import { idpTypeToSlug } from "@/lib/idp";
import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { startIDPFlow } from "@/lib/server/idp"; import { startIDPFlow } from "@/lib/server/idp";
import { SignInWithGithub } from "./idps/SignInWithGithub"; import {
IdentityProvider,
IdentityProviderType,
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { useRouter } from "next/navigation";
import { ReactNode, useState } from "react";
import Alert from "./Alert";
import { SignInWithAzureAD } from "./idps/SignInWithAzureAD"; import { SignInWithAzureAD } from "./idps/SignInWithAzureAD";
import { SignInWithGoogle } from "./idps/SignInWithGoogle"; import { SignInWithGithub } from "./idps/SignInWithGithub";
import { SignInWithGitlab } from "./idps/SignInWithGitlab"; import { SignInWithGitlab } from "./idps/SignInWithGitlab";
import { SignInWithGoogle } from "./idps/SignInWithGoogle";
export interface SignInWithIDPProps { export interface SignInWithIDPProps {
children?: ReactNode; children?: ReactNode;

View File

@@ -1,15 +1,15 @@
"use client"; "use client";
import { QRCodeSVG } from "qrcode.react"; import { verifyTOTP } from "@/lib/server-actions";
import Alert, { AlertType } from "./Alert";
import Link from "next/link"; import Link from "next/link";
import CopyToClipboard from "./CopyToClipboard"; import { useRouter } from "next/navigation";
import { TextInput } from "./Input"; import { QRCodeSVG } from "qrcode.react";
import { Button, ButtonVariants } from "./Button";
import { Spinner } from "./Spinner";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { useRouter } from "next/navigation"; import Alert from "./Alert";
import { verifyTOTP } from "@/lib/server-actions"; import { Button, ButtonVariants } from "./Button";
import CopyToClipboard from "./CopyToClipboard";
import { TextInput } from "./Input";
import { Spinner } from "./Spinner";
type Inputs = { type Inputs = {
code: string; code: string;

View File

@@ -1,8 +1,8 @@
"use client"; "use client";
import React, { useEffect, useState } from "react";
import { useTheme } from "next-themes";
import { MoonIcon, SunIcon } from "@heroicons/react/24/outline"; import { MoonIcon, SunIcon } from "@heroicons/react/24/outline";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
function Theme() { function Theme() {
const { resolvedTheme, setTheme } = useTheme(); const { resolvedTheme, setTheme } = useTheme();

View File

@@ -1,8 +1,8 @@
"use client"; "use client";
import { setTheme } from "@/utils/colors"; import { setTheme } from "@/utils/colors";
import { ReactNode, useEffect } from "react";
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb"; import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb";
import { ReactNode, useEffect } from "react";
type Props = { type Props = {
branding: BrandingSettings | undefined; branding: BrandingSettings | undefined;

View File

@@ -1,19 +1,19 @@
"use client"; "use client";
import { ReactNode, useEffect, useState } from "react"; import { sendLoginname } from "@/lib/server/loginname";
import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input";
import { useForm } from "react-hook-form";
import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner";
import Alert from "./Alert";
import { import {
LoginSettings, LoginSettings,
PasskeysType, PasskeysType,
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import BackButton from "./BackButton";
import { sendLoginname } from "@/lib/server/loginname";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { useRouter } from "next/navigation";
import { ReactNode, useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import Alert from "./Alert";
import BackButton from "./BackButton";
import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input";
import { Spinner } from "./Spinner";
type Inputs = { type Inputs = {
loginName: string; loginName: string;

View File

@@ -1,13 +1,13 @@
"use client"; "use client";
import { resendVerifyEmail, verifyUserByEmail } from "@/lib/server/email";
import Alert from "@/ui/Alert";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { Button, ButtonVariants } from "./Button"; import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input"; import { TextInput } from "./Input";
import { useForm } from "react-hook-form";
import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner"; import { Spinner } from "./Spinner";
import Alert from "@/ui/Alert";
import { resendVerifyEmail, verifyUserByEmail } from "@/lib/server/email";
type Inputs = { type Inputs = {
code: string; code: string;

View File

@@ -1,6 +1,4 @@
import Image from "next/image"; import Image from "next/image";
import { ZitadelLogoDark } from "./ZitadelLogoDark";
import { ZitadelLogoLight } from "./ZitadelLogoLight";
type Props = { type Props = {
height?: number; height?: number;
width?: number; width?: number;

View File

@@ -1,5 +1,5 @@
import tinycolor from "tinycolor2";
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb"; import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb";
import tinycolor from "tinycolor2";
export interface Color { export interface Color {
name: string; name: string;

View File

@@ -1,11 +1,13 @@
"use server"; "use server";
import { addSessionToCookie, updateSessionCookie } from "@/lib/cookies";
import { import {
createSessionFromChecks,
createSessionForUserIdAndIdpIntent, createSessionForUserIdAndIdpIntent,
createSessionFromChecks,
getSession, getSession,
setSession, setSession,
} from "@/lib/zitadel"; } from "@/lib/zitadel";
import { create, timestampDate, toDate } from "@zitadel/client";
import { import {
Challenges, Challenges,
RequestChallenges, RequestChallenges,
@@ -15,9 +17,6 @@ import {
Checks, Checks,
ChecksSchema, ChecksSchema,
} from "@zitadel/proto/zitadel/session/v2/session_service_pb"; } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { timestampDate, toDate } from "@zitadel/client";
import { create } from "@zitadel/client";
import { addSessionToCookie, updateSessionCookie } from "@/lib/cookies";
type CustomCookieData = { type CustomCookieData = {
id: string; id: string;

View File

@@ -1,6 +1,6 @@
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react"; import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths"; import tsconfigPaths from "vite-tsconfig-paths";
import { defineConfig } from "vitest/config";
export default defineConfig({ export default defineConfig({
plugins: [tsconfigPaths(), react()], plugins: [tsconfigPaths(), react()],

View File

@@ -28,6 +28,7 @@
"@vitejs/plugin-react": "^4.2.1", "@vitejs/plugin-react": "^4.2.1",
"eslint": "8.57.0", "eslint": "8.57.0",
"eslint-config-zitadel": "workspace:*", "eslint-config-zitadel": "workspace:*",
"@zitadel/prettier-config": "workspace:^",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^4.0.0", "prettier-plugin-organize-imports": "^4.0.0",
"tsup": "^8.2.4", "tsup": "^8.2.4",

View File

@@ -7,4 +7,5 @@ export default {
trailingComma: 'all', trailingComma: 'all',
bracketSpacing: true, bracketSpacing: true,
arrowParens: 'always', arrowParens: 'always',
plugins: ["prettier-plugin-organize-imports"]
}; };

3
pnpm-lock.yaml generated
View File

@@ -17,6 +17,9 @@ importers:
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^4.2.1 specifier: ^4.2.1
version: 4.3.1(vite@5.4.2) version: 4.3.1(vite@5.4.2)
'@zitadel/prettier-config':
specifier: workspace:^
version: link:packages/zitadel-prettier-config
eslint: eslint:
specifier: 8.57.0 specifier: 8.57.0
version: 8.57.0 version: 8.57.0

1
prettier.config.cjs Normal file
View File

@@ -0,0 +1 @@
export { default } from "@zitadel/prettier-config";