Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/server/auth/handlers/authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export type AuthorizationHandlerOptions = {
* Set to false to disable rate limiting for this endpoint.
*/
rateLimit?: Partial<RateLimitOptions> | false;

/**
* Set to true to throw errors to the express error handler
*/
throwErrors?: boolean;
};

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

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

if (throwErrors) {
throw error;
}

return;
}

Expand Down Expand Up @@ -142,6 +151,10 @@ export function authorizationHandler({ provider, rateLimit: rateLimitConfig }: A
const serverError = new ServerError('Internal Server Error');
res.redirect(302, createErrorRedirect(redirect_uri, serverError, state));
}

if (throwErrors) {
throw error;
}
}
});

Expand Down
12 changes: 11 additions & 1 deletion src/server/auth/handlers/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export type ClientRegistrationHandlerOptions = {
* If not set, defaults to true.
*/
clientIdGeneration?: boolean;

/**
* Set to true to throw errors to the express error handler
*/
throwErrors?: boolean;
};

const DEFAULT_CLIENT_SECRET_EXPIRY_SECONDS = 30 * 24 * 60 * 60; // 30 days
Expand All @@ -41,7 +46,8 @@ export function clientRegistrationHandler({
clientsStore,
clientSecretExpirySeconds = DEFAULT_CLIENT_SECRET_EXPIRY_SECONDS,
rateLimit: rateLimitConfig,
clientIdGeneration = true
clientIdGeneration = true,
throwErrors
}: ClientRegistrationHandlerOptions): RequestHandler {
if (!clientsStore.registerClient) {
throw new Error('Client registration store does not support registering clients');
Expand Down Expand Up @@ -112,6 +118,10 @@ export function clientRegistrationHandler({
const serverError = new ServerError('Internal Server Error');
res.status(500).json(serverError.toResponseObject());
}

if (throwErrors) {
throw error;
}
}
});

Expand Down
8 changes: 7 additions & 1 deletion src/server/auth/handlers/revoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ export type RevocationHandlerOptions = {
* Set to false to disable rate limiting for this endpoint.
*/
rateLimit?: Partial<RateLimitOptions> | false;

throwErrors?: boolean;
};

export function revocationHandler({ provider, rateLimit: rateLimitConfig }: RevocationHandlerOptions): RequestHandler {
export function revocationHandler({ provider, rateLimit: rateLimitConfig, throwErrors }: RevocationHandlerOptions): RequestHandler {
if (!provider.revokeToken) {
throw new Error('Auth provider does not support revoking tokens');
}
Expand Down Expand Up @@ -72,6 +74,10 @@ export function revocationHandler({ provider, rateLimit: rateLimitConfig }: Revo
const serverError = new ServerError('Internal Server Error');
res.status(500).json(serverError.toResponseObject());
}

if (throwErrors) {
throw error;
}
}
});

Expand Down
15 changes: 12 additions & 3 deletions src/server/auth/handlers/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export type TokenHandlerOptions = {
* Set to false to disable rate limiting for this endpoint.
*/
rateLimit?: Partial<RateLimitOptions> | false;

/**
* Set to true to throw errors to the express error handler
*/
throwErrors?: boolean;
};

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

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

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

// Authenticate and extract client details
router.use(authenticateClient({ clientsStore: provider.clientsStore }));
router.use(authenticateClient({ clientsStore: provider.clientsStore, throwErrors }));

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

default:
throw new UnsupportedGrantTypeError('The grant type is not supported by this authorization server.');
throw new UnsupportedGrantTypeError(`The grant type '${grant_type}' is not supported by this authorization server.`);
}
} catch (error) {
if (error instanceof OAuthError) {
Expand All @@ -150,6 +155,10 @@ export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHand
const serverError = new ServerError('Internal Server Error');
res.status(500).json(serverError.toResponseObject());
}

if (throwErrors) {
throw error;
}
}
});

Expand Down
16 changes: 15 additions & 1 deletion src/server/auth/middleware/bearerAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export type BearerAuthMiddlewareOptions = {
* Optional resource metadata URL to include in WWW-Authenticate header.
*/
resourceMetadataUrl?: string;

/**
* Set to true to throw errors to the express error handler
*/
throwErrors?: boolean;
};

declare module 'express-serve-static-core' {
Expand All @@ -37,7 +42,12 @@ declare module 'express-serve-static-core' {
* If resourceMetadataUrl is provided, it will be included in the WWW-Authenticate header
* for 401 responses as per the OAuth 2.0 Protected Resource Metadata spec.
*/
export function requireBearerAuth({ verifier, requiredScopes = [], resourceMetadataUrl }: BearerAuthMiddlewareOptions): RequestHandler {
export function requireBearerAuth({
verifier,
requiredScopes = [],
resourceMetadataUrl,
throwErrors
}: BearerAuthMiddlewareOptions): RequestHandler {
return async (req, res, next) => {
try {
const authHeader = req.headers.authorization;
Expand Down Expand Up @@ -91,6 +101,10 @@ export function requireBearerAuth({ verifier, requiredScopes = [], resourceMetad
const serverError = new ServerError('Internal Server Error');
res.status(500).json(serverError.toResponseObject());
}

if (throwErrors) {
throw error;
}
}
};
}
11 changes: 10 additions & 1 deletion src/server/auth/middleware/clientAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export type ClientAuthenticationMiddlewareOptions = {
* A store used to read information about registered OAuth clients.
*/
clientsStore: OAuthRegisteredClientsStore;

/**
* Set to true to throw errors to the express error handler
*/
throwErrors?: boolean;
};

const ClientAuthenticatedRequestSchema = z.object({
Expand All @@ -25,7 +30,7 @@ declare module 'express-serve-static-core' {
}
}

export function authenticateClient({ clientsStore }: ClientAuthenticationMiddlewareOptions): RequestHandler {
export function authenticateClient({ clientsStore, throwErrors }: ClientAuthenticationMiddlewareOptions): RequestHandler {
return async (req, res, next) => {
try {
const result = ClientAuthenticatedRequestSchema.safeParse(req.body);
Expand Down Expand Up @@ -67,6 +72,10 @@ export function authenticateClient({ clientsStore }: ClientAuthenticationMiddlew
const serverError = new ServerError('Internal Server Error');
res.status(500).json(serverError.toResponseObject());
}

if (throwErrors) {
throw error;
}
}
};
}
Loading