diff --git a/.changeset/orange-pumpkins-poke.md b/.changeset/orange-pumpkins-poke.md
new file mode 100644
index 0000000000..6673bf5dc0
--- /dev/null
+++ b/.changeset/orange-pumpkins-poke.md
@@ -0,0 +1,10 @@
+---
+'@clerk/chrome-extension': minor
+'@clerk/clerk-js': minor
+'@clerk/backend': minor
+'@clerk/nextjs': minor
+'@clerk/clerk-react': minor
+'@clerk/types': minor
+---
+
+Experimental support for `` with role checks.
diff --git a/packages/backend/src/tokens/authObjects.ts b/packages/backend/src/tokens/authObjects.ts
index 3bb5b5bbf2..c9096b6b85 100644
--- a/packages/backend/src/tokens/authObjects.ts
+++ b/packages/backend/src/tokens/authObjects.ts
@@ -1,5 +1,11 @@
import { deprecated } from '@clerk/shared/deprecated';
-import type { ActClaim, JwtPayload, ServerGetToken, ServerGetTokenOptions } from '@clerk/types';
+import type {
+ ActClaim,
+ experimental__CheckAuthorizationWithoutPermission,
+ JwtPayload,
+ ServerGetToken,
+ ServerGetTokenOptions,
+} from '@clerk/types';
import type { Organization, Session, User } from '../api';
import { createBackendApiClient } from '../api';
@@ -36,6 +42,10 @@ export type SignedInAuthObject = {
orgSlug: string | undefined;
organization: Organization | undefined;
getToken: ServerGetToken;
+ /**
+ * @experimental The method is experimental and subject to change in future releases.
+ */
+ experimental__has: experimental__CheckAuthorizationWithoutPermission;
debug: AuthObjectDebug;
};
@@ -51,6 +61,10 @@ export type SignedOutAuthObject = {
orgSlug: null;
organization: null;
getToken: ServerGetToken;
+ /**
+ * @experimental The method is experimental and subject to change in future releases.
+ */
+ experimental__has: experimental__CheckAuthorizationWithoutPermission;
debug: AuthObjectDebug;
};
@@ -110,6 +124,7 @@ export function signedInAuthObject(
orgSlug,
organization,
getToken,
+ experimental__has: createHasAuthorization({ orgId, orgRole, userId }),
debug: createDebug({ ...options, ...debugData }),
};
}
@@ -131,11 +146,21 @@ export function signedOutAuthObject(debugData?: AuthObjectDebugData): SignedOutA
orgSlug: null,
organization: null,
getToken: () => Promise.resolve(null),
+ experimental__has: () => false,
debug: createDebug(debugData),
};
}
-export function prunePrivateMetadata(resource?: { private_metadata: any } | { privateMetadata: any } | null) {
+export function prunePrivateMetadata(
+ resource?:
+ | {
+ private_metadata: any;
+ }
+ | {
+ privateMetadata: any;
+ }
+ | null,
+) {
// Delete sensitive private metadata from resource before rendering in SSR
if (resource) {
// @ts-ignore
@@ -190,3 +215,34 @@ const createGetToken: CreateGetToken = params => {
return sessionToken;
};
};
+
+const createHasAuthorization =
+ ({
+ orgId,
+ orgRole,
+ userId,
+ }: {
+ userId: string;
+ orgId: string | undefined;
+ orgRole: string | undefined;
+ }): experimental__CheckAuthorizationWithoutPermission =>
+ params => {
+ if (!orgId || !userId) {
+ return false;
+ }
+
+ if (params.role) {
+ return orgRole === params.role;
+ }
+
+ if (params.some) {
+ return !!params.some.find(permObj => {
+ if (permObj.role) {
+ return orgRole === permObj.role;
+ }
+ return false;
+ });
+ }
+
+ return false;
+ };
diff --git a/packages/chrome-extension/src/__snapshots__/exports.test.ts.snap b/packages/chrome-extension/src/__snapshots__/exports.test.ts.snap
index 2d7332aaf8..3ac0e70526 100644
--- a/packages/chrome-extension/src/__snapshots__/exports.test.ts.snap
+++ b/packages/chrome-extension/src/__snapshots__/exports.test.ts.snap
@@ -8,6 +8,7 @@ exports[`public exports should not include a breaking change 1`] = `
"ClerkProvider",
"CreateOrganization",
"EmailLinkErrorCode",
+ "Experimental__Gate",
"MagicLinkErrorCode",
"MultisessionAppSupport",
"OrganizationList",
diff --git a/packages/clerk-js/src/core/resources/Session.test.ts b/packages/clerk-js/src/core/resources/Session.test.ts
index e098f5597d..b3f5c889d8 100644
--- a/packages/clerk-js/src/core/resources/Session.test.ts
+++ b/packages/clerk-js/src/core/resources/Session.test.ts
@@ -73,7 +73,7 @@ describe('Session', () => {
updated_at: new Date().getTime(),
} as SessionJSON);
- const isAuthorized = await session.isAuthorized({ permission: 'org:sys_profile:delete' });
+ const isAuthorized = await session.experimental__checkAuthorization({ permission: 'org:sys_profile:delete' });
expect(isAuthorized).toBe(true);
});
@@ -93,7 +93,7 @@ describe('Session', () => {
updated_at: new Date().getTime(),
} as SessionJSON);
- const isAuthorized = await session.isAuthorized({ permission: 'org:sys_profile:delete' });
+ const isAuthorized = await session.experimental__checkAuthorization({ permission: 'org:sys_profile:delete' });
expect(isAuthorized).toBe(false);
});
diff --git a/packages/clerk-js/src/core/resources/Session.ts b/packages/clerk-js/src/core/resources/Session.ts
index a7850e8000..ef04429b66 100644
--- a/packages/clerk-js/src/core/resources/Session.ts
+++ b/packages/clerk-js/src/core/resources/Session.ts
@@ -2,9 +2,9 @@ import { runWithExponentialBackOff } from '@clerk/shared';
import { is4xxError } from '@clerk/shared/error';
import type {
ActJWTClaim,
+ CheckAuthorization,
GetToken,
GetTokenOptions,
- IsAuthorized,
SessionJSON,
SessionResource,
SessionStatus,
@@ -70,8 +70,6 @@ export class Session extends BaseResource implements SessionResource {
return SessionTokenCache.clear();
};
- // TODO: Fix this eslint error
- // eslint-disable-next-line @typescript-eslint/require-await
getToken: GetToken = async (options?: GetTokenOptions): Promise => {
return runWithExponentialBackOff(() => this._getToken(options), {
shouldRetry: (error: unknown, currentIteration: number) => !is4xxError(error) && currentIteration < 4,
@@ -81,48 +79,44 @@ export class Session extends BaseResource implements SessionResource {
/**
* @experimental The method is experimental and subject to change in future releases.
*/
- isAuthorized: IsAuthorized = async params => {
- return new Promise((resolve, reject) => {
- // if there is no active organization user can not be authorized
- if (!this.lastActiveOrganizationId || !this.user) {
- return resolve(false);
- }
+ experimental__checkAuthorization: CheckAuthorization = params => {
+ // if there is no active organization user can not be authorized
+ if (!this.lastActiveOrganizationId || !this.user) {
+ return false;
+ }
- // loop through organizationMemberships from client piggybacking
- const orgMemberships = this.user.organizationMemberships || [];
- const activeMembership = orgMemberships.find(mem => mem.organization.id === this.lastActiveOrganizationId);
+ // loop through organizationMemberships from client piggybacking
+ const orgMemberships = this.user.organizationMemberships || [];
+ const activeMembership = orgMemberships.find(mem => mem.organization.id === this.lastActiveOrganizationId);
- // Based on FAPI this should never happen, but we handle it anyway
- if (!activeMembership) {
- return resolve(false);
- }
+ // Based on FAPI this should never happen, but we handle it anyway
+ if (!activeMembership) {
+ return false;
+ }
- const activeOrganizationPermissions = activeMembership.permissions;
- const activeOrganizationRole = activeMembership.role;
+ const activeOrganizationPermissions = activeMembership.permissions;
+ const activeOrganizationRole = activeMembership.role;
- if (params.permission) {
- return resolve(activeOrganizationPermissions.includes(params.permission));
- }
- if (params.role) {
- return resolve(activeOrganizationRole === params.role);
- }
+ if (params.permission) {
+ return activeOrganizationPermissions.includes(params.permission);
+ }
+ if (params.role) {
+ return activeOrganizationRole === params.role;
+ }
- if (params.any) {
- return resolve(
- !!params.any.find(permObj => {
- if (permObj.permission) {
- return activeOrganizationPermissions.includes(permObj.permission);
- }
- if (permObj.role) {
- return activeOrganizationRole === permObj.role;
- }
- return false;
- }),
- );
- }
+ if (params.some) {
+ return !!params.some.find(permObj => {
+ if (permObj.permission) {
+ return activeOrganizationPermissions.includes(permObj.permission);
+ }
+ if (permObj.role) {
+ return activeOrganizationRole === permObj.role;
+ }
+ return false;
+ });
+ }
- return reject();
- });
+ return false;
};
#hydrateCache = (token: TokenResource | null) => {
diff --git a/packages/clerk-js/src/ui/common/Gate.tsx b/packages/clerk-js/src/ui/common/Gate.tsx
index 7da69f6b22..0c1a016742 100644
--- a/packages/clerk-js/src/ui/common/Gate.tsx
+++ b/packages/clerk-js/src/ui/common/Gate.tsx
@@ -1,12 +1,11 @@
-import type { IsAuthorized } from '@clerk/types';
+import type { CheckAuthorization } from '@clerk/types';
import type { ComponentType, PropsWithChildren, ReactNode } from 'react';
import React, { useEffect } from 'react';
import { useCoreSession } from '../contexts';
-import { useFetch } from '../hooks';
import { useRouter } from '../router';
-type GateParams = Parameters[0];
+type GateParams = Parameters[0];
type GateProps = PropsWithChildren<
GateParams & {
fallback?: ReactNode;
@@ -15,11 +14,10 @@ type GateProps = PropsWithChildren<
>;
export const useGate = (params: GateParams) => {
- const { isAuthorized } = useCoreSession();
- const { data: isAuthorizedUser } = useFetch(isAuthorized, params);
+ const { experimental__checkAuthorization } = useCoreSession();
return {
- isAuthorizedUser,
+ isAuthorizedUser: experimental__checkAuthorization(params),
};
};
diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfileRoutes.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfileRoutes.tsx
index 53fd277bfb..0af1a3cd55 100644
--- a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfileRoutes.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfileRoutes.tsx
@@ -77,7 +77,7 @@ export const OrganizationProfileRoutes = (props: PropsOfComponent
diff --git a/packages/clerk-js/src/ui/utils/test/mockHelpers.ts b/packages/clerk-js/src/ui/utils/test/mockHelpers.ts
index e8dc6477cd..bb03f1628a 100644
--- a/packages/clerk-js/src/ui/utils/test/mockHelpers.ts
+++ b/packages/clerk-js/src/ui/utils/test/mockHelpers.ts
@@ -35,7 +35,7 @@ export const mockClerkMethods = (clerk: LoadedClerk): DeepJestMocked {
mockMethodsOf(session, {
- exclude: ['isAuthorized'],
+ exclude: ['experimental__checkAuthorization'],
});
mockMethodsOf(session.user);
session.user?.emailAddresses.forEach(m => mockMethodsOf(m));
diff --git a/packages/nextjs/src/app-router/server/controlComponents.tsx b/packages/nextjs/src/app-router/server/controlComponents.tsx
index ee3aceacae..ac506a1ec8 100644
--- a/packages/nextjs/src/app-router/server/controlComponents.tsx
+++ b/packages/nextjs/src/app-router/server/controlComponents.tsx
@@ -1,3 +1,5 @@
+import type { experimental__CheckAuthorizationWithoutPermission } from '@clerk/types';
+import { redirect } from 'next/navigation';
import React from 'react';
import { auth } from './auth';
@@ -13,3 +15,38 @@ export function SignedOut(props: React.PropsWithChildren) {
const { userId } = auth();
return userId ? null : <>{children}>;
}
+
+type GateServerComponentProps = React.PropsWithChildren<
+ Parameters[0] & {
+ fallback?: React.ReactNode;
+ redirectTo?: string;
+ }
+>;
+
+/**
+ * @experimental The component is experimental and subject to change in future releases.
+ */
+export function experimental__Gate(gateProps: GateServerComponentProps) {
+ const { children, fallback, redirectTo, ...restAuthorizedParams } = gateProps;
+ const { experimental__has } = auth();
+
+ const isAuthorizedUser = experimental__has(restAuthorizedParams);
+
+ const handleFallback = () => {
+ if (!redirectTo && !fallback) {
+ throw new Error('Provide `` with a `fallback` or `redirectTo`');
+ }
+
+ if (redirectTo) {
+ return redirect(redirectTo);
+ }
+
+ return <>{fallback}>;
+ };
+
+ if (!isAuthorizedUser) {
+ return handleFallback();
+ }
+
+ return <>{children}>;
+}
diff --git a/packages/nextjs/src/client-boundary/controlComponents.ts b/packages/nextjs/src/client-boundary/controlComponents.ts
index 5b7c92e29a..2ce6bb6333 100644
--- a/packages/nextjs/src/client-boundary/controlComponents.ts
+++ b/packages/nextjs/src/client-boundary/controlComponents.ts
@@ -5,6 +5,7 @@ export {
ClerkLoading,
SignedOut,
SignedIn,
+ Experimental__Gate,
RedirectToSignIn,
RedirectToSignUp,
RedirectToUserProfile,
diff --git a/packages/nextjs/src/components.client.ts b/packages/nextjs/src/components.client.ts
index 2fcf82aa99..3bdb446014 100644
--- a/packages/nextjs/src/components.client.ts
+++ b/packages/nextjs/src/components.client.ts
@@ -1,2 +1,2 @@
export { ClerkProvider } from './client-boundary/ClerkProvider';
-export { SignedIn, SignedOut } from './client-boundary/controlComponents';
+export { SignedIn, SignedOut, Experimental__Gate } from './client-boundary/controlComponents';
diff --git a/packages/nextjs/src/components.server.ts b/packages/nextjs/src/components.server.ts
index a18963af32..e002e1b086 100644
--- a/packages/nextjs/src/components.server.ts
+++ b/packages/nextjs/src/components.server.ts
@@ -1,10 +1,11 @@
import { ClerkProvider } from './app-router/server/ClerkProvider';
-import { SignedIn, SignedOut } from './app-router/server/controlComponents';
+import { experimental__Gate, SignedIn, SignedOut } from './app-router/server/controlComponents';
-export { ClerkProvider, SignedOut, SignedIn };
+export { ClerkProvider, SignedOut, SignedIn, experimental__Gate as Experimental__Gate };
export type ServerComponentsServerModuleTypes = {
ClerkProvider: typeof ClerkProvider;
SignedIn: typeof SignedIn;
SignedOut: typeof SignedOut;
+ Experimental__Gate: typeof experimental__Gate;
};
diff --git a/packages/nextjs/src/index.ts b/packages/nextjs/src/index.ts
index ed565c7873..6b4c171424 100644
--- a/packages/nextjs/src/index.ts
+++ b/packages/nextjs/src/index.ts
@@ -93,6 +93,12 @@ export const ClerkProvider = ComponentsModule.ClerkProvider as ServerComponentsS
export const SignedIn = ComponentsModule.SignedIn as ServerComponentsServerModuleTypes['SignedIn'];
export const SignedOut = ComponentsModule.SignedOut as ServerComponentsServerModuleTypes['SignedOut'];
+/**
+ * @experimental
+ */
+export const Experimental__Gate =
+ ComponentsModule.Experimental__Gate as ServerComponentsServerModuleTypes['Experimental__Gate'];
+
export const auth = ServerHelperModule.auth as ServerHelpersServerModuleTypes['auth'];
export const currentUser = ServerHelperModule.currentUser as ServerHelpersServerModuleTypes['currentUser'];
// export const getAuth = ServerHelperModule.getAuth as ServerHelpersServerModuleTypes['getAuth'];
diff --git a/packages/react/src/components/controlComponents.tsx b/packages/react/src/components/controlComponents.tsx
index 2079110210..983a647210 100644
--- a/packages/react/src/components/controlComponents.tsx
+++ b/packages/react/src/components/controlComponents.tsx
@@ -1,10 +1,11 @@
-import type { HandleOAuthCallbackParams } from '@clerk/types';
+import type { experimental__CheckAuthorizationWithoutPermission, HandleOAuthCallbackParams } from '@clerk/types';
import React from 'react';
import { useAuthContext } from '../contexts/AuthContext';
import { useIsomorphicClerkContext } from '../contexts/IsomorphicClerkContext';
import { useSessionContext } from '../contexts/SessionContext';
import { LoadedGuarantee } from '../contexts/StructureContext';
+import { useAuth } from '../hooks';
import type { RedirectToSignInProps, RedirectToSignUpProps, WithClerkProp } from '../types';
import { withClerk } from './withClerk';
@@ -40,6 +41,25 @@ export const ClerkLoading = ({ children }: React.PropsWithChildren): JS
return <>{children}>;
};
+type GateProps = React.PropsWithChildren<
+ Parameters[0] & {
+ fallback?: React.ReactNode;
+ }
+>;
+
+/**
+ * @experimental The component is experimental and subject to change in future releases.
+ */
+export const experimental__Gate = ({ children, fallback, ...restAuthorizedParams }: GateProps) => {
+ const { experimental__has } = useAuth();
+
+ if (experimental__has(restAuthorizedParams)) {
+ return <>{children}>;
+ }
+
+ return <>{fallback ?? null}>;
+};
+
export const RedirectToSignIn = withClerk(({ clerk, ...props }: WithClerkProp) => {
const { client, session } = clerk;
// TODO: Remove temp use of __unstable__environment
diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts
index 1d00b724a3..55c0949dbb 100644
--- a/packages/react/src/components/index.ts
+++ b/packages/react/src/components/index.ts
@@ -14,6 +14,7 @@ export {
ClerkLoading,
SignedOut,
SignedIn,
+ experimental__Gate as Experimental__Gate,
RedirectToSignIn,
RedirectToSignUp,
RedirectToUserProfile,
diff --git a/packages/react/src/hooks/useAuth.ts b/packages/react/src/hooks/useAuth.ts
index 293639e92d..7cfb14f788 100644
--- a/packages/react/src/hooks/useAuth.ts
+++ b/packages/react/src/hooks/useAuth.ts
@@ -1,4 +1,10 @@
-import type { ActJWTClaim, GetToken, MembershipRole, SignOut } from '@clerk/types';
+import type {
+ ActJWTClaim,
+ experimental__CheckAuthorizationWithoutPermission,
+ GetToken,
+ MembershipRole,
+ SignOut,
+} from '@clerk/types';
import { useCallback } from 'react';
import { useAuthContext } from '../contexts/AuthContext';
@@ -7,6 +13,10 @@ import { invalidStateError } from '../errors';
import type IsomorphicClerk from '../isomorphicClerk';
import { createGetToken, createSignOut } from './utils';
+type experimental__CheckAuthorizationSignedOut = (
+ params?: Parameters[0],
+) => false;
+
type UseAuthReturn =
| {
isLoaded: false;
@@ -17,6 +27,10 @@ type UseAuthReturn =
orgId: undefined;
orgRole: undefined;
orgSlug: undefined;
+ /**
+ * @experimental The method is experimental and subject to change in future releases.
+ */
+ experimental__has: experimental__CheckAuthorizationSignedOut;
signOut: SignOut;
getToken: GetToken;
}
@@ -29,6 +43,10 @@ type UseAuthReturn =
orgId: null;
orgRole: null;
orgSlug: null;
+ /**
+ * @experimental The method is experimental and subject to change in future releases.
+ */
+ experimental__has: experimental__CheckAuthorizationSignedOut;
signOut: SignOut;
getToken: GetToken;
}
@@ -41,6 +59,10 @@ type UseAuthReturn =
orgId: null;
orgRole: null;
orgSlug: null;
+ /**
+ * @experimental The method is experimental and subject to change in future releases.
+ */
+ experimental__has: experimental__CheckAuthorizationSignedOut;
signOut: SignOut;
getToken: GetToken;
}
@@ -53,6 +75,10 @@ type UseAuthReturn =
orgId: string;
orgRole: MembershipRole;
orgSlug: string | null;
+ /**
+ * @experimental The method is experimental and subject to change in future releases.
+ */
+ experimental__has: experimental__CheckAuthorizationWithoutPermission;
signOut: SignOut;
getToken: GetToken;
};
@@ -105,6 +131,24 @@ export const useAuth: UseAuth = () => {
const getToken: GetToken = useCallback(createGetToken(isomorphicClerk), [isomorphicClerk]);
const signOut: SignOut = useCallback(createSignOut(isomorphicClerk), [isomorphicClerk]);
+ const has = useCallback(
+ (params?: Parameters[0]) => {
+ if (!orgId || !userId || !orgRole) {
+ return false;
+ }
+
+ if (!params) {
+ return false;
+ }
+
+ if (params.role) {
+ return orgRole === params.role;
+ }
+ return false;
+ },
+ [orgId, orgRole, userId],
+ );
+
if (sessionId === undefined && userId === undefined) {
return {
isLoaded: false,
@@ -115,6 +159,7 @@ export const useAuth: UseAuth = () => {
orgId: undefined,
orgRole: undefined,
orgSlug: undefined,
+ experimental__has: () => false,
signOut,
getToken,
};
@@ -130,6 +175,7 @@ export const useAuth: UseAuth = () => {
orgId: null,
orgRole: null,
orgSlug: null,
+ experimental__has: () => false,
signOut,
getToken,
};
@@ -145,6 +191,7 @@ export const useAuth: UseAuth = () => {
orgId,
orgRole,
orgSlug: orgSlug || null,
+ experimental__has: has,
signOut,
getToken,
};
@@ -160,6 +207,7 @@ export const useAuth: UseAuth = () => {
orgId: null,
orgRole: null,
orgSlug: null,
+ experimental__has: () => false,
signOut,
getToken,
};
diff --git a/packages/react/src/utils/deriveState.ts b/packages/react/src/utils/deriveState.ts
index c22204d279..74770e84ac 100644
--- a/packages/react/src/utils/deriveState.ts
+++ b/packages/react/src/utils/deriveState.ts
@@ -10,10 +10,10 @@ export const deriveState = (clerkLoaded: boolean, state: Resources, initialState
const deriveFromSsrInitialState = (initialState: InitialState) => {
const userId = initialState.userId;
- const user = initialState.user as any as UserResource;
+ const user = initialState.user as UserResource;
const sessionId = initialState.sessionId;
- const session = initialState.session as any as ActiveSessionResource;
- const organization = initialState.organization as any as OrganizationResource;
+ const session = initialState.session as ActiveSessionResource;
+ const organization = initialState.organization as OrganizationResource;
const orgId = initialState.orgId;
const orgRole = initialState.orgRole as MembershipRole;
const orgSlug = initialState.orgSlug;
@@ -46,6 +46,7 @@ const deriveFromClientSideState = (state: Resources) => {
const membership = organization
? user?.organizationMemberships?.find(om => om.organization.id === orgId)
: organization;
+ const orgPermissions = membership ? membership.permissions : membership;
const orgRole = membership ? membership.role : membership;
const lastOrganizationInvitation = state.lastOrganizationInvitation;
@@ -60,6 +61,7 @@ const deriveFromClientSideState = (state: Resources) => {
orgId,
orgRole,
orgSlug,
+ orgPermissions,
actor,
lastOrganizationInvitation,
lastOrganizationMember,
diff --git a/packages/types/src/jwtv2.ts b/packages/types/src/jwtv2.ts
index 21963b8501..14151e8d55 100644
--- a/packages/types/src/jwtv2.ts
+++ b/packages/types/src/jwtv2.ts
@@ -112,5 +112,6 @@ export interface JwtPayload extends CustomJwtSessionClaims {
*/
export interface ActClaim {
sub: string;
+
[x: string]: unknown;
}
diff --git a/packages/types/src/session.ts b/packages/types/src/session.ts
index 3eaecba62e..e6455d2489 100644
--- a/packages/types/src/session.ts
+++ b/packages/types/src/session.ts
@@ -4,11 +4,27 @@ import type { ClerkResource } from './resource';
import type { TokenResource } from './token';
import type { UserResource } from './user';
-export type IsAuthorized = (isAuthorizedParams: IsAuthorizedParams) => Promise;
+export type experimental__CheckAuthorizationWithoutPermission = (
+ isAuthorizedParams: CheckAuthorizationParamsWithoutPermission,
+) => boolean;
-type IsAuthorizedParams =
+type CheckAuthorizationParamsWithoutPermission =
| {
- any: (
+ some: {
+ role: string;
+ }[];
+ role?: never;
+ }
+ | {
+ some?: never;
+ role: string;
+ };
+
+export type CheckAuthorization = (isAuthorizedParams: CheckAuthorizationParams) => boolean;
+
+type CheckAuthorizationParams =
+ | {
+ some: (
| {
role: string;
permission?: never;
@@ -24,20 +40,18 @@ type IsAuthorizedParams =
permission?: never;
}
| {
- any?: never;
+ some?: never;
role: string;
permission?: never;
}
| {
- any?: never;
+ some?: never;
role?: never;
// Adding (string & {}) allows for getting eslint autocomplete but also accepts any string
// eslint-disable-next-line
permission: OrganizationPermission | (string & {});
};
-type IsAuthorizedReturnValues = boolean;
-
export interface SessionResource extends ClerkResource {
id: string;
status: SessionStatus;
@@ -56,7 +70,7 @@ export interface SessionResource extends ClerkResource {
/**
* @experimental The method is experimental and subject to change in future releases.
*/
- isAuthorized: IsAuthorized;
+ experimental__checkAuthorization: CheckAuthorization;
clearCache: () => void;
createdAt: Date;
updatedAt: Date;