Skip to content

Commit 80c9737

Browse files
committed
Introduce throwErrors property on middlewares and handlers
1 parent ce420f8 commit 80c9737

File tree

6 files changed

+69
-8
lines changed

6 files changed

+69
-8
lines changed

src/server/auth/handlers/authorize.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export type AuthorizationHandlerOptions = {
1313
* Set to false to disable rate limiting for this endpoint.
1414
*/
1515
rateLimit?: Partial<RateLimitOptions> | false;
16+
17+
/**
18+
* Set to true to throw errors to the express error handler
19+
*/
20+
throwErrors?: boolean;
1621
};
1722

1823
// Parameters that must be validated in order to issue redirects.
@@ -34,7 +39,7 @@ const RequestAuthorizationParamsSchema = z.object({
3439
resource: z.string().url().optional()
3540
});
3641

37-
export function authorizationHandler({ provider, rateLimit: rateLimitConfig }: AuthorizationHandlerOptions): RequestHandler {
42+
export function authorizationHandler({ provider, rateLimit: rateLimitConfig, throwErrors }: AuthorizationHandlerOptions): RequestHandler {
3843
// Create a router to apply middleware
3944
const router = express.Router();
4045
router.use(allowedMethods(['GET', 'POST']));
@@ -101,6 +106,10 @@ export function authorizationHandler({ provider, rateLimit: rateLimitConfig }: A
101106
res.status(500).json(serverError.toResponseObject());
102107
}
103108

109+
if (throwErrors) {
110+
throw error;
111+
}
112+
104113
return;
105114
}
106115

@@ -142,6 +151,10 @@ export function authorizationHandler({ provider, rateLimit: rateLimitConfig }: A
142151
const serverError = new ServerError('Internal Server Error');
143152
res.redirect(302, createErrorRedirect(redirect_uri, serverError, state));
144153
}
154+
155+
if (throwErrors) {
156+
throw error;
157+
}
145158
}
146159
});
147160

src/server/auth/handlers/register.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export type ClientRegistrationHandlerOptions = {
3333
* If not set, defaults to true.
3434
*/
3535
clientIdGeneration?: boolean;
36+
37+
/**
38+
* Set to true to throw errors to the express error handler
39+
*/
40+
throwErrors?: boolean;
3641
};
3742

3843
const DEFAULT_CLIENT_SECRET_EXPIRY_SECONDS = 30 * 24 * 60 * 60; // 30 days
@@ -41,7 +46,8 @@ export function clientRegistrationHandler({
4146
clientsStore,
4247
clientSecretExpirySeconds = DEFAULT_CLIENT_SECRET_EXPIRY_SECONDS,
4348
rateLimit: rateLimitConfig,
44-
clientIdGeneration = true
49+
clientIdGeneration = true,
50+
throwErrors
4551
}: ClientRegistrationHandlerOptions): RequestHandler {
4652
if (!clientsStore.registerClient) {
4753
throw new Error('Client registration store does not support registering clients');
@@ -112,6 +118,10 @@ export function clientRegistrationHandler({
112118
const serverError = new ServerError('Internal Server Error');
113119
res.status(500).json(serverError.toResponseObject());
114120
}
121+
122+
if (throwErrors) {
123+
throw error;
124+
}
115125
}
116126
});
117127

src/server/auth/handlers/revoke.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ export type RevocationHandlerOptions = {
1414
* Set to false to disable rate limiting for this endpoint.
1515
*/
1616
rateLimit?: Partial<RateLimitOptions> | false;
17+
18+
throwErrors?: boolean;
1719
};
1820

19-
export function revocationHandler({ provider, rateLimit: rateLimitConfig }: RevocationHandlerOptions): RequestHandler {
21+
export function revocationHandler({ provider, rateLimit: rateLimitConfig, throwErrors }: RevocationHandlerOptions): RequestHandler {
2022
if (!provider.revokeToken) {
2123
throw new Error('Auth provider does not support revoking tokens');
2224
}
@@ -72,6 +74,10 @@ export function revocationHandler({ provider, rateLimit: rateLimitConfig }: Revo
7274
const serverError = new ServerError('Internal Server Error');
7375
res.status(500).json(serverError.toResponseObject());
7476
}
77+
78+
if (throwErrors) {
79+
throw error;
80+
}
7581
}
7682
});
7783

src/server/auth/handlers/token.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export type TokenHandlerOptions = {
2222
* Set to false to disable rate limiting for this endpoint.
2323
*/
2424
rateLimit?: Partial<RateLimitOptions> | false;
25+
26+
/**
27+
* Set to true to throw errors to the express error handler
28+
*/
29+
throwErrors?: boolean;
2530
};
2631

