Skip to content

Commit 21e9777

Browse files
authored
Revert "feat(server-js): add revokeRefreshToken and logout revocation support…" (#216)
This reverts commit cce3b4c.
1 parent cce3b4c commit 21e9777

11 files changed

Lines changed: 5 additions & 654 deletions

File tree

examples/example-express-web/src/auth0.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,5 @@ export function auth0(options: Auth0ExpressOptions) {
8484
response.redirect(logoutUrl.href);
8585
});
8686

87-
router.post('/auth/revoke', async (request: Request, response: Response) => {
88-
await request.auth0Client.revokeRefreshToken({}, { request, response });
89-
response.redirect('/private');
90-
});
91-
9287
return router;
9388
}
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
This is a private page.
2-
3-
<form method="POST" action="/auth/revoke" class="mt-3">
4-
<button type="submit" class="btn btn-warning">Revoke Refresh Token</button>
5-
</form>
1+
This is a private page.

packages/auth0-auth-js/src/auth-client.spec.ts

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -3992,93 +3992,3 @@ test('database.changePassword request carries the Auth0-Client telemetry header'
39923992
await c.database.changePassword({ email: 'a@b.com', connection: 'db' });
39933993
expect(headers?.get('Auth0-Client')).toBeTruthy();
39943994
});
3995-
3996-
describe('revokeToken', () => {
3997-
const revocationEndpoint = `https://${domain}/oauth/revoke`;
3998-
3999-
const setupRevocationHandlers = (handler: Parameters<typeof http.post>[1]) => {
4000-
server.use(
4001-
http.get(`https://${domain}/.well-known/openid-configuration`, () =>
4002-
HttpResponse.json({ ...buildOpenIdConfiguration(domain), revocation_endpoint: revocationEndpoint })
4003-
),
4004-
http.post(revocationEndpoint, handler)
4005-
);
4006-
};
4007-
4008-
const makeClient = () =>
4009-
new AuthClient({
4010-
domain,
4011-
clientId: '<client_id>',
4012-
clientSecret: '<client_secret>',
4013-
discoveryCache: { ttl: 0 },
4014-
});
4015-
4016-
test('should successfully revoke a token', async () => {
4017-
let capturedToken: string | null = null;
4018-
let capturedHint: string | null = null;
4019-
setupRevocationHandlers(async ({ request }) => {
4020-
const body = await request.formData();
4021-
capturedToken = body.get('token') as string;
4022-
capturedHint = body.get('token_type_hint') as string;
4023-
return new HttpResponse(null, { status: 200 });
4024-
});
4025-
4026-
await expect(
4027-
makeClient().revokeToken({ token: '<refresh_token>', tokenTypeHint: 'refresh_token' })
4028-
).resolves.toBeUndefined();
4029-
expect(capturedToken).toBe('<refresh_token>');
4030-
expect(capturedHint).toBe('refresh_token');
4031-
});
4032-
4033-
test('should revoke a token without tokenTypeHint', async () => {
4034-
let capturedHint: FormDataEntryValue | null = null;
4035-
setupRevocationHandlers(async ({ request }) => {
4036-
const body = await request.formData();
4037-
capturedHint = body.get('token_type_hint');
4038-
return new HttpResponse(null, { status: 200 });
4039-
});
4040-
4041-
await expect(
4042-
makeClient().revokeToken({ token: '<refresh_token>' })
4043-
).resolves.toBeUndefined();
4044-
expect(capturedHint).toBeNull();
4045-
});
4046-
4047-
test('should throw TokenRevocationError when revocation fails', async () => {
4048-
setupRevocationHandlers(() =>
4049-
HttpResponse.json(
4050-
{ error: '<error_code>', error_description: '<error_description>' },
4051-
{ status: 400 }
4052-
)
4053-
);
4054-
4055-
await expect(
4056-
makeClient().revokeToken({ token: '<invalid_token>' })
4057-
).rejects.toThrowError(
4058-
expect.objectContaining({
4059-
code: 'token_revocation_error',
4060-
message: 'An error occurred while trying to revoke the token.',
4061-
cause: expect.objectContaining({
4062-
error: '<error_code>',
4063-
error_description: '<error_description>',
4064-
}),
4065-
})
4066-
);
4067-
});
4068-
4069-
test('should send client credentials on the revocation request', async () => {
4070-
let capturedClientId: string | null = null;
4071-
let capturedClientSecret: string | null = null;
4072-
setupRevocationHandlers(async ({ request }) => {
4073-
const body = await request.formData();
4074-
capturedClientId = body.get('client_id') as string;
4075-
capturedClientSecret = body.get('client_secret') as string;
4076-
return new HttpResponse(null, { status: 200 });
4077-
});
4078-
4079-
await makeClient().revokeToken({ token: '<refresh_token>', tokenTypeHint: 'refresh_token' });
4080-
4081-
expect(capturedClientId).toBe('<client_id>');
4082-
expect(capturedClientSecret).toBe('<client_secret>');
4083-
});
4084-
});

