Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 554242e

Browse files
panteliselefijxy
andauthored
feat(clerk-js,clerk-react): Introduce sessionClaims in useAuth() (#5565)
Signed-off-by: panteliselef <[email protected]> Co-authored-by: ijxy <[email protected]>
1 parent f17e445 commit 554242e

File tree

16 files changed

+125
-27
lines changed

16 files changed

+125
-27
lines changed

.changeset/cuddly-cars-stop.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
'@clerk/clerk-react': minor
4+
'@clerk/types': minor
5+
---
6+
7+
Introduce `sessionClaims` to useAuth().
8+
- thanks to [@ijxy](https://github.com/ijxy) for the [contribution](https://github.com/clerk/javascript/pull/4823)

packages/clerk-js/bundlewatch.config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"files": [
33
{ "path": "./dist/clerk.js", "maxSize": "590kB" },
4-
{ "path": "./dist/clerk.browser.js", "maxSize": "73.4KB" },
4+
{ "path": "./dist/clerk.browser.js", "maxSize": "73.5KB" },
55
{ "path": "./dist/clerk.headless*.js", "maxSize": "55KB" },
66
{ "path": "./dist/ui-common*.js", "maxSize": "99KB" },
77
{ "path": "./dist/vendors*.js", "maxSize": "36KB" },

packages/clerk-js/src/core/clerk.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,15 @@ export class Clerk implements ClerkInterface {
381381

382382
this.#options = this.#initOptions(options);
383383

384+
/**
385+
* Listen to `Session.getToken` resolving to emit the updated session
386+
* with the new token to the state listeners.
387+
*/
388+
eventBus.on(events.SessionTokenResolved, () => {
389+
this.#setAccessors(this.session);
390+
this.#emit();
391+
});
392+
384393
assertNoLegacyProp(this.#options);
385394

386395
if (this.#options.sdkMetadata) {

packages/clerk-js/src/core/events.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const events = {
55
TokenUpdate: 'token:update',
66
UserSignOut: 'user:signOut',
77
EnvironmentUpdate: 'environment:update',
8+
SessionTokenResolved: 'session:tokenResolved',
89
} as const;
910

1011
type TokenUpdatePayload = { token: TokenResource | null };
@@ -13,6 +14,7 @@ type InternalEvents = {
1314
[events.TokenUpdate]: TokenUpdatePayload;
1415
[events.UserSignOut]: null;
1516
[events.EnvironmentUpdate]: null;
17+
[events.SessionTokenResolved]: null;
1618
};
1719

1820
export const eventBus = createEventBus<InternalEvents>();

packages/clerk-js/src/core/resources/Session.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,12 @@ export class Session extends BaseResource implements SessionResource {
367367
return tokenResolver.then(token => {
368368
if (shouldDispatchTokenUpdate) {
369369
eventBus.emit(events.TokenUpdate, { token });
370+
371+
if (token.jwt) {
372+
this.lastActiveToken = token;
373+
// Emits the updated session with the new token to the state listeners
374+
eventBus.emit(events.SessionTokenResolved, null);
375+
}
370376
}
371377
// Return null when raw string is empty to indicate that there it's signed-out
372378
return token.getRawString() || null;

packages/clerk-js/src/core/resources/__tests__/Session.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ describe('Session', () => {
4646

4747
await session.getToken();
4848

49-
expect(dispatchSpy).toHaveBeenCalledTimes(1);
49+
expect(dispatchSpy).toHaveBeenCalledTimes(2);
5050
expect(dispatchSpy.mock.calls[0]).toMatchSnapshot();
51+
expect(dispatchSpy.mock.calls[1]).toMatchSnapshot();
5152
});
5253

5354
it('hydrates token cache from lastActiveToken', async () => {
@@ -95,8 +96,9 @@ describe('Session', () => {
9596

9697
await session.getToken();
9798

98-
expect(dispatchSpy).toHaveBeenCalledTimes(1);
99+
expect(dispatchSpy).toHaveBeenCalledTimes(2);
99100
expect(dispatchSpy.mock.calls[0]).toMatchSnapshot();
101+
expect(dispatchSpy.mock.calls[1]).toMatchSnapshot();
100102
});
101103

102104
it('does not dispatch token:update if template is provided', async () => {
@@ -138,7 +140,7 @@ describe('Session', () => {
138140

139141
await session.getToken({ organizationId: 'activeOrganization' });
140142

141-
expect(dispatchSpy).toHaveBeenCalledTimes(1);
143+
expect(dispatchSpy).toHaveBeenCalledTimes(2);
142144
});
143145

144146
it('does not dispatch token:update when provided organization ID does not match current active organization', async () => {

packages/clerk-js/src/core/resources/__tests__/__snapshots__/Session.test.ts.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ exports[`Session getToken() dispatches token:update event on getToken with activ
3434
]
3535
`;
3636

37+
exports[`Session getToken() dispatches token:update event on getToken with active organization 2`] = `
38+
[
39+
"session:tokenResolved",
40+
null,
41+
]
42+
`;
43+
3744
exports[`Session getToken() dispatches token:update event on getToken without active organization 1`] = `
3845
[
3946
"token:update",
@@ -67,3 +74,10 @@ exports[`Session getToken() dispatches token:update event on getToken without ac
6774
},
6875
]
6976
`;
77+
78+
exports[`Session getToken() dispatches token:update event on getToken without active organization 2`] = `
79+
[
80+
"session:tokenResolved",
81+
null,
82+
]
83+
`;

packages/clerk-js/src/utils/memoizeStateListenerCallback.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ function sessionChanged(prev: SessionResource, next: SessionResource): boolean {
3232
return (
3333
prev.id !== next.id ||
3434
prev.updatedAt.getTime() < next.updatedAt.getTime() ||
35-
sessionFVAChanged(prev, next) ||
35+
// TODO: Optimize this to once JWT v2 formatting is out.
36+
prev.lastActiveToken?.jwt?.claims?.__raw !== next.lastActiveToken?.jwt?.claims?.__raw ||
3637
sessionUserMembershipPermissionsChanged(prev, next) ||
3738
sessionUserChanged(prev, next)
3839
);
@@ -53,15 +54,6 @@ function userMembershipsChanged(prev: UserResource, next: UserResource): boolean
5354
);
5455
}
5556

56-
function sessionFVAChanged(prev: SessionResource, next: SessionResource): boolean {
57-
const prevFVA = prev.factorVerificationAge;
58-
const nextFVA = next.factorVerificationAge;
59-
if (prevFVA !== null && nextFVA !== null) {
60-
return prevFVA[0] !== nextFVA[0] || prevFVA[1] !== nextFVA[1];
61-
}
62-
return prevFVA !== nextFVA;
63-
}
64-
6557
function sessionUserChanged(prev: SessionResource, next: SessionResource): boolean {
6658
if (!!prev.user !== !!next.user) {
6759
return true;
@@ -82,10 +74,7 @@ function sessionUserMembershipPermissionsChanged(prev: SessionResource, next: Se
8274
mem => mem.organization.id === prev.lastActiveOrganizationId,
8375
);
8476

85-
return (
86-
prevActiveMembership?.role !== nextActiveMembership?.role ||
87-
prevActiveMembership?.permissions?.length !== nextActiveMembership?.permissions?.length
88-
);
77+
return prevActiveMembership?.permissions?.length !== nextActiveMembership?.permissions?.length;
8978
}
9079

9180
// TODO: Decide if this belongs in the resources

packages/react/src/contexts/AuthContext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createContextAndHook } from '@clerk/shared/react';
22
import type {
33
ActClaim,
4+
JwtPayload,
45
OrganizationCustomPermissionKey,
56
OrganizationCustomRoleKey,
67
SessionStatusClaim,
@@ -10,6 +11,7 @@ export type AuthContextValue = {
1011
userId: string | null | undefined;
1112
sessionId: string | null | undefined;
1213
sessionStatus: SessionStatusClaim | null | undefined;
14+
sessionClaims: JwtPayload | null | undefined;
1315
actor: ActClaim | null | undefined;
1416
orgId: string | null | undefined;
1517
orgRole: OrganizationCustomRoleKey | null | undefined;

packages/react/src/contexts/ClerkContextProvider.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export function ClerkContextProvider(props: ClerkContextProvider) {
3838
const {
3939
sessionId,
4040
sessionStatus,
41+
sessionClaims,
4142
session,
4243
userId,
4344
user,
@@ -54,6 +55,7 @@ export function ClerkContextProvider(props: ClerkContextProvider) {
5455
const value = {
5556
sessionId,
5657
sessionStatus,
58+
sessionClaims,
5759
userId,
5860
actor,
5961
orgId,
@@ -63,7 +65,8 @@ export function ClerkContextProvider(props: ClerkContextProvider) {
6365
factorVerificationAge,
6466
};
6567
return { value };
66-
}, [sessionId, sessionStatus, userId, actor, orgId, orgRole, orgSlug, factorVerificationAge]);
68+
}, [sessionId, sessionStatus, userId, actor, orgId, orgRole, orgSlug, factorVerificationAge, sessionClaims?.__raw]);
69+
6770
const sessionCtx = React.useMemo(() => ({ value: session }), [sessionId, session]);
6871
const userCtx = React.useMemo(() => ({ value: user }), [userId, user]);
6972
const organizationCtx = React.useMemo(() => {

0 commit comments

Comments
 (0)