This middleware is actually very simple. So ported it to typescript.
Install latest oauth2-server as separate package and avoid using this obsolete package.
import { Promise } from "bluebird";
import {
Request,
Response,
AuthenticateOptions,
AuthorizationCode,
AuthorizeOptions,
ServerOptions,
TokenOptions,
Token,
InvalidArgumentError,
OAuthError,
UnauthorizedRequestError,
} from "oauth2-server";
import * as NodeOAuthServer from "oauth2-server";
import {
RequestHandler,
Response as ExpressResponse,
Request as ExpressRequest,
NextFunction,
} from "express";
interface IOAuthServerOptions extends
ServerOptions {
useErrorHandler?: boolean;
continueMiddleware?: boolean;
}
export function OAuthServer(options?: IOAuthServerOptions): void {
options = options || {} as IOAuthServerOptions;
if (!options.model) {
throw new InvalidArgumentError('Missing parameter: `model`');
}
this.useErrorHandler = options.useErrorHandler ? true : false;
delete options.useErrorHandler;
this.continueMiddleware = options.continueMiddleware ? true : false;
delete options.continueMiddleware;
this.server = new NodeOAuthServer(options);
}
/**
* Authentication Middleware.
*
* Returns a middleware that will validate a token.
*
* (See: https://tools.ietf.org/html/rfc6749#section-7)
*/
OAuthServer.prototype.authenticate = function (options: AuthenticateOptions): any {
const that = this;
return function (req: ExpressRequest, res: ExpressResponse, next: NextFunction): any {
const request = new Request(req);
const response = new Response(res);
return Promise.bind(that)
.then(function (): Promise<Token> {
return (this.server as NodeOAuthServer).authenticate(request, response, options);
})
.tap(function (token: Token): void {
(res as any).locals.oauth = { token };
next();
})
.catch(function (e: Error): void {
return handleError.call(this, e, req, res, null, next);
});
};
};
/**
* Authorization Middleware.
*
* Returns a middleware that will authorize a client to request tokens.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.1)
*/
OAuthServer.prototype.authorize = function (options: AuthorizeOptions): RequestHandler {
const that = this;
return function (req: ExpressRequest, res: ExpressResponse, next: NextFunction): any {
const request = new Request(req);
const response = new Response(res);
return Promise.bind(that)
.then(function (): Promise<AuthorizationCode> {
return (this.server as NodeOAuthServer).authorize(request, response, options);
})
.tap(function (code: AuthorizationCode): void {
(res as any).locals.oauth = { code };
if (this.continueMiddleware) {
next();
}
})
.then(function (): void {
return handleResponse.call(this, req, res, response);
})
.catch(function (e: Error): void {
return handleError.call(this, e, req, res, response, next);
});
};
};
/**
* Grant Middleware.
*
* Returns middleware that will grant tokens to valid requests.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.2)
*/
OAuthServer.prototype.token = function (options: TokenOptions): RequestHandler {
const that = this;
return function (req: ExpressRequest, res: ExpressResponse, next: NextFunction): Promise<void> {
const request = new Request(req);
const response = new Response(res);
return Promise.bind(that)
.then(function (): Promise<Token> {
return (this.server as NodeOAuthServer).token(request, response, options);
})
.tap(function (token: Token): void {
(res as any).locals.oauth = { token };
if (this.continueMiddleware) {
next();
}
})
.then(function (): void {
return handleResponse.call(this, req, res, response);
})
.catch(function (e: Error): void {
return handleError.call(this, e, req, res, response, next);
});
};
};
const handleResponse = function (req: ExpressRequest, res: ExpressResponse, response: Response): void {
if (response.status === 302) {
const location = response.headers.location;
delete response.headers.location;
res.set(response.headers);
res.redirect(location);
} else {
res.set(response.headers);
res.status(response.status).send(response.body);
}
};
const handleError = function (e: OAuthError, req: ExpressRequest, res: ExpressResponse, response: Response, next: NextFunction): void {
if (this.useErrorHandler === true) {
next(e);
} else {
if (response) {
res.set(response.headers);
}
res.status(e.code);
if (e instanceof UnauthorizedRequestError) {
res.send();
return;
}
res.send({ error: e.name, error_description: e.message });
}
};
export default OAuthServer;