packages/auth0-auth-js/src/auth-client.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
BuildLinkUserUrlError,
88
BuildUnlinkUserUrlError,
99
TokenExchangeError,
10-
TokenRevocationError,
1110
MissingClientAuthError,
1211
NotSupportedError,
1312
NotSupportedErrorCode,
@@ -47,7 +46,6 @@ import {
4746
TokenByPasswordlessEmailOptions,
4847
TokenByPasswordlessSmsOptions,
4948
TokenByRefreshTokenOptions,
50-
RevokeTokenOptions,
5149
TokenForConnectionOptions,
5250
TokenResponse,
5351
ActClaim,
@@ -1115,27 +1113,6 @@ export class AuthClient {
11151113
}
11161114
}
11171115

1118-
/**
1119-
* Revokes a token at the Auth0 /oauth/revoke endpoint.
1120-
*
1121-
* @throws {TokenRevocationError} If the revocation request fails.
1122-
*/
1123-
public async revokeToken(options: RevokeTokenOptions): Promise<void> {
1124-
const { configuration } = await this.#discover();
1125-
const params: Record<string, string> = {};
1126-
if (options.tokenTypeHint) {
1127-
params['token_type_hint'] = options.tokenTypeHint;
1128-
}
1129-
try {
1130-
await client.tokenRevocation(configuration, options.token, params);
1131-
} catch (e) {
1132-
throw new TokenRevocationError(
1133-
'An error occurred while trying to revoke the token.',
1134-
toOAuth2Error(e)
1135-
);
1136-
}
1137-
}
1138-
11391116
/**
11401117
* Retrieves a token using Resource Owner Password Grant.
11411118
* @param options Options for authenticating with username and password.

packages/auth0-auth-js/src/errors.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,6 @@ export class TokenExchangeError extends ApiError {
171171
}
172172
}
173173

174-
/**
175-
* Error thrown when revoking a token fails.
176-
*/
177-
export class TokenRevocationError extends ApiError {
178-
constructor(message: string, cause?: OAuth2Error) {
179-
super('token_revocation_error', message, cause);
180-
this.name = 'TokenRevocationError';
181-
}
182-
}
183-
184174
/**
185175
* Error thrown when verifying the logout token.
186176
*/

packages/auth0-auth-js/src/types.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -605,13 +605,6 @@ export interface TokenVaultExchangeOptions {
605605
extra?: Record<string, string | string[]>;
606606
}
607607

