Skip to content

Commit da415c8

Browse files
authored
feat(react,shared): Ensure has is always defined (#7458)
1 parent 7ea89a4 commit da415c8

File tree

5 files changed

+41
-34
lines changed

5 files changed

+41
-34
lines changed

.changeset/steady-has-default.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@clerk/react': patch
3+
'@clerk/shared': patch
4+
---
5+
6+
Ensure `useAuth().has` is always defined by defaulting to false when auth data is missing.

packages/react/src/hooks/__tests__/useAuth.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ describe('useDerivedAuth', () => {
9898
expect(current.orgId).toBeUndefined();
9999
expect(current.orgRole).toBeUndefined();
100100
expect(current.orgSlug).toBeUndefined();
101-
expect(current.has).toBeUndefined();
101+
expect(current.has).toBeInstanceOf(Function);
102+
expect(current.has?.({ permission: 'test' })).toBe(false);
102103
});
103104

104105
it('returns loaded but not signed in when sessionId and userId are null', () => {

packages/react/src/hooks/__tests__/useAuth.type.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { describe, expectTypeOf, it } from 'vitest';
44
import type { useAuth } from '../useAuth';
55

66
type UseAuthParameters = Parameters<typeof useAuth>[0];
7-
type HasFunction = Exclude<ReturnType<typeof useAuth>['has'], undefined>;
7+
type HasFunction = ReturnType<typeof useAuth>['has'];
88
type ParamsOfHas = Parameters<HasFunction>[0];
99

1010
describe('useAuth type tests', () => {

packages/shared/src/authorization.ts

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -260,86 +260,86 @@ const resolveAuthState = ({
260260
}: AuthStateOptions): UseAuthReturn | undefined => {
261261
if (sessionId === undefined && userId === undefined) {
262262
return {
263+
actor: undefined,
264+
getToken,
265+
has: () => false,
263266
isLoaded: false,
264267
isSignedIn: undefined,
265-
sessionId,
266-
sessionClaims: undefined,
267-
userId,
268-
actor: undefined,
269268
orgId: undefined,
270269
orgRole: undefined,
271270
orgSlug: undefined,
272-
has: undefined,
271+
sessionClaims: undefined,
272+
sessionId,
273273
signOut,
274-
getToken,
274+
userId,
275275
} as const;
276276
}
277277

278278
if (sessionId === null && userId === null) {
279279
return {
280+
actor: null,
281+
getToken,
282+
has: () => false,
280283
isLoaded: true,
281284
isSignedIn: false,
282-
sessionId,
283-
userId,
284-
sessionClaims: null,
285-
actor: null,
286285
orgId: null,
287286
orgRole: null,
288287
orgSlug: null,
289-
has: () => false,
288+
sessionClaims: null,
289+
sessionId,
290290
signOut,
291-
getToken,
291+
userId,
292292
} as const;
293293
}
294294

295295
if (treatPendingAsSignedOut && sessionStatus === 'pending') {
296296
return {
297+
actor: null,
298+
getToken,
299+
has: () => false,
297300
isLoaded: true,
298301
isSignedIn: false,
299-
sessionId: null,
300-
userId: null,
301-
sessionClaims: null,
302-
actor: null,
303302
orgId: null,
304303
orgRole: null,
305304
orgSlug: null,
306-
has: () => false,
305+
sessionClaims: null,
306+
sessionId: null,
307307
signOut,
308-
getToken,
308+
userId: null,
309309
} as const;
310310
}
311311

312312
if (!!sessionId && !!sessionClaims && !!userId && !!orgId && !!orgRole) {
313313
return {
314+
actor: actor || null,
315+
getToken,
316+
has,
314317
isLoaded: true,
315318
isSignedIn: true,
316-
sessionId,
317-
sessionClaims,
318-
userId,
319-
actor: actor || null,
320319
orgId,
321320
orgRole,
322321
orgSlug: orgSlug || null,
323-
has,
322+
sessionClaims,
323+
sessionId,
324324
signOut,
325-
getToken,
325+
userId,
326326
} as const;
327327
}
328328

329329
if (!!sessionId && !!sessionClaims && !!userId && !orgId) {
330330
return {
331+
actor: actor || null,
332+
getToken,
333+
has,
331334
isLoaded: true,
332335
isSignedIn: true,
333-
sessionId,
334-
sessionClaims,
335-
userId,
336-
actor: actor || null,
337336
orgId: null,
338337
orgRole: null,
339338
orgSlug: null,
340-
has,
339+
sessionClaims,
340+
sessionId,
341341
signOut,
342-
getToken,
342+
userId,
343343
} as const;
344344
}
345345
};

packages/shared/src/types/hooks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import type { UserResource } from './user';
1414
/**
1515
* @inline
1616
*/
17-
type CheckAuthorizationSignedOut = undefined;
17+
type CheckAuthorizationWithoutOrgOrUser = (params: Parameters<CheckAuthorizationWithCustomPermissions>[0]) => false;
1818
/**
1919
* @inline
2020
*/
21-
type CheckAuthorizationWithoutOrgOrUser = (params: Parameters<CheckAuthorizationWithCustomPermissions>[0]) => false;
21+
type CheckAuthorizationSignedOut = CheckAuthorizationWithoutOrgOrUser;
2222

2323
/**
2424
* @inline

0 commit comments

Comments
 (0)