2732
const TokenRequestSchema = z.object({
@@ -41,7 +46,7 @@ const RefreshTokenGrantSchema = z.object({
4146
resource: z.string().url().optional()
4247
});
4348

44-
export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHandlerOptions): RequestHandler {
49+
export function tokenHandler({ provider, rateLimit: rateLimitConfig, throwErrors }: TokenHandlerOptions): RequestHandler {
4550
// Nested router so we can configure middleware and restrict HTTP method
4651
const router = express.Router();
4752

@@ -66,7 +71,7 @@ export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHand
6671
}
6772

6873
// Authenticate and extract client details
69-
router.use(authenticateClient({ clientsStore: provider.clientsStore }));
74+
router.use(authenticateClient({ clientsStore: provider.clientsStore, throwErrors }));
7075

7176
router.post('/', async (req, res) => {
7277
res.setHeader('Cache-Control', 'no-store');
@@ -140,7 +145,7 @@ export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHand
140145
//case "client_credentials":
141146

142147
default:
143-
throw new UnsupportedGrantTypeError('The grant type is not supported by this authorization server.');
148+
throw new UnsupportedGrantTypeError(`The grant type '${grant_type}' is not supported by this authorization server.`);
144149
}
145150
} catch (error) {
146151
if (error instanceof OAuthError) {
@@ -150,6 +155,10 @@ export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHand
150155
const serverError = new ServerError('Internal Server Error');
151156
res.status(500).json(serverError.toResponseObject());
152157
}
158+
159+
if (throwErrors) {
160+
throw error;
161+
}
153162
}
154163
});
155164

src/server/auth/middleware/bearerAuth.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ export type BearerAuthMiddlewareOptions = {
1818
* Optional resource metadata URL to include in WWW-Authenticate header.
1919
*/
2020
resourceMetadataUrl?: string;
21+
22+
/**
23+
* Set to true to throw errors to the express error handler
24+
*/
25+
throwErrors?: boolean;
2126
};
2227

2328
declare module 'express-serve-static-core' {
@@ -37,7 +42,12 @@ declare module 'express-serve-static-core' {
3742
* If resourceMetadataUrl is provided, it will be included in the WWW-Authenticate header
3843
* for 401 responses as per the OAuth 2.0 Protected Resource Metadata spec.
3944
*/
40-
export function requireBearerAuth({ verifier, requiredScopes = [], resourceMetadataUrl }: BearerAuthMiddlewareOptions): RequestHandler {
45+
export function requireBearerAuth({
46+
verifier,
47+
requiredScopes = [],
48+
resourceMetadataUrl,
49+
throwErrors
50+
}: BearerAuthMiddlewareOptions): RequestHandler {
4151
return async (req, res, next) => {
4252
try {
4353
const authHeader = req.headers.authorization;
@@ -91,6 +101,10 @@ export function requireBearerAuth({ verifier, requiredScopes = [], resourceMetad
91101
const serverError = new ServerError('Internal Server Error');
92102
res.status(500).json(serverError.toResponseObject());
93103
}
104+
105+
if (throwErrors) {
106+
throw error;
107+
}
94108
}
95109
};
96110
}

src/server/auth/middleware/clientAuth.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ export type ClientAuthenticationMiddlewareOptions = {
99
* A store used to read information about registered OAuth clients.
1010
*/
1111
clientsStore: OAuthRegisteredClientsStore;
12+
13+
/**
14+
* Set to true to throw errors to the express error handler
15+
*/
16+
throwErrors?: boolean;
1217
};
1318

1419
const ClientAuthenticatedRequestSchema = z.object({
@@ -25,7 +30,7 @@ declare module 'express-serve-static-core' {
2530
}
2631
}
2732

28-
export function authenticateClient({ clientsStore }: ClientAuthenticationMiddlewareOptions): RequestHandler {
33+
export function authenticateClient({ clientsStore, throwErrors }: ClientAuthenticationMiddlewareOptions): RequestHandler {
2934
return async (req, res, next) => {
3035
try {
3136
const result = ClientAuthenticatedRequestSchema.safeParse(req.body);
@@ -67,6 +72,10 @@ export function authenticateClient({ clientsStore }: ClientAuthenticationMiddlew
6772
const serverError = new ServerError('Internal Server Error');
6873
res.status(500).json(serverError.toResponseObject());
6974
}
75+
76+
if (throwErrors) {
77+
throw error;
78+
}
7079
}
7180
};
7281
}

0 commit comments

Comments
 (0)