608-
export interface RevokeTokenOptions {
609-
/** The token to revoke. */
610-
token: string;
611-
/** Hint about the token type. Per RFC 7009. */
612-
tokenTypeHint?: 'refresh_token' | 'access_token';
613-
}
614-
615608
export interface BuildLogoutUrlOptions {
616609
/**
617610
* The URL to which the user should be redirected after the logout.

packages/auth0-server-js/EXAMPLES.md

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@
5858
- [Passing `StoreOptions`](#passing-storeoptions-9)
5959
- [Retrieving an Access Token for a Connection](#retrieving-an-access-token-for-a-connection)
6060
- [Passing `StoreOptions`](#passing-storeoptions-10)
61-
- [Revoking a Refresh Token](#revoking-a-refresh-token)
62-
- [Revoking the session token](#revoking-the-session-token)
63-
- [Revoking an explicit token](#revoking-an-explicit-token)
64-
- [Revoking on logout](#revoking-on-logout)
6561
- [Logout](#logout)
6662
- [Passing the `returnTo` parameter](#passing-the-returnto-parameter)
6763
- [Passing `StoreOptions`](#passing-storeoptions-11)
@@ -1477,45 +1473,6 @@ Once an enterprise connection has the option enabled, `getSession()` / `getUser(
14771473
- The connection must be an `okta` or `oidc` enterprise connection with `id_token_session_expiry_supported: true` (Dashboard toggle "Use ID Token for Session Expiry", Management API, or Terraform).
14781474
- Authorization Code flow.
14791475
1480-
## Revoking a Refresh Token
1481-
1482-
Revoking a refresh token invalidates it at Auth0 so it can no longer be used to obtain new access tokens.
1483-
This is useful when implementing secure logout flows or when a user's session needs to be forcibly terminated.
1484-
1485-
Revocation requires the application to have been granted `offline_access` scope so Auth0 issues a refresh token, and the target API must have **Allow Offline Access** enabled.
1486-
1487-
> **Note:** Revocation does not affect access tokens that have already been issued. They remain valid until their expiry. For immediate session termination, combine revocation with `logout()`.
1488-
1489-
### Revoking the session token
1490-
1491-
When called without arguments, `revokeRefreshToken()` reads the refresh token directly from the current session:
1492-
1493-
```ts
1494-
await serverClient.revokeRefreshToken();
1495-
```
1496-
1497-
If no session exists or the session has no refresh token, a `MissingSessionError` is thrown.
1498-
1499-
### Revoking an explicit token
1500-
1501-
A specific token can be passed via `options.token`, bypassing the session lookup:
1502-
1503-
```ts
1504-
await serverClient.revokeRefreshToken({ token: '<refresh_token>' });
1505-
```
1506-
1507-
### Revoking on logout
1508-
1509-
`logout()` automatically revokes the session's refresh token before clearing the local session.
1510-
Revocation is best-effort: if it fails for any reason (network error, token already revoked, misconfiguration), logout still proceeds. In resolver mode, both revocation and local session deletion only occur when the stored session domain matches the resolved domain — if they differ, the session belongs to a different tenant and is left untouched.
1511-
1512-
```ts
1513-
const logoutUrl = await serverClient.logout({
1514-
returnTo: 'http://localhost:3000',
1515-
});
1516-
// Redirect user to logoutUrl
1517-
```
1518-
15191476
## Logout
15201477
15211478
Logging out ensures the stored tokens and user information are removed, and that the user is no longer considered logged-in by the SDK.

packages/auth0-server-js/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export { ServerClient } from './server-client.js';
22
export { AbstractStateStore } from './store/abstract-state-store.js';
33
export { AbstractTransactionStore } from './store/abstract-transaction-store.js';
44
export type { TokenResponse, ActClaim } from '@auth0/auth0-auth-js';
5-
export { TokenExchangeError, TokenRevocationError, MissingClientAuthError, OrganizationValidationError } from '@auth0/auth0-auth-js';
5+
export { TokenExchangeError, MissingClientAuthError, OrganizationValidationError } from '@auth0/auth0-auth-js';
66

77
export type { CookieHandler, CookieSerializeOptions } from './store/cookie-handler.js';
88
export { CookieTransactionStore } from './store/cookie-transaction-store.js';

0 commit comments

Comments
 (0)