Skip to content

Commit

Permalink
feat(clerk-js): Session.isAuthorized now support the any parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
panteliselef committed Oct 18, 2023
1 parent 27448e7 commit ef2dff3
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 16 deletions.
13 changes: 11 additions & 2 deletions packages/clerk-js/src/core/resources/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ 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 => {
return new Promise((resolve, reject) => {
// if there is no active organization user can not be authorized
if (!this.lastActiveOrganizationId || !this.user) {
return resolve(false);
Expand All @@ -106,8 +106,17 @@ export class Session extends BaseResource implements SessionResource {
}

if (params.any) {
return resolve(params.any.filter(perm => activeOrganizationPermissions.includes(perm)).length > 0);
return resolve(
params.any.filter(permObj => {
if (permObj.permission) {
return activeOrganizationPermissions.includes(permObj.permission);
}
return activeOrganizationRole === permObj.role;
}).length > 0,
);
}

return reject();
});
};

Expand Down
4 changes: 2 additions & 2 deletions packages/clerk-js/src/ui/common/Gate.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { IsAuthorized, OrganizationPermission } from '@clerk/types';
import type { IsAuthorized } 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 = Omit<Parameters<IsAuthorized>[0], 'permission'> & { permission?: OrganizationPermission };
type GateParams = Parameters<IsAuthorized>[0];
type GateProps = PropsWithChildren<
GateParams & {
fallback?: ReactNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const OrganizationProfileRoutes = (props: PropsOfComponent<typeof Profile
</Route>
<Route path=':id'>
<Gate
any={['org:sys_domains:manage', 'org:sys_domains:delete']}
any={[{ permission: 'org:sys_domains:manage' }, { permission: 'org:sys_domains:delete' }]}
redirectTo='../../'
>
<VerifiedDomainPage />
Expand Down
13 changes: 11 additions & 2 deletions packages/clerk-js/src/ui/utils/test/mockHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const mockClerkMethods = (clerk: LoadedClerk): DeepJestMocked<LoadedClerk
clerk.client.sessions.forEach(session => {
mockMethodsOf(session);
session.isAuthorized = jest.fn(args => {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
// if there is no active organization user can not be authorized
if (!session.lastActiveOrganizationId || !session.user) {
return resolve(false);
Expand All @@ -57,8 +57,17 @@ export const mockClerkMethods = (clerk: LoadedClerk): DeepJestMocked<LoadedClerk
}

if (args.any) {
return resolve(args.any.filter(perm => activeOrganizationPermissions.includes(perm)).length > 0);
return resolve(
args.any.filter(permObj => {
if (permObj.permission) {
return activeOrganizationPermissions.includes(permObj.permission);
}
return activeOrganizationRole === permObj.role;
}).length > 0,
);
}

return reject(false);
});
});
mockMethodsOf(session.user);
Expand Down
38 changes: 29 additions & 9 deletions packages/types/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,35 @@ import type { UserResource } from './user';

export type IsAuthorized = (isAuthorizedParams: IsAuthorizedParams) => Promise<IsAuthorizedReturnValues>;

interface IsAuthorizedParams {
// Adding (string & {}) allows for getting eslint autocomplete but also accepts any string
// eslint-disable-next-line
permission?: OrganizationPermission | (string & {});
role?: string;
// Adding (string & {}) allows for getting eslint autocomplete but also accepts any string
// eslint-disable-next-line
any?: (OrganizationPermission | (string & {}))[];
}
type IsAuthorizedParams =
| {
any: (
| {
role: string;
permission?: never;
}
| {
role?: never;
// Adding (string & {}) allows for getting eslint autocomplete but also accepts any string
// eslint-disable-next-line
permission: OrganizationPermission | (string & {});
}
)[];
role?: never;
permission?: never;
}
| {
any?: never;
role: string;
permission?: never;
}
| {
any?: 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;

Expand Down

0 comments on commit ef2dff3

Please sign in to comment.