diff --git a/.github/workflows/login-quality.yml b/.github/workflows/login-quality.yml index 81383941c6..f5fb46c6c4 100644 --- a/.github/workflows/login-quality.yml +++ b/.github/workflows/login-quality.yml @@ -52,7 +52,7 @@ jobs: - name: Install dependencies run: pnpm install - name: Run login quality checks with Turbo - run: pnpm turbo lint test:unit --filter=./login + run: pnpm turbo test:unit --filter=@zitadel/login env: # latest if branch is main, otherwise image version which is the pull request number LOGIN_BAKE_CLI: depot bake diff --git a/login/apps/login/.eslintrc.cjs b/login/apps/login/.eslintrc.cjs index da3473042a..76ad0c10d8 100644 --- a/login/apps/login/.eslintrc.cjs +++ b/login/apps/login/.eslintrc.cjs @@ -7,8 +7,8 @@ module.exports = { "@next/next/no-img-element": "off", "react/no-unescaped-entities": "off", "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], - "no-undef": "off" + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "no-undef": "off", }, parserOptions: { ecmaVersion: "latest", diff --git a/login/apps/login/package.json b/login/apps/login/package.json index 68d29b1e83..f205d93cfc 100644 --- a/login/apps/login/package.json +++ b/login/apps/login/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "next dev", "dev:turbo": "next dev --turbopack", - "test:unit": "pnpm vitest", + "test:unit": "pnpm vitest --run", "test:unit:standalone": "pnpm test:unit", "test:unit:watch": "pnpm test:unit --watch", "lint": "pnpm exec next lint && pnpm exec prettier --check .", diff --git a/login/apps/login/prettier.config.mjs b/login/apps/login/prettier.config.mjs index 58866d827d..5e0f9b2584 100644 --- a/login/apps/login/prettier.config.mjs +++ b/login/apps/login/prettier.config.mjs @@ -4,8 +4,8 @@ export default { useTabs: false, semi: true, singleQuote: false, - trailingComma: 'all', + trailingComma: "all", bracketSpacing: true, - arrowParens: 'always', - plugins: ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"] + arrowParens: "always", + plugins: ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"], }; diff --git a/login/apps/login/scripts/prepare-standalone.js b/login/apps/login/scripts/prepare-standalone.js index d40cebc206..666e116edb 100644 --- a/login/apps/login/scripts/prepare-standalone.js +++ b/login/apps/login/scripts/prepare-standalone.js @@ -5,80 +5,89 @@ * This script converts the monorepo version to a standalone version */ -import fs from 'fs/promises'; -import { execSync } from 'child_process'; +import { execSync } from "child_process"; +import fs from "fs/promises"; const FILES_TO_REMOVE = [ - // Turbo is not needed for standalone builds since there are no workspace dependencies - { file: 'turbo.json', backup: 'turbo.monorepo.backup.json' } + // Turbo is not needed for standalone builds since there are no workspace dependencies + { file: "turbo.json", backup: "turbo.monorepo.backup.json" }, ]; async function prepareStandalone() { - console.log('šŸ”§ Preparing standalone version...\n'); + console.log("šŸ”§ Preparing standalone version...\n"); - const args = process.argv.slice(2); - const shouldInstall = args.includes('--install'); + const args = process.argv.slice(2); + const shouldInstall = args.includes("--install"); - try { - // Step 1: Copy package.standalone.json to package.json - console.log('šŸ“¦ Setting up package.json...'); - const packageStandaloneExists = await fs.access('package.standalone.json').then(() => true).catch(() => false); + try { + // Step 1: Copy package.standalone.json to package.json + console.log("šŸ“¦ Setting up package.json..."); + const packageStandaloneExists = await fs + .access("package.standalone.json") + .then(() => true) + .catch(() => false); - if (packageStandaloneExists) { - // Backup current package.json - await fs.copyFile('package.json', 'package.monorepo.backup.json'); - console.log(' šŸ’¾ Backed up package.json → package.monorepo.backup.json'); + if (packageStandaloneExists) { + // Backup current package.json + await fs.copyFile("package.json", "package.monorepo.backup.json"); + console.log( + " šŸ’¾ Backed up package.json → package.monorepo.backup.json", + ); - // Copy standalone version - await fs.copyFile('package.standalone.json', 'package.json'); - console.log(' āœ… package.standalone.json → package.json'); - } else { - throw new Error('package.standalone.json not found!'); - } - - // Step 2: Remove unnecessary files for standalone - console.log('šŸ—‘ļø Removing monorepo-specific files...'); - for (const item of FILES_TO_REMOVE) { - const fileExists = await fs.access(item.file).then(() => true).catch(() => false); - - if (fileExists) { - // Backup current file - await fs.copyFile(item.file, item.backup); - console.log(` šŸ’¾ Backed up ${item.file} → ${item.backup}`); - - // Remove the file - await fs.unlink(item.file); - console.log(` šŸ—‘ļø Removed ${item.file} (not needed in standalone)`); - } else { - console.log(` ā„¹ļø ${item.file} not found, skipping`); - } - } - - // Step 3: Install dependencies if requested - if (shouldInstall) { - console.log('\nšŸ“„ Installing dependencies...'); - try { - execSync('pnpm install', { stdio: 'inherit' }); - console.log(' āœ… Dependencies installed successfully'); - } catch (error) { - console.warn(' āš ļø pnpm install failed, you may need to run it manually'); - } - } - - console.log('\nšŸŽ‰ Standalone preparation complete!'); - console.log(' ✨ Turbo removed - using standard npm scripts'); - console.log('\nšŸ“‹ Next steps:'); - if (!shouldInstall) { - console.log(' 1. Run: pnpm install'); - } - console.log(' 2. Run: pnpm run dev'); - console.log(' 3. Start developing!\n'); - - } catch (error) { - console.error('\nāŒ Failed to prepare standalone version:', error.message); - console.error('Please check the error above and try again.\n'); - process.exit(1); + // Copy standalone version + await fs.copyFile("package.standalone.json", "package.json"); + console.log(" āœ… package.standalone.json → package.json"); + } else { + throw new Error("package.standalone.json not found!"); } + + // Step 2: Remove unnecessary files for standalone + console.log("šŸ—‘ļø Removing monorepo-specific files..."); + for (const item of FILES_TO_REMOVE) { + const fileExists = await fs + .access(item.file) + .then(() => true) + .catch(() => false); + + if (fileExists) { + // Backup current file + await fs.copyFile(item.file, item.backup); + console.log(` šŸ’¾ Backed up ${item.file} → ${item.backup}`); + + // Remove the file + await fs.unlink(item.file); + console.log(` šŸ—‘ļø Removed ${item.file} (not needed in standalone)`); + } else { + console.log(` ā„¹ļø ${item.file} not found, skipping`); + } + } + + // Step 3: Install dependencies if requested + if (shouldInstall) { + console.log("\nšŸ“„ Installing dependencies..."); + try { + execSync("pnpm install", { stdio: "inherit" }); + console.log(" āœ… Dependencies installed successfully"); + } catch (error) { + console.warn( + " āš ļø pnpm install failed, you may need to run it manually", + ); + } + } + + console.log("\nšŸŽ‰ Standalone preparation complete!"); + console.log(" ✨ Turbo removed - using standard npm scripts"); + console.log("\nšŸ“‹ Next steps:"); + if (!shouldInstall) { + console.log(" 1. Run: pnpm install"); + } + console.log(" 2. Run: pnpm run dev"); + console.log(" 3. Start developing!\n"); + } catch (error) { + console.error("\nāŒ Failed to prepare standalone version:", error.message); + console.error("Please check the error above and try again.\n"); + process.exit(1); + } } prepareStandalone(); diff --git a/login/apps/login/src/app/(login)/accounts/page.tsx b/login/apps/login/src/app/(login)/accounts/page.tsx index a1e99401e2..5af25c1d0b 100644 --- a/login/apps/login/src/app/(login)/accounts/page.tsx +++ b/login/apps/login/src/app/(login)/accounts/page.tsx @@ -10,7 +10,7 @@ import { } from "@/lib/zitadel"; import { UserPlusIcon } from "@heroicons/react/24/outline"; import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb"; -import { getLocale } from "next-intl/server"; +// import { getLocale } from "next-intl/server"; import { headers } from "next/headers"; import Link from "next/link"; @@ -33,7 +33,7 @@ export default async function Page(props: { searchParams: Promise>; }) { const searchParams = await props.searchParams; - const locale = getLocale(); + // const locale = getLocale(); const requestId = searchParams?.requestId; const organization = searchParams?.organization; @@ -78,11 +78,11 @@ export default async function Page(props: {

