fix(auth0): skip profile cache when id_token has no sub claim
When the JWT id_token lacks a sub claim, the cache key would be auth0-profile:undefined, causing all users without a sub to share the same cached profile. Now skips caching entirely when sub is missing and fetches the profile directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
This commit is contained in:
@@ -242,4 +242,47 @@ describe('createAuth0Authenticator', () => {
|
||||
expect(mockFetchProfile).toHaveBeenCalledTimes(2);
|
||||
expect(result.fullProfile).toEqual(updatedProfile);
|
||||
});
|
||||
|
||||
it('should skip cache when id_token has no sub claim', async () => {
|
||||
const header = Buffer.from(JSON.stringify({ alg: 'none' })).toString(
|
||||
'base64url',
|
||||
);
|
||||
const payload = Buffer.from(JSON.stringify({ aud: 'test' })).toString(
|
||||
'base64url',
|
||||
);
|
||||
const idTokenWithoutSub = `${header}.${payload}.`;
|
||||
|
||||
mockExecuteRefresh.mockResolvedValue({
|
||||
accessToken: 'new-access-token',
|
||||
refreshToken: 'new-refresh-token',
|
||||
params: {
|
||||
token_type: 'bearer',
|
||||
scope: 'openid profile',
|
||||
expires_in: 3600,
|
||||
id_token: idTokenWithoutSub,
|
||||
},
|
||||
});
|
||||
|
||||
const authenticator = createAuth0Authenticator({ cache });
|
||||
const ctx = authenticator.initialize({
|
||||
callbackUrl: 'http://localhost/callback',
|
||||
config: mockConfig,
|
||||
});
|
||||
|
||||
const result = await authenticator.refresh(
|
||||
{
|
||||
refreshToken: 'my-refresh-token',
|
||||
scope: 'openid profile',
|
||||
req: {} as express.Request,
|
||||
},
|
||||
ctx,
|
||||
);
|
||||
|
||||
// Profile is fetched directly
|
||||
expect(mockFetchProfile).toHaveBeenCalledWith('new-access-token');
|
||||
expect(result.fullProfile).toEqual(mockProfile);
|
||||
// Cache is never read or written
|
||||
expect(cache.get).not.toHaveBeenCalled();
|
||||
expect(cache.set).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -140,17 +140,20 @@ export function createAuth0Authenticator(options?: { cache?: CacheService }) {
|
||||
);
|
||||
|
||||
const { sub } = decodeJwt(result.params.id_token);
|
||||
const cacheKey = `auth0-profile:${sub}`;
|
||||
let fullProfile = (await profileCache?.get(cacheKey)) as
|
||||
| PassportProfile
|
||||
| undefined;
|
||||
const cacheKey = sub ? `auth0-profile:${sub}` : undefined;
|
||||
|
||||
let fullProfile = cacheKey
|
||||
? ((await profileCache?.get(cacheKey)) as PassportProfile | undefined)
|
||||
: undefined;
|
||||
|
||||
if (!fullProfile) {
|
||||
fullProfile = await helper.fetchProfile(result.accessToken);
|
||||
await profileCache?.set(
|
||||
cacheKey,
|
||||
JSON.parse(JSON.stringify(fullProfile)),
|
||||
);
|
||||
if (cacheKey) {
|
||||
await profileCache?.set(
|
||||
cacheKey,
|
||||
JSON.parse(JSON.stringify(fullProfile)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user