From c9063853e538a4010f5d4e522a3da5abc80098a4 Mon Sep 17 00:00:00 2001 From: Papageorgiou Nikos Date: Wed, 25 Sep 2024 10:59:26 +0300 Subject: [PATCH] feat(clerk-js,ui,types): Hide sign up url from component mode is restricted (#4206) --- .changeset/gold-lamps-appear.md | 6 +++++ packages/clerk-js/bundlewatch.config.json | 2 +- packages/clerk-js/src/core/constants.ts | 7 ++++++ .../src/ui/components/SignIn/SignInStart.tsx | 18 ++++++++------- .../SignIn/__tests__/SignInStart.test.tsx | 23 +++++++++++++++++++ .../src/ui/utils/test/fixtureHelpers.ts | 8 +++++++ packages/types/src/userSettings.ts | 3 +++ .../ui/src/components/sign-in/steps/start.tsx | 17 +++++++++----- packages/ui/src/constants/user-settings.ts | 6 +++++ 9 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 .changeset/gold-lamps-appear.md create mode 100644 packages/ui/src/constants/user-settings.ts diff --git a/.changeset/gold-lamps-appear.md b/.changeset/gold-lamps-appear.md new file mode 100644 index 0000000000..bdacd44a2d --- /dev/null +++ b/.changeset/gold-lamps-appear.md @@ -0,0 +1,6 @@ +--- +"@clerk/clerk-js": minor +"@clerk/types": minor +--- + +Hide sign up url from `` component when mode is `restricted` \ No newline at end of file diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json index bbb0e027c5..f0f2208f71 100644 --- a/packages/clerk-js/bundlewatch.config.json +++ b/packages/clerk-js/bundlewatch.config.json @@ -1,6 +1,6 @@ { "files": [ - { "path": "./dist/clerk.browser.js", "maxSize": "64kB" }, + { "path": "./dist/clerk.browser.js", "maxSize": "64.1kB" }, { "path": "./dist/clerk.headless.js", "maxSize": "43kB" }, { "path": "./dist/ui-common*.js", "maxSize": "86KB" }, { "path": "./dist/vendors*.js", "maxSize": "70KB" }, diff --git a/packages/clerk-js/src/core/constants.ts b/packages/clerk-js/src/core/constants.ts index 82a8c3f320..a025cfc8ce 100644 --- a/packages/clerk-js/src/core/constants.ts +++ b/packages/clerk-js/src/core/constants.ts @@ -1,3 +1,5 @@ +import type { SignUpModes } from '@clerk/types'; + // TODO: Do we still have a use for this or can we simply preserve all params? export const PRESERVED_QUERYSTRING_PARAMS = [ 'redirect_url', @@ -29,3 +31,8 @@ export const SIGN_IN_INITIAL_VALUE_KEYS = ['email_address', 'phone_number', 'use export const SIGN_UP_INITIAL_VALUE_KEYS = ['email_address', 'phone_number', 'username', 'first_name', 'last_name']; export const DEBOUNCE_MS = 350; + +export const SIGN_UP_MODES: Record = { + PUBLIC: 'public', + RESTRICTED: 'restricted', +}; diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx index d2b6f83835..4bfb6c6dd5 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx @@ -3,7 +3,7 @@ import { isWebAuthnAutofillSupported, isWebAuthnSupported } from '@clerk/shared/ import type { ClerkAPIError, SignInCreateParams, SignInResource } from '@clerk/types'; import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; -import { ERROR_CODES } from '../../../core/constants'; +import { ERROR_CODES, SIGN_UP_MODES } from '../../../core/constants'; import { clerkInvalidFAPIResponse } from '../../../core/errors'; import { getClerkQueryParam, removeClerkQueryParam } from '../../../utils'; import type { SignInStartIdentifier } from '../../common'; @@ -410,13 +410,15 @@ export function _SignInStart(): JSX.Element { - - - - + {userSettings.signUp.mode === SIGN_UP_MODES.PUBLIC && ( + + + + + )} diff --git a/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx b/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx index 8ee9c1e1ce..b88ad62ae3 100644 --- a/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx @@ -111,6 +111,29 @@ describe('SignInStart', () => { }); }); + describe('Restricted mode', () => { + it('"Don\'t have an account?" text should not be presented', async () => { + const { wrapper } = await createFixtures(f => { + f.withEmailAddress(); + f.withRestrictedMode(); + }); + render(, { wrapper }); + expect(screen.queryByText(/Don’t have an account/i)).not.toBeInTheDocument(); + }); + + it('"Don\'t have an account?" text should be visible', async () => { + const { wrapper, fixtures } = await createFixtures(f => { + f.withEmailAddress(); + }); + render(, { wrapper }); + + const signUpLink = screen.getByText(/Don’t have an account/i).nextElementSibling; + expect(signUpLink?.textContent).toBe('Sign up'); + expect(signUpLink?.tagName.toUpperCase()).toBe('A'); + expect(signUpLink?.getAttribute('href')).toMatch(fixtures.environment.displayConfig.signUpUrl); + }); + }); + describe('Social OAuth', () => { it.each(OAUTH_PROVIDERS)('shows the "Continue with $name" social OAuth button', async ({ provider, name }) => { const { wrapper } = await createFixtures(f => { diff --git a/packages/clerk-js/src/ui/utils/test/fixtureHelpers.ts b/packages/clerk-js/src/ui/utils/test/fixtureHelpers.ts index e6f1d73fca..7f09b4093b 100644 --- a/packages/clerk-js/src/ui/utils/test/fixtureHelpers.ts +++ b/packages/clerk-js/src/ui/utils/test/fixtureHelpers.ts @@ -17,6 +17,7 @@ import type { VerificationJSON, } from '@clerk/types'; +import { SIGN_UP_MODES } from '../../../core/constants'; import type { OrgParams } from '../../../core/test/fixtures'; import { createUser, getOrganizationId } from '../../../core/test/fixtures'; import { createUserFixture } from './fixtures'; @@ -318,6 +319,8 @@ const createUserSettingsFixtureHelpers = (environment: EnvironmentJSON) => { show_zxcvbn: false, min_zxcvbn_strength: 0, }; + us.sign_up.mode = SIGN_UP_MODES.PUBLIC; + const emptyAttribute = { first_factors: [], second_factors: [], @@ -477,6 +480,10 @@ const createUserSettingsFixtureHelpers = (environment: EnvironmentJSON) => { }; }; + const withRestrictedMode = () => { + us.sign_up.mode = SIGN_UP_MODES.RESTRICTED; + }; + // TODO: Add the rest, consult pkg/generate/auth_config.go return { @@ -494,5 +501,6 @@ const createUserSettingsFixtureHelpers = (environment: EnvironmentJSON) => { withAuthenticatorApp, withPasskey, withPasskeySettings, + withRestrictedMode, }; }; diff --git a/packages/types/src/userSettings.ts b/packages/types/src/userSettings.ts index ca61c41953..9edc2755e7 100644 --- a/packages/types/src/userSettings.ts +++ b/packages/types/src/userSettings.ts @@ -47,10 +47,13 @@ export type SignInData = { }; }; +export type SignUpModes = 'public' | 'restricted'; + export type SignUpData = { allowlist_only: boolean; progressive: boolean; captcha_enabled: boolean; + mode: SignUpModes; }; export type PasswordSettingsData = { diff --git a/packages/ui/src/components/sign-in/steps/start.tsx b/packages/ui/src/components/sign-in/steps/start.tsx index 27d137ef4b..a37958b4b4 100644 --- a/packages/ui/src/components/sign-in/steps/start.tsx +++ b/packages/ui/src/components/sign-in/steps/start.tsx @@ -11,12 +11,14 @@ import { PhoneNumberField } from '~/common/phone-number-field'; import { PhoneNumberOrUsernameField } from '~/common/phone-number-or-username-field'; import { UsernameField } from '~/common/username-field'; import { LOCALIZATION_NEEDED } from '~/constants/localizations'; +import { SIGN_UP_MODES } from '~/constants/user-settings'; import { useAppearance } from '~/contexts'; import { useAttributes } from '~/hooks/use-attributes'; import { useCard } from '~/hooks/use-card'; import { useDevModeWarning } from '~/hooks/use-dev-mode-warning'; import { useDisplayConfig } from '~/hooks/use-display-config'; import { useEnabledConnections } from '~/hooks/use-enabled-connections'; +import { useEnvironment } from '~/hooks/use-environment'; import { useLocalizations } from '~/hooks/use-localizations'; import { Button } from '~/primitives/button'; import * as Card from '~/primitives/card'; @@ -27,6 +29,7 @@ import { Separator } from '~/primitives/separator'; export function SignInStart() { const enabledConnections = useEnabledConnections(); const { t } = useLocalizations(); + const { userSettings } = useEnvironment(); const { enabled: usernameEnabled } = useAttributes('username'); const { enabled: phoneNumberEnabled } = useAttributes('phone_number'); const { enabled: emailAddressEnabled } = useAttributes('email_address'); @@ -184,12 +187,14 @@ export function SignInStart() { - - - {t('signIn.start.actionText')}{' '} - {t('signIn.start.actionLink')} - - + {userSettings.signUp.mode === SIGN_UP_MODES.PUBLIC ? ( + + + {t('signIn.start.actionText')}{' '} + {t('signIn.start.actionLink')} + + + ) : null} diff --git a/packages/ui/src/constants/user-settings.ts b/packages/ui/src/constants/user-settings.ts new file mode 100644 index 0000000000..54db661f8b --- /dev/null +++ b/packages/ui/src/constants/user-settings.ts @@ -0,0 +1,6 @@ +import type { SignUpModes } from '@clerk/types'; + +export const SIGN_UP_MODES: Record = { + PUBLIC: 'public', + RESTRICTED: 'restricted', +};