Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 10 additions & 21 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { inBrowser as inClientSide, isValidBrowserOnline } from '@clerk/shared/browser';
import { clerkEvents, createClerkEventBus } from '@clerk/shared/clerkEventBus';
import { deprecated } from '@clerk/shared/deprecated';
import {
ClerkRuntimeError,
EmailLinkError,
Expand Down Expand Up @@ -1277,7 +1276,7 @@ export class Clerk implements ClerkInterface {
* `setActive` can be used to set the active session and/or organization.
*/
public setActive = async (params: SetActiveParams): Promise<void> => {
const { organization, beforeEmit, redirectUrl, navigate: setActiveNavigate } = params;
const { organization, redirectUrl, navigate: setActiveNavigate } = params;
let { session } = params;
this.__internal_setActiveInProgress = true;
debugLogger.debug(
Expand Down Expand Up @@ -1375,29 +1374,15 @@ export class Clerk implements ClerkInterface {
eventBus.emit(events.TokenUpdate, { token: null });
}

//2. If there's a beforeEmit, typically we're navigating. Emit the session as
// undefined, then wait for beforeEmit to complete before emitting the new session.
// When undefined, neither SignedIn nor SignedOut renders, which avoids flickers or
// automatic reloading when reloading shouldn't be happening.
//2. Handle navigation with redirectUrl or setActiveNavigate
const tracker = createBeforeUnloadTracker(this.#options.standardBrowser);

if (beforeEmit) {
deprecated(
'Clerk.setActive({beforeEmit})',
'Use the `redirectUrl` property instead. Example `Clerk.setActive({redirectUrl:"/"})`',
);
await tracker.track(async () => {
this.#setTransitiveState();
await beforeEmit(newSession);
});
}

const taskUrl =
newSession?.status === 'pending' &&
newSession?.currentTask &&
this.#options.taskUrls?.[newSession?.currentTask.key];

if (!beforeEmit && (redirectUrl || taskUrl || setActiveNavigate)) {
if (redirectUrl || taskUrl || setActiveNavigate) {
await tracker.track(async () => {
if (!this.client) {
// Typescript is not happy because since thinks this.client might have changed to undefined because the function is asynchronous.
Expand Down Expand Up @@ -1544,15 +1529,19 @@ export class Clerk implements ClerkInterface {
public buildSignInUrl(options?: SignInRedirectOptions): string {
return this.#buildUrl(
'signInUrl',
{ ...options, redirectUrl: options?.redirectUrl || window.location.href },
{ ...options, redirectUrl: options?.redirectUrl || window.location.href } as RedirectOptions & {
redirectUrl?: string;
},
options?.initialValues,
);
}

public buildSignUpUrl(options?: SignUpRedirectOptions): string {
return this.#buildUrl(
'signUpUrl',
{ ...options, redirectUrl: options?.redirectUrl || window.location.href },
{ ...options, redirectUrl: options?.redirectUrl || window.location.href } as RedirectOptions & {
redirectUrl?: string;
},
options?.initialValues,
);
}
Expand Down Expand Up @@ -2874,7 +2863,7 @@ export class Clerk implements ClerkInterface {

#buildUrl = (
key: 'signInUrl' | 'signUpUrl',
options: RedirectOptions,
options: RedirectOptions & { redirectUrl?: string },
_initValues?: Record<string, string>,
): string => {
if (!key || !this.loaded || !this.environment || !this.environment.displayConfig) {
Expand Down
7 changes: 0 additions & 7 deletions packages/clerk-js/src/core/resources/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import type {
PasskeyResource,
PhoneNumberResource,
RemoveUserPasswordParams,
SamlAccountResource,
SetProfileImageParams,
TOTPJSON,
TOTPResource,
Expand Down Expand Up @@ -49,7 +48,6 @@ import {
OrganizationSuggestion,
Passkey,
PhoneNumber,
SamlAccount,
SessionWithActivities,
TOTP,
UserOrganizationInvitation,
Expand All @@ -69,8 +67,6 @@ export class User extends BaseResource implements UserResource {
enterpriseAccounts: EnterpriseAccountResource[] = [];
passkeys: PasskeyResource[] = [];

samlAccounts: SamlAccountResource[] = [];

organizationMemberships: OrganizationMembershipResource[] = [];
passwordEnabled = false;
firstName: string | null = null;
Expand Down Expand Up @@ -365,8 +361,6 @@ export class User extends BaseResource implements UserResource {

this.organizationMemberships = (data.organization_memberships || []).map(om => new OrganizationMembership(om));

this.samlAccounts = (data.saml_accounts || []).map(sa => new SamlAccount(sa, this.path() + '/saml_accounts'));

this.enterpriseAccounts = (data.enterprise_accounts || []).map(
ea => new EnterpriseAccount(ea, this.path() + '/enterprise_accounts'),
);
Expand Down Expand Up @@ -413,7 +407,6 @@ export class User extends BaseResource implements UserResource {
external_accounts: this.externalAccounts.map(ea => ea.__internal_toSnapshot()),
passkeys: this.passkeys.map(passkey => passkey.__internal_toSnapshot()),
organization_memberships: this.organizationMemberships.map(om => om.__internal_toSnapshot()),
saml_accounts: this.samlAccounts.map(sa => sa.__internal_toSnapshot()),
enterprise_accounts: this.enterpriseAccounts.map(ea => ea.__internal_toSnapshot()),
totp_enabled: this.totpEnabled,
backup_code_enabled: this.backupCodeEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CreateOrganizationForm } from './CreateOrganizationForm';
export const CreateOrganizationPage = withCardStateProvider(() => {
const { closeCreateOrganization } = useClerk();

const { mode, navigateAfterCreateOrganization, skipInvitationScreen, hideSlug } = useCreateOrganizationContext();
const { mode, navigateAfterCreateOrganization, skipInvitationScreen } = useCreateOrganizationContext();
const card = useCardState();
const { showDevModeNotice } = useDevMode();

Expand All @@ -33,7 +33,6 @@ export const CreateOrganizationPage = withCardStateProvider(() => {
closeCreateOrganization();
}
}}
hideSlug={hideSlug}
/>
</Card.Content>
<Card.Footer />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export const OrganizationSwitcherPopover = React.forwardRef<HTMLDivElement, Orga

organizationProfileProps,
skipInvitationScreen,
hideSlug,
} = useOrganizationSwitcherContext();

const { user } = useUser();
Expand Down Expand Up @@ -86,7 +85,7 @@ export const OrganizationSwitcherPopover = React.forwardRef<HTMLDivElement, Orga
if (createOrganizationMode === 'navigation') {
return navigateCreateOrganization();
}
return openCreateOrganization({ afterCreateOrganizationUrl, skipInvitationScreen, hideSlug });
return openCreateOrganization({ afterCreateOrganizationUrl, skipInvitationScreen });
};

const handleItemClick = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export const useCreateOrganizationContext = () => {
return {
...ctx,
skipInvitationScreen: ctx.skipInvitationScreen || false,
hideSlug: ctx.hideSlug || false,
navigateAfterCreateOrganization,
componentName,
};
Expand Down
17 changes: 2 additions & 15 deletions packages/clerk-js/src/ui/contexts/components/UserButton.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { deprecatedObjectProperty } from '@clerk/shared/deprecated';
import { useClerk } from '@clerk/shared/react';
import { createContext, useContext, useMemo } from 'react';

Expand Down Expand Up @@ -26,22 +25,10 @@ export const useUserButtonContext = () => {
const signInUrl = ctx.signInUrl || options.signInUrl || displayConfig.signInUrl;
const userProfileUrl = ctx.userProfileUrl || displayConfig.userProfileUrl;

if (ctx.afterSignOutUrl) {
deprecatedObjectProperty(ctx, 'afterSignOutUrl', `Move 'afterSignOutUrl' to '<ClerkProvider/>`);
}

const afterSignOutUrl = ctx.afterSignOutUrl || clerk.buildAfterSignOutUrl();
const afterSignOutUrl = clerk.buildAfterSignOutUrl();
const navigateAfterSignOut = () => navigate(afterSignOutUrl);

if (ctx.afterSignOutUrl) {
deprecatedObjectProperty(
ctx,
'afterMultiSessionSingleSignOutUrl',
`Move 'afterMultiSessionSingleSignOutUrl' to '<ClerkProvider/>`,
);
}
const afterMultiSessionSingleSignOutUrl =
ctx.afterMultiSessionSingleSignOutUrl || clerk.buildAfterMultiSessionSingleSignOutUrl();
const afterMultiSessionSingleSignOutUrl = clerk.buildAfterMultiSessionSingleSignOutUrl();
const navigateAfterMultiSessionSingleSignOut = () => clerk.redirectWithAuth(afterMultiSessionSingleSignOutUrl);

const afterSwitchSessionUrl = ctx.afterSwitchSessionUrl || displayConfig.afterSwitchSessionUrl;
Expand Down
19 changes: 2 additions & 17 deletions packages/clerk-js/src/utils/assertNoLegacyProp.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
import { logger } from '@clerk/shared/logger';

export function assertNoLegacyProp(props: Record<string, any>) {
const legacyProps = ['redirectUrl', 'afterSignInUrl', 'afterSignUpUrl', 'after_sign_in_url', 'after_sign_up_url'];
const legacyProp = Object.keys(props).find(key => legacyProps.includes(key));

if (legacyProp && props[legacyProp]) {
logger.warnOnce(
`Clerk: The prop "${legacyProp}" is deprecated and should be replaced with the new "fallbackRedirectUrl" or "forceRedirectUrl" props instead. Learn more: https://clerk.com/docs/guides/custom-redirects#redirect-url-props`,
);
}
}

export function warnForNewPropShadowingLegacyProp(
newKey: string | undefined,
newValue: string | undefined | null,
legacyKey: string | undefined,
legacyValue: string | undefined | null,
) {
if (newValue && legacyValue) {
logger.warnOnce(
`Clerk: The "${newKey}" prop ("${newValue}") has priority over the legacy "${legacyKey}" (or "redirectUrl") ("${legacyValue}"), which will be completely ignored in this case. "${legacyKey}" (or "redirectUrl" prop) should be replaced with the new "fallbackRedirectUrl" or "forceRedirectUrl" props instead. Learn more: https://clerk.com/docs/guides/custom-redirects#redirect-url-props`,
throw new Error(
`Clerk: The prop "${legacyProp}" has been removed. Please use "fallbackRedirectUrl" or "forceRedirectUrl" instead. Learn more: https://clerk.com/docs/guides/custom-redirects#redirect-url-props`,
);
}
}
38 changes: 3 additions & 35 deletions packages/clerk-js/src/utils/redirectUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { applyFunctionToObj, filterProps, removeUndefined } from '@clerk/shared/
import { camelToSnake } from '@clerk/shared/underscore';
import type { ClerkOptions, RedirectOptions } from '@clerk/types';

import { assertNoLegacyProp, warnForNewPropShadowingLegacyProp } from './assertNoLegacyProp';
import { assertNoLegacyProp } from './assertNoLegacyProp';
import { isAllowedRedirect, relativeToAbsoluteUrl } from './url';

type ComponentMode = 'modal' | 'mounted';
Expand All @@ -13,9 +13,6 @@ export class RedirectUrls {
'signInFallbackRedirectUrl',
'signUpForceRedirectUrl',
'signUpFallbackRedirectUrl',
'afterSignInUrl',
'afterSignUpUrl',
'redirectUrl',
];

private static preserved = ['redirectUrl'];
Expand Down Expand Up @@ -78,19 +75,13 @@ export class RedirectUrls {
this.fromSearchParams.signInFallbackRedirectUrl ||
this.fromProps.signInFallbackRedirectUrl ||
this.fromOptions.signInFallbackRedirectUrl;
const afterSignInUrl =
this.fromSearchParams.afterSignInUrl || this.fromProps.afterSignInUrl || this.fromOptions.afterSignInUrl;
const afterSignUpUrl =
this.fromSearchParams.afterSignUpUrl || this.fromProps.afterSignUpUrl || this.fromOptions.afterSignUpUrl;
const redirectUrl = this.fromSearchParams.redirectUrl || this.fromProps.redirectUrl || this.fromOptions.redirectUrl;
const redirectUrl = this.fromSearchParams.redirectUrl;

const res: RedirectOptions = {
const res: RedirectOptions & { redirectUrl?: string | null } = {
signUpForceRedirectUrl,
signUpFallbackRedirectUrl,
signInFallbackRedirectUrl,
signInForceRedirectUrl,
afterSignInUrl,
afterSignUpUrl,
redirectUrl,
};

Expand All @@ -108,37 +99,14 @@ export class RedirectUrls {
#getRedirectUrl(prefix: 'signIn' | 'signUp') {
const forceKey = `${prefix}ForceRedirectUrl` as const;
const fallbackKey = `${prefix}FallbackRedirectUrl` as const;
let newKeyInUse: string | undefined;

const legacyPropKey = `after${prefix[0].toUpperCase()}${prefix.slice(1)}Url` as 'afterSignInUrl' | 'afterSignUpUrl';

let result;
// Prioritize forceRedirectUrl
result = this.fromSearchParams[forceKey] || this.fromProps[forceKey] || this.fromOptions[forceKey];
if (result) {
newKeyInUse = forceKey;
}
// Try to get redirect_url, only allowed as a search param
result ||= this.fromSearchParams.redirectUrl;
if (result) {
newKeyInUse = 'redirectUrl';
}
// Otherwise, fallback to fallbackRedirectUrl
result ||= this.fromSearchParams[fallbackKey] || this.fromProps[fallbackKey] || this.fromOptions[fallbackKey];
if (result) {
newKeyInUse = fallbackKey;
}

// TODO: v6
// Remove the compatibility layer for afterSignInUrl and afterSignUpUrl
const legacyValue =
this.fromSearchParams[legacyPropKey] ||
this.fromProps[legacyPropKey] ||
this.fromProps.redirectUrl ||
this.fromOptions[legacyPropKey];

warnForNewPropShadowingLegacyProp(newKeyInUse, result, legacyPropKey, legacyValue);
result ||= legacyValue;

if (!result && this.mode === 'modal') {
return window.location.href;
Expand Down
3 changes: 0 additions & 3 deletions packages/nextjs/src/client-boundary/controlComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ export {
RedirectToSignIn,
RedirectToSignUp,
RedirectToTasks,
RedirectToUserProfile,
AuthenticateWithRedirectCallback,
RedirectToCreateOrganization,
RedirectToOrganizationProfile,
} from '@clerk/react';

export { MultisessionAppSupport } from '@clerk/react/internal';
3 changes: 0 additions & 3 deletions packages/nextjs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ export {
ClerkFailed,
ClerkLoaded,
ClerkLoading,
RedirectToCreateOrganization,
RedirectToOrganizationProfile,
RedirectToSignIn,
RedirectToSignUp,
RedirectToTasks,
RedirectToUserProfile,
} from './client-boundary/controlComponents';

/**
Expand Down
5 changes: 0 additions & 5 deletions packages/nextjs/src/server/clerkMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ export type ClerkMiddlewareSessionAuthObject = (SignedInAuthObject | SignedOutAu
redirectToSignUp: RedirectFun<Response>;
};

/**
* @deprecated Use `ClerkMiddlewareSessionAuthObject` instead.
*/
export type ClerkMiddlewareAuthObject = ClerkMiddlewareSessionAuthObject;

export type ClerkMiddlewareAuth = AuthFn;

type ClerkMiddlewareHandler = (
Expand Down
7 changes: 1 addition & 6 deletions packages/nextjs/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ export { buildClerkProps } from './buildClerkProps';
export { auth } from '../app-router/server/auth';
export { currentUser } from '../app-router/server/currentUser';
export { clerkMiddleware } from './clerkMiddleware';
export type {
ClerkMiddlewareAuth,
ClerkMiddlewareSessionAuthObject,
ClerkMiddlewareAuthObject,
ClerkMiddlewareOptions,
} from './clerkMiddleware';
export type { ClerkMiddlewareAuth, ClerkMiddlewareSessionAuthObject, ClerkMiddlewareOptions } from './clerkMiddleware';

/**
* Re-export resource types from @clerk/backend
Expand Down
2 changes: 0 additions & 2 deletions packages/nextjs/src/utils/mergeNextClerkPropsWithEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export const mergeNextClerkPropsWithEnv = (props: Omit<NextClerkProviderProps, '
props.signInFallbackRedirectUrl || process.env.NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL || '',
signUpFallbackRedirectUrl:
props.signUpFallbackRedirectUrl || process.env.NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL || '',
afterSignInUrl: props.afterSignInUrl || process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL || '',
afterSignUpUrl: props.afterSignUpUrl || process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL || '',
newSubscriptionRedirectUrl:
props.newSubscriptionRedirectUrl || process.env.NEXT_PUBLIC_CLERK_CHECKOUT_CONTINUE_URL || '',
telemetry: props.telemetry ?? {
Expand Down
Loading
Loading