-
+
-
-
+
+
diff --git a/login/apps/login/src/app/(login)/authenticator/set/page.tsx b/login/apps/login/src/app/(login)/authenticator/set/page.tsx index a339426c89..c123395aeb 100644 --- a/login/apps/login/src/app/(login)/authenticator/set/page.tsx +++ b/login/apps/login/src/app/(login)/authenticator/set/page.tsx @@ -18,7 +18,7 @@ import { listAuthenticationMethodTypes, } from "@/lib/zitadel"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb"; -import { getLocale } from "next-intl/server"; +// import { getLocale } from "next-intl/server"; import { headers } from "next/headers"; import { redirect } from "next/navigation"; @@ -26,7 +26,7 @@ export default async function Page(props: { searchParams: Promise>; }) { const searchParams = await props.searchParams; - const locale = getLocale(); + // const locale = getLocale(); const { loginName, requestId, organization, sessionId } = searchParams; @@ -193,7 +193,7 @@ export default async function Page(props: { {loginSettings?.allowExternalIdp && !!identityProviders.length && ( <> -
+

diff --git a/login/apps/login/src/app/(login)/layout.tsx b/login/apps/login/src/app/(login)/layout.tsx index 936c7e17e4..0a75a920f1 100644 --- a/login/apps/login/src/app/(login)/layout.tsx +++ b/login/apps/login/src/app/(login)/layout.tsx @@ -27,13 +27,13 @@ export default async function RootLayout({ -
+
-
+
@@ -42,11 +42,11 @@ export default async function RootLayout({ >
-
+
{children} -
+
diff --git a/login/apps/login/src/app/(login)/loginname/page.tsx b/login/apps/login/src/app/(login)/loginname/page.tsx index f15f440930..37b57ed1b9 100644 --- a/login/apps/login/src/app/(login)/loginname/page.tsx +++ b/login/apps/login/src/app/(login)/loginname/page.tsx @@ -79,7 +79,7 @@ export default async function Page(props: { > {identityProviders && loginSettings?.allowExternalIdp && ( -
+

-
+
diff --git a/login/apps/login/src/app/(login)/register/page.tsx b/login/apps/login/src/app/(login)/register/page.tsx index aa83ad1ead..3fead718dc 100644 --- a/login/apps/login/src/app/(login)/register/page.tsx +++ b/login/apps/login/src/app/(login)/register/page.tsx @@ -117,7 +117,7 @@ export default async function Page(props: { {loginSettings?.allowExternalIdp && !!identityProviders.length && ( <> -
+

diff --git a/login/apps/login/src/app/(login)/verify/page.tsx b/login/apps/login/src/app/(login)/verify/page.tsx index a61d4e608c..55cc8bd1ec 100644 --- a/login/apps/login/src/app/(login)/verify/page.tsx +++ b/login/apps/login/src/app/(login)/verify/page.tsx @@ -136,7 +136,7 @@ export default async function Page(props: { searchParams: Promise }) { )} {id && send && ( -
+
diff --git a/login/apps/login/src/components/address-bar.tsx b/login/apps/login/src/components/address-bar.tsx index 7e7bda6bd0..67417649dc 100644 --- a/login/apps/login/src/components/address-bar.tsx +++ b/login/apps/login/src/components/address-bar.tsx @@ -11,7 +11,7 @@ export function AddressBar({ domain }: Props) { const pathname = usePathname(); return ( -
+
-
+
{domain}
{pathname ? ( diff --git a/login/apps/login/src/components/alert.tsx b/login/apps/login/src/components/alert.tsx index 417e67934e..fa18b750f2 100644 --- a/login/apps/login/src/components/alert.tsx +++ b/login/apps/login/src/components/alert.tsx @@ -26,7 +26,7 @@ export function Alert({ children, type = AlertType.ALERT }: Props) { return (
{type === AlertType.ALERT && ( - + )} {type === AlertType.INFO && ( - + )} - {children} + {children}
); } diff --git a/login/apps/login/src/components/app-avatar.tsx b/login/apps/login/src/components/app-avatar.tsx index defe388438..84879d08ac 100644 --- a/login/apps/login/src/components/app-avatar.tsx +++ b/login/apps/login/src/components/app-avatar.tsx @@ -27,7 +27,7 @@ export function AppAvatar({ appName, imageUrl, shadow }: AvatarProps) { return (
) : ( - {credentials} + {credentials} )}
); diff --git a/login/apps/login/src/components/auth-methods.tsx b/login/apps/login/src/components/auth-methods.tsx index ff0bcf0b32..82271c93a6 100644 --- a/login/apps/login/src/components/auth-methods.tsx +++ b/login/apps/login/src/components/auth-methods.tsx @@ -35,12 +35,12 @@ export const TOTP = (alreadyAdded: boolean, link: string) => {
@@ -63,7 +63,7 @@ export const U2F = (alreadyAdded: boolean, link: string) => {
@@ -73,7 +73,7 @@ export const U2F = (alreadyAdded: boolean, link: string) => { viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" - className="w-8 h-8 mr-4" + className="mr-4 h-8 w-8" > {
{
{
@@ -176,7 +176,7 @@ export const PASSKEYS = (alreadyAdded: boolean, link: string) => { viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" - className="w-8 h-8 mr-4" + className="mr-4 h-8 w-8" > {
@@ -225,9 +225,9 @@ export const PASSWORD = (alreadyAdded: boolean, link: string) => { function Setup() { return ( -
+
- +
); diff --git a/login/apps/login/src/components/authentication-method-radio.tsx b/login/apps/login/src/components/authentication-method-radio.tsx index c3b273ab46..121e257485 100644 --- a/login/apps/login/src/components/authentication-method-radio.tsx +++ b/login/apps/login/src/components/authentication-method-radio.tsx @@ -34,20 +34,18 @@ export function AuthenticationMethodRadio({ className={({ active, checked }) => `${ active - ? "ring-2 ring-opacity-60 ring-primary-light-500 dark:ring-white/20" + ? "ring-2 ring-primary-light-500 ring-opacity-60 dark:ring-white/20" : "" - } - ${ - checked - ? "bg-background-light-400 dark:bg-background-dark-400 ring-2 ring-primary-light-500 dark:ring-primary-dark-500" - : "bg-background-light-400 dark:bg-background-dark-400" - } - h-full flex-1 relative border boder-divider-light dark:border-divider-dark flex cursor-pointer rounded-lg px-5 py-4 focus:outline-none hover:shadow-lg dark:hover:bg-white/10` + } ${ + checked + ? "bg-background-light-400 ring-2 ring-primary-light-500 dark:bg-background-dark-400 dark:ring-primary-dark-500" + : "bg-background-light-400 dark:bg-background-dark-400" + } boder-divider-light relative flex h-full flex-1 cursor-pointer rounded-lg border px-5 py-4 hover:shadow-lg focus:outline-none dark:border-divider-dark dark:hover:bg-white/10` } > {({ active, checked }) => ( <> -
+
{method === "passkey" && ( @@ -76,7 +74,7 @@ export function AuthenticationMethodRadio({ )} {method === AuthenticationMethod.Passkey && ( @@ -82,7 +82,7 @@ export function Avatar({ height={48} width={48} alt="avatar" - className="w-full h-full border border-divider-light dark:border-divider-dark rounded-full" + className="h-full w-full rounded-full border border-divider-light dark:border-divider-dark" src={imageUrl} /> ) : ( diff --git a/login/apps/login/src/components/button.tsx b/login/apps/login/src/components/button.tsx index a25a30538a..59f7af39d1 100644 --- a/login/apps/login/src/components/button.tsx +++ b/login/apps/login/src/components/button.tsx @@ -33,8 +33,7 @@ export const getButtonClasses = ( color: ButtonColors, ) => clsx({ - "box-border font-normal leading-36px text-14px inline-flex items-center rounded-md focus:outline-none transition-colors transition-shadow duration-300": - true, + "box-border font-normal leading-36px text-14px inline-flex items-center rounded-md focus:outline-none transition-colors transition-shadow duration-300": true, "shadow hover:shadow-xl active:shadow-xl disabled:border-none disabled:bg-gray-300 disabled:text-gray-600 disabled:shadow-none disabled:cursor-not-allowed disabled:dark:bg-gray-800 disabled:dark:text-gray-900": variant === ButtonVariants.Primary, "bg-primary-light-500 dark:bg-primary-dark-500 hover:bg-primary-light-400 hover:dark:bg-primary-dark-400 text-primary-light-contrast-500 dark:text-primary-dark-contrast-500": diff --git a/login/apps/login/src/components/change-password-form.tsx b/login/apps/login/src/components/change-password-form.tsx index 00513d8dda..1c93e4ae23 100644 --- a/login/apps/login/src/components/change-password-form.tsx +++ b/login/apps/login/src/components/change-password-form.tsx @@ -149,7 +149,7 @@ export function ChangePasswordForm({ return (
-
+
- {loading && }{" "} + {loading && }{" "}
diff --git a/login/apps/login/src/components/checkbox.tsx b/login/apps/login/src/components/checkbox.tsx index 41b45aad92..aa0c066f24 100644 --- a/login/apps/login/src/components/checkbox.tsx +++ b/login/apps/login/src/components/checkbox.tsx @@ -36,7 +36,7 @@ export const Checkbox = forwardRef( return (
-
+
( disabled={disabled} type="checkbox" className={classNames( - "form-checkbox rounded border-gray-300 text-primary-light-500 dark:text-primary-dark-500 shadow-sm focus:border-indigo-300 focus:ring focus:ring-offset-0 focus:ring-indigo-200 focus:ring-opacity-50", + "form-checkbox rounded border-gray-300 text-primary-light-500 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 focus:ring-offset-0 dark:text-primary-dark-500", className, )} {...props} diff --git a/login/apps/login/src/components/choose-authenticator-to-login.tsx b/login/apps/login/src/components/choose-authenticator-to-login.tsx index 0f5dd79134..ccebf83e6d 100644 --- a/login/apps/login/src/components/choose-authenticator-to-login.tsx +++ b/login/apps/login/src/components/choose-authenticator-to-login.tsx @@ -25,7 +25,7 @@ export function ChooseAuthenticatorToLogin({
)} -
+
{authMethods.includes(AuthenticationMethodType.PASSWORD) && loginSettings?.allowUsernamePassword && PASSWORD(false, "/password?" + params)} diff --git a/login/apps/login/src/components/choose-authenticator-to-setup.tsx b/login/apps/login/src/components/choose-authenticator-to-setup.tsx index 4aa4de720a..9eb744f3a5 100644 --- a/login/apps/login/src/components/choose-authenticator-to-setup.tsx +++ b/login/apps/login/src/components/choose-authenticator-to-setup.tsx @@ -37,7 +37,7 @@ export function ChooseAuthenticatorToSetup({ )} -
+
{!authMethods.includes(AuthenticationMethodType.PASSWORD) && loginSettings.allowUsernamePassword && PASSWORD(false, "/password/set?" + params)} diff --git a/login/apps/login/src/components/choose-second-factor-to-setup.tsx b/login/apps/login/src/components/choose-second-factor-to-setup.tsx index edd0ae2b61..38599053ff 100644 --- a/login/apps/login/src/components/choose-second-factor-to-setup.tsx +++ b/login/apps/login/src/components/choose-second-factor-to-setup.tsx @@ -58,7 +58,7 @@ export function ChooseSecondFactorToSetup({ return ( <> -
+
{loginSettings.secondFactors.map((factor) => { switch (factor) { case SecondFactorType.OTP: @@ -94,7 +94,7 @@ export function ChooseSecondFactorToSetup({
{!force && ( diff --git a/login/apps/login/src/components/copy-to-clipboard.tsx b/login/apps/login/src/components/copy-to-clipboard.tsx index cf0dedc060..615af7884f 100644 --- a/login/apps/login/src/components/copy-to-clipboard.tsx +++ b/login/apps/login/src/components/copy-to-clipboard.tsx @@ -27,7 +27,7 @@ export function CopyToClipboard({ value }: Props) {
diff --git a/login/apps/login/src/components/dynamic-theme.tsx b/login/apps/login/src/components/dynamic-theme.tsx index d50bc082ea..ec92b1c627 100644 --- a/login/apps/login/src/components/dynamic-theme.tsx +++ b/login/apps/login/src/components/dynamic-theme.tsx @@ -17,7 +17,7 @@ export function DynamicTheme({ }) { return ( -
+
{branding && ( diff --git a/login/apps/login/src/components/idps/base-button.tsx b/login/apps/login/src/components/idps/base-button.tsx index 0185c57996..a38278e7cb 100644 --- a/login/apps/login/src/components/idps/base-button.tsx +++ b/login/apps/login/src/components/idps/base-button.tsx @@ -26,15 +26,15 @@ export const BaseButton = forwardRef< ref={ref} disabled={formStatus.pending} className={clsx( - "flex-1 transition-all cursor-pointer flex flex-row items-center bg-background-light-400 text-text-light-500 dark:bg-background-dark-500 dark:text-text-dark-500 border border-divider-light hover:border-black dark:border-divider-dark hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500 outline-none rounded-md px-4 text-sm", + "flex flex-1 cursor-pointer flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 text-sm text-text-light-500 outline-none transition-all hover:border-black focus:border-primary-light-500 dark:border-divider-dark dark:bg-background-dark-500 dark:text-text-dark-500 hover:dark:border-white focus:dark:border-primary-dark-500", props.className, )} > -
-
+
+
{props.children}
- {formStatus.pending && } + {formStatus.pending && }
); diff --git a/login/apps/login/src/components/idps/sign-in-with-apple.tsx b/login/apps/login/src/components/idps/sign-in-with-apple.tsx index 17e3fc43bb..8047cd6a7c 100644 --- a/login/apps/login/src/components/idps/sign-in-with-apple.tsx +++ b/login/apps/login/src/components/idps/sign-in-with-apple.tsx @@ -12,7 +12,7 @@ export const SignInWithApple = forwardRef< return ( -
+
Apple Logo diff --git a/login/apps/login/src/components/idps/sign-in-with-azure-ad.tsx b/login/apps/login/src/components/idps/sign-in-with-azure-ad.tsx index 3cd33708b6..f16b8cab21 100644 --- a/login/apps/login/src/components/idps/sign-in-with-azure-ad.tsx +++ b/login/apps/login/src/components/idps/sign-in-with-azure-ad.tsx @@ -12,13 +12,13 @@ export const SignInWithAzureAd = forwardRef< return ( -
+
diff --git a/login/apps/login/src/components/idps/sign-in-with-github.tsx b/login/apps/login/src/components/idps/sign-in-with-github.tsx index 8800e66c3d..55eb987112 100644 --- a/login/apps/login/src/components/idps/sign-in-with-github.tsx +++ b/login/apps/login/src/components/idps/sign-in-with-github.tsx @@ -11,7 +11,7 @@ function GitHubLogo() { xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 1024 1024" - className="h-8 w-8 hidden dark:block" + className="hidden h-8 w-8 dark:block" > -
+
-
+
clsx({ - "h-[40px] mb-[2px] rounded p-[7px] bg-input-light-background dark:bg-input-dark-background transition-colors duration-300 grow": - true, - "border border-input-light-border dark:border-input-dark-border hover:border-black hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500": - true, - "focus:outline-none focus:ring-0 text-base text-black dark:text-white placeholder:italic placeholder-gray-700 dark:placeholder-gray-700": - true, + "h-[40px] mb-[2px] rounded p-[7px] bg-input-light-background dark:bg-input-dark-background transition-colors duration-300 grow": true, + "border border-input-light-border dark:border-input-dark-border hover:border-black hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500": true, + "focus:outline-none focus:ring-0 text-base text-black dark:text-white placeholder:italic placeholder-gray-700 dark:placeholder-gray-700": true, "border border-warn-light-500 dark:border-warn-dark-500 hover:border-warn-light-500 hover:dark:border-warn-dark-500 focus:border-warn-light-500 focus:dark:border-warn-dark-500": error, "pointer-events-none text-gray-500 dark:text-gray-800 border border-input-light-border dark:border-input-dark-border hover:border-light-hoverborder hover:dark:border-hoverborder cursor-default": @@ -60,7 +57,7 @@ export const TextInput = forwardRef( return ( @@ -81,12 +78,12 @@ export const TextInput = forwardRef( /> {suffix && ( - + @{suffix} )} -
+
{error ? error : " "}
diff --git a/login/apps/login/src/components/language-switcher.tsx b/login/apps/login/src/components/language-switcher.tsx index 67b54e58e3..1b2ea9d727 100644 --- a/login/apps/login/src/components/language-switcher.tsx +++ b/login/apps/login/src/components/language-switcher.tsx @@ -37,13 +37,13 @@ export function LanguageSwitcher() { {selected.name} @@ -51,7 +51,7 @@ export function LanguageSwitcher() { anchor="bottom" transition className={clsx( - "w-[var(--button-width)] rounded-xl border border-black/5 dark:border-white/5 bg-background-light-500 dark:bg-background-dark-500 p-1 [--anchor-gap:var(--spacing-1)] focus:outline-none", + "w-[var(--button-width)] rounded-xl border border-black/5 bg-background-light-500 p-1 [--anchor-gap:var(--spacing-1)] focus:outline-none dark:border-white/5 dark:bg-background-dark-500", "transition duration-100 ease-in data-[leave]:data-[closed]:opacity-0", )} > @@ -59,7 +59,7 @@ export function LanguageSwitcher() {
diff --git a/login/apps/login/src/components/ldap-username-password-form.tsx b/login/apps/login/src/components/ldap-username-password-form.tsx index 2f9824dff2..5fd36efa32 100644 --- a/login/apps/login/src/components/ldap-username-password-form.tsx +++ b/login/apps/login/src/components/ldap-username-password-form.tsx @@ -100,7 +100,7 @@ export function LDAPUsernamePasswordForm({ idpId, link }: Props) { onClick={handleSubmit(submitUsernamePassword)} data-testid="submit-button" > - {loading && } + {loading && }
diff --git a/login/apps/login/src/components/login-otp.tsx b/login/apps/login/src/components/login-otp.tsx index 4ad6cced6a..f2b7e903d7 100644 --- a/login/apps/login/src/components/login-otp.tsx +++ b/login/apps/login/src/components/login-otp.tsx @@ -220,14 +220,14 @@ export function LoginOTP({ {["email", "sms"].includes(method) && (
- +
diff --git a/login/apps/login/src/components/login-passkey.tsx b/login/apps/login/src/components/login-passkey.tsx index 5a3b0b6496..968f861ff1 100644 --- a/login/apps/login/src/components/login-passkey.tsx +++ b/login/apps/login/src/components/login-passkey.tsx @@ -271,7 +271,7 @@ export function LoginPasskey({ }} data-testid="submit-button" > - {loading && }{" "} + {loading && }{" "}
diff --git a/login/apps/login/src/components/password-complexity.tsx b/login/apps/login/src/components/password-complexity.tsx index 40988984b6..4f0b460c71 100644 --- a/login/apps/login/src/components/password-complexity.tsx +++ b/login/apps/login/src/components/password-complexity.tsx @@ -19,7 +19,7 @@ const check = ( viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" - className="w-6 h-6 las la-check text-green-500 dark:text-green-500 mr-2 text-lg" + className="las la-check mr-2 h-6 w-6 text-lg text-green-500 dark:text-green-500" role="img" > Matches @@ -32,7 +32,7 @@ const check = ( ); const cross = ( {!loginSettings?.hidePasswordReset && (
diff --git a/login/apps/login/src/components/privacy-policy-checkboxes.tsx b/login/apps/login/src/components/privacy-policy-checkboxes.tsx index 4ab0e33222..86ccb08721 100644 --- a/login/apps/login/src/components/privacy-policy-checkboxes.tsx +++ b/login/apps/login/src/components/privacy-policy-checkboxes.tsx @@ -23,7 +23,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) { return ( <> -

+

{legal?.helpLink && ( @@ -34,7 +34,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) { viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" - className="ml-1 w-5 h-5" + className="ml-1 h-5 w-5" > -

+
- {loading && }{" "} + {loading && }{" "}
diff --git a/login/apps/login/src/components/register-form.tsx b/login/apps/login/src/components/register-form.tsx index 6217bbcbb9..554a0f08c2 100644 --- a/login/apps/login/src/components/register-form.tsx +++ b/login/apps/login/src/components/register-form.tsx @@ -124,7 +124,7 @@ export function RegisterForm({ const [tosAndPolicyAccepted, setTosAndPolicyAccepted] = useState(false); return (
-
+
-

+

@@ -211,14 +211,14 @@ export function RegisterForm({ const usePasswordToContinue: boolean = loginSettings?.allowUsernamePassword && loginSettings?.passkeysType == PasskeysType.ALLOWED - ? !!!(selected === methods[0]) // choose selection if both available + ? !(selected === methods[0]) // choose selection if both available : !!loginSettings?.allowUsernamePassword; // if password is chosen // set password as default if only password is allowed return submitAndContinue(values, usePasswordToContinue); })} data-testid="submit-button" > - {loading && } + {loading && }
diff --git a/login/apps/login/src/components/register-passkey.tsx b/login/apps/login/src/components/register-passkey.tsx index e21e1acdbb..5855c906fd 100644 --- a/login/apps/login/src/components/register-passkey.tsx +++ b/login/apps/login/src/components/register-passkey.tsx @@ -211,7 +211,7 @@ export function RegisterPasskey({ onClick={handleSubmit(submitRegisterAndContinue)} data-testid="submit-button" > - {loading && }{" "} + {loading && }{" "}
diff --git a/login/apps/login/src/components/register-u2f.tsx b/login/apps/login/src/components/register-u2f.tsx index e72bf1fc69..ebaabb8390 100644 --- a/login/apps/login/src/components/register-u2f.tsx +++ b/login/apps/login/src/components/register-u2f.tsx @@ -216,7 +216,7 @@ export function RegisterU2f({ onClick={submitRegisterAndContinue} data-testid="submit-button" > - {loading && }{" "} + {loading && }{" "}
diff --git a/login/apps/login/src/components/self-service-menu.tsx b/login/apps/login/src/components/self-service-menu.tsx index 449c1dda1f..8690160aed 100644 --- a/login/apps/login/src/components/self-service-menu.tsx +++ b/login/apps/login/src/components/self-service-menu.tsx @@ -15,7 +15,7 @@ export function SelfServiceMenu({ sessionId }: { sessionId: string }) { // } return ( -
+
{list.map((menuitem, index) => { return ( { {name} diff --git a/login/apps/login/src/components/session-clear-item.tsx b/login/apps/login/src/components/session-clear-item.tsx index 81930b11b3..1c9e53121f 100644 --- a/login/apps/login/src/components/session-clear-item.tsx +++ b/login/apps/login/src/components/session-clear-item.tsx @@ -52,7 +52,7 @@ export function SessionClearItem({ reload(); }); }} - className="group flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light hover:shadow-lg dark:hover:bg-white/10 py-2 px-4 rounded-md transition-all" + className="group flex flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 transition-all hover:shadow-lg dark:bg-background-dark-400 dark:hover:bg-white/10" >
{session.factors?.user?.displayName} - + {session.factors?.user?.loginName} {valid ? ( - + {verifiedAt && ( ) : ( verifiedAt && ( - + expired{" "} {session.expirationDate && moment(timestampDate(session.expirationDate)).fromNow()} @@ -90,14 +90,14 @@ export function SessionClearItem({
-
+
{valid ? ( -
+
) : ( -
+
)}
diff --git a/login/apps/login/src/components/session-item.tsx b/login/apps/login/src/components/session-item.tsx index 94e7a19da5..f189d05828 100644 --- a/login/apps/login/src/components/session-item.tsx +++ b/login/apps/login/src/components/session-item.tsx @@ -102,7 +102,7 @@ export function SessionItem({ } } }} - className="group flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light hover:shadow-lg dark:hover:bg-white/10 py-2 px-4 rounded-md transition-all" + className="group flex flex-row items-center rounded-md border border-divider-light bg-background-light-400 px-4 py-2 transition-all hover:shadow-lg dark:bg-background-dark-400 dark:hover:bg-white/10" >
{session.factors?.user?.displayName} - + {session.factors?.user?.loginName} {valid ? ( - + {verifiedAt && moment(timestampDate(verifiedAt)).fromNow()} ) : ( verifiedAt && ( - + expired{" "} {session.expirationDate && moment(timestampDate(session.expirationDate)).fromNow()} @@ -135,13 +135,13 @@ export function SessionItem({
{valid ? ( -
+
) : ( -
+
)} { event.preventDefault(); event.stopPropagation(); diff --git a/login/apps/login/src/components/set-password-form.tsx b/login/apps/login/src/components/set-password-form.tsx index 2c3db8dbf2..d4b68e1b93 100644 --- a/login/apps/login/src/components/set-password-form.tsx +++ b/login/apps/login/src/components/set-password-form.tsx @@ -188,18 +188,18 @@ export function SetPasswordForm({ return ( -
+
{codeRequired && (
- +
diff --git a/login/apps/login/src/components/set-register-password-form.tsx b/login/apps/login/src/components/set-register-password-form.tsx index 7660e60753..7ffa18de26 100644 --- a/login/apps/login/src/components/set-register-password-form.tsx +++ b/login/apps/login/src/components/set-register-password-form.tsx @@ -108,7 +108,7 @@ export function SetRegisterPasswordForm({ return ( -
+
- {loading && }{" "} + {loading && }{" "}
diff --git a/login/apps/login/src/components/sign-in-with-idp.tsx b/login/apps/login/src/components/sign-in-with-idp.tsx index ec9cfb36f8..755416f6c9 100644 --- a/login/apps/login/src/components/sign-in-with-idp.tsx +++ b/login/apps/login/src/components/sign-in-with-idp.tsx @@ -76,8 +76,8 @@ export function SignInWithIdp({ }; return ( -
-

+

+

{!!identityProviders.length && identityProviders?.map(renderIDPButton)} diff --git a/login/apps/login/src/components/skeleton.tsx b/login/apps/login/src/components/skeleton.tsx index 548953d278..c54351f410 100644 --- a/login/apps/login/src/components/skeleton.tsx +++ b/login/apps/login/src/components/skeleton.tsx @@ -2,7 +2,7 @@ import { ReactNode } from "react"; export function Skeleton({ children }: { children?: ReactNode }) { return ( -
+
{children}
); diff --git a/login/apps/login/src/components/spinner.tsx b/login/apps/login/src/components/spinner.tsx index 5ed2f04c80..d4f7731323 100644 --- a/login/apps/login/src/components/spinner.tsx +++ b/login/apps/login/src/components/spinner.tsx @@ -4,7 +4,7 @@ export const Spinner: FC<{ className?: string }> = ({ className = "" }) => { return ( clsx({ - "w-fit border-box h-18.5px flex flex-row items-center whitespace-nowrap tracking-wider leading-4 items-center justify-center px-2 py-2px text-12px rounded-full shadow-sm": - true, + "w-fit border-box h-18.5px flex flex-row items-center whitespace-nowrap tracking-wider leading-4 items-center justify-center px-2 py-2px text-12px rounded-full shadow-sm": true, "bg-state-success-light-background text-state-success-light-color dark:bg-state-success-dark-background dark:text-state-success-dark-color ": state === BadgeState.Success, "bg-state-neutral-light-background text-state-neutral-light-color dark:bg-state-neutral-dark-background dark:text-state-neutral-dark-color": diff --git a/login/apps/login/src/components/tab.tsx b/login/apps/login/src/components/tab.tsx index bd82931b5a..f26652de96 100644 --- a/login/apps/login/src/components/tab.tsx +++ b/login/apps/login/src/components/tab.tsx @@ -23,7 +23,7 @@ export const Tab = ({ return (
); diff --git a/login/apps/login/src/components/totp-register.tsx b/login/apps/login/src/components/totp-register.tsx index ea40fffbf0..f15c0d034c 100644 --- a/login/apps/login/src/components/totp-register.tsx +++ b/login/apps/login/src/components/totp-register.tsx @@ -105,14 +105,14 @@ export function TotpRegister({ } return ( -
+
{uri && ( <> -
+
{uri} @@ -145,7 +145,7 @@ export function TotpRegister({ onClick={handleSubmit(continueWithCode)} data-testid="submit-button" > - {loading && } + {loading && }
diff --git a/login/apps/login/src/components/user-avatar.tsx b/login/apps/login/src/components/user-avatar.tsx index f2aa0bfed7..8a26ba187a 100644 --- a/login/apps/login/src/components/user-avatar.tsx +++ b/login/apps/login/src/components/user-avatar.tsx @@ -42,14 +42,14 @@ export function UserAvatar({ loginName={loginName ?? ""} />
- + {loginName} {showDropdown && ( diff --git a/login/apps/login/src/components/username-form.tsx b/login/apps/login/src/components/username-form.tsx index 1dffade4b5..7e636cffde 100644 --- a/login/apps/login/src/components/username-form.tsx +++ b/login/apps/login/src/components/username-form.tsx @@ -110,7 +110,7 @@ export function UsernameForm({ /> {allowRegister && (
diff --git a/login/apps/login/src/components/verify-form.tsx b/login/apps/login/src/components/verify-form.tsx index dac4c91314..1ed69aa3f9 100644 --- a/login/apps/login/src/components/verify-form.tsx +++ b/login/apps/login/src/components/verify-form.tsx @@ -114,14 +114,14 @@ export function VerifyForm({
- +
diff --git a/login/apps/login/src/lib/cookies.ts b/login/apps/login/src/lib/cookies.ts index 7de87a98e7..45463d7a4d 100644 --- a/login/apps/login/src/lib/cookies.ts +++ b/login/apps/login/src/lib/cookies.ts @@ -314,7 +314,7 @@ export async function getMostRecentCookieWithLoginname({ if (stringifiedCookie?.value) { const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value); let filtered = sessions.filter((cookie) => { - return !!loginName ? cookie.loginName === loginName : true; + return loginName ? cookie.loginName === loginName : true; }); if (organization) { diff --git a/login/apps/login/src/lib/server/passkeys.ts b/login/apps/login/src/lib/server/passkeys.ts index 3470629f24..06c2a7554c 100644 --- a/login/apps/login/src/lib/server/passkeys.ts +++ b/login/apps/login/src/lib/server/passkeys.ts @@ -145,7 +145,7 @@ export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) { // if no name is provided, try to generate one from the user agent let passkeyName = command.passkeyName; - if (!!!passkeyName) { + if (!passkeyName) { const headersList = await headers(); const userAgentStructure = { headers: headersList }; const { browser, device, os } = userAgent(userAgentStructure); diff --git a/login/apps/login/src/lib/server/u2f.ts b/login/apps/login/src/lib/server/u2f.ts index 3fe5194336..12f4bdeecd 100644 --- a/login/apps/login/src/lib/server/u2f.ts +++ b/login/apps/login/src/lib/server/u2f.ts @@ -67,7 +67,7 @@ export async function verifyU2F(command: VerifyU2FCommand) { } let passkeyName = command.passkeyName; - if (!!!passkeyName) { + if (!passkeyName) { const headersList = await headers(); const userAgentStructure = { headers: headersList }; const { browser, device, os } = userAgent(userAgentStructure); diff --git a/login/apps/login/src/styles/globals.scss b/login/apps/login/src/styles/globals.scss index cfce853bc7..f1242eb573 100755 --- a/login/apps/login/src/styles/globals.scss +++ b/login/apps/login/src/styles/globals.scss @@ -8,11 +8,11 @@ @layer base { h1, .ztdl-h1 { - @apply text-2xl text-center; + @apply text-center text-2xl; } .ztdl-p { - @apply text-sm text-center text-text-light-secondary-500 dark:text-text-dark-secondary-500 text-center; + @apply text-center text-sm text-text-light-secondary-500 dark:text-text-dark-secondary-500; } } diff --git a/login/apps/login/tailwind.config.mjs b/login/apps/login/tailwind.config.mjs index 604ffac7a1..87595a43bd 100644 --- a/login/apps/login/tailwind.config.mjs +++ b/login/apps/login/tailwind.config.mjs @@ -9,14 +9,26 @@ let themeColors = { link: { light: { contrast: {} }, dark: { contrast: {} } }, }; -const shades = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900"]; +const shades = [ + "50", + "100", + "200", + "300", + "400", + "500", + "600", + "700", + "800", + "900", +]; const themes = ["light", "dark"]; const types = ["background", "primary", "warn", "text", "link"]; types.forEach((type) => { themes.forEach((theme) => { shades.forEach((shade) => { - themeColors[type][theme][shade] = `var(--theme-${theme}-${type}-${shade})`; + themeColors[type][theme][shade] = + `var(--theme-${theme}-${type}-${shade})`; themeColors[type][theme][`contrast-${shade}`] = `var(--theme-${theme}-${type}-contrast-${shade})`; themeColors[type][theme][`secondary-${shade}`] = diff --git a/login/apps/login/test-setup.ts b/login/apps/login/test-setup.ts new file mode 100644 index 0000000000..f149f27ae4 --- /dev/null +++ b/login/apps/login/test-setup.ts @@ -0,0 +1 @@ +import "@testing-library/jest-dom/vitest"; diff --git a/login/apps/login/vitest.config.mts b/login/apps/login/vitest.config.mts index 238c5b8b93..a45dd4c0ee 100644 --- a/login/apps/login/vitest.config.mts +++ b/login/apps/login/vitest.config.mts @@ -7,6 +7,6 @@ export default defineConfig({ test: { include: ["src/**/*.test.ts", "src/**/*.test.tsx"], environment: "jsdom", - setupFiles: ["@testing-library/jest-dom/vitest"], + setupFiles: ["./test-setup.ts"], }, }); diff --git a/login/test-setup.ts b/login/test-setup.ts new file mode 100644 index 0000000000..5f766d62a8 --- /dev/null +++ b/login/test-setup.ts @@ -0,0 +1,2 @@ +// Test setup file to handle jest-dom configuration +import "@testing-library/jest-dom";