From 3dd720d69a7338fb4e3a99e5ef6a4c68badb1dad Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 20 Jun 2017 14:19:23 -0400 Subject: [PATCH 1/2] v3 types --- types/oauth2-server/index.d.ts | 709 +++++++++++---------- types/oauth2-server/oauth2-server-tests.ts | 105 ++- 2 files changed, 475 insertions(+), 339 deletions(-) diff --git a/types/oauth2-server/index.d.ts b/types/oauth2-server/index.d.ts index 0e3ff61006..5b37754596 100644 --- a/types/oauth2-server/index.d.ts +++ b/types/oauth2-server/index.d.ts @@ -1,6 +1,6 @@ // Type definitions for Node OAuth2 Server -// Project: https://github.com/thomseddon/node-oauth2-server -// Definitions by: Robbie Van Gorkom +// Project: https://github.com/oauthjs/node-oauth2-server +// Definitions by: Charles Irick and Robbie Van Gorkom // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /* =================== USAGE =================== @@ -10,414 +10,467 @@ =============================================== */ +import { RequestHandler } from "express"; +import { Request } from "express"; +/** + * Represents an OAuth2 server instance. + */ +declare class OAuth2Server { + static OAuth2Server: typeof OAuth2Server; + /** + * Instantiates OAuth2Server using the supplied model + * + * @param options + */ + constructor(options: OAuth2Server.ServerOptions); -import {RequestHandler} from "express"; -import {Request} from "express"; + /** + * Authenticates a request. + * + * @param request + * @param response + * @param options + * @param callback + */ + authenticate( + request: OAuth2Server.Request, + response: OAuth2Server.Response, + options?: OAuth2Server.AuthenticateOptions, + callback?: OAuth2Server.Callback + ): Promise; -declare function o(config: o.Config): o.OAuth2Server; + /** + * Authorizes a token request. + * + * @param request + * @param response + * @param options + * @param callback + */ + authorize( + request: OAuth2Server.Request, + response: OAuth2Server.Response, + options?: OAuth2Server.AuthorizeOptions, + callback?: OAuth2Server.Callback + ): Promise; + + /** + * Retrieves a new token for an authorized token request. + * + * @param request + * @param response + * @param options + * @param callback + */ + token( + request: OAuth2Server.Request, + response: OAuth2Server.Response, + options?: OAuth2Server.TokenOptions, + callback?: OAuth2Server.Callback + ): Promise; +} + +declare namespace OAuth2Server { + /** + * Represents an incoming HTTP request. + */ + class Request { + body?: Object; + headers?: Object; + method?: string; + query?: Object; + + /** + * Instantiates Request using the supplied options. + * + * @param options + */ + constructor(options?: Object | Express.Request); + + /** + * Returns the specified HTTP header field. The match is case-insensitive. + * + * @param field + */ + get(field: string): any | undefined; + + /** + * Checks if the request’s Content-Type HTTP header matches any of the given MIME types. + * + * @param types + */ + is(types: string[]): string | false; -declare namespace o { - interface OAuth2Server { - grant(): RequestHandler; - authorise(): any; - errorHandler(): any; } - interface Config { + /** + * Represents an outgoing HTTP response. + */ + class Response { + body?: Object; + headers?: Object; + status?: number; + + /** + * Instantiates Response using the supplied options. + * + * @param options + */ + constructor(options?: Object | Express.Response); + + /** + * Returns the specified HTTP header field. The match is case-insensitive. + * + * @param field + */ + get(field: string): any | undefined; + + /** + * Sets the specified HTTP header field. The match is case-insensitive. + * + * @param field + * @param value + */ + set(field: string, value: string): void; + + /** + * Redirects to the specified URL using 302 Found. + * + * @param url + */ + redirect(url: string): void; + } + + interface ServerOptions extends AuthenticateOptions, AuthorizeOptions, TokenOptions { /** * Model object */ - model: {}; + model: AuthorizationCodeModel | ClientCredentialsModel | RefreshTokenModel | PasswordModel | ExtensionModel; + } + interface AuthenticateOptions { /** - * grant types you wish to support, currently the module supports authorization_code, - * password, refresh_token and client_credentials + * The scope(s) to authenticate. */ - grants: string[]; + scope?: string | undefined; /** - * If true errors will be logged to console. You may also pass a custom function, in - * which case that function will be called with the error as its first argument - * Default: false + * Set the X-Accepted-OAuth-Scopes HTTP header on response objects. */ - debug?: boolean; + addAcceptedScopesHeader?: boolean; /** - * Life of access tokens in seconds - * If null, tokens will considered to never expire - * Default: 3600 + * Set the X-OAuth-Scopes HTTP header on response objects. + */ + addAuthorizedScopesHeader?: boolean; + + /** + * Allow clients to pass bearer tokens in the query string of a request. + */ + allowBearerTokensInQueryString?: boolean; + } + + interface AuthorizeOptions { + /** + * The authenticate handler + */ + authenticateHandler?: {}; + + /** + * Allow clients to specify an empty state + */ + allowEmptyState?: boolean; + + /** + * Lifetime of generated authorization codes in seconds (default = 5 minutes). + */ + authorizationCodeLifetime?: number; + } + + interface TokenOptions { + /** + * Lifetime of generated access tokens in seconds (default = 1 hour) */ accessTokenLifetime?: number; /** - * Life of refresh tokens in seconds - * If null, tokens will considered to never expire - * Default: 1209600 + * Lifetime of generated refresh tokens in seconds (default = 2 weeks) */ refreshTokenLifetime?: number; /** - * Life of auth codes in seconds - * Default: 30 + * Allow extended attributes to be set on the returned token */ - authCodeLifetime?: number; + allowExtendedTokenAttributes?: boolean; /** - * Regex to sanity check client id against before checking model. Note: the default - * just matches common client_id structures, change as needed - * Default: /^[a-z0-9-_]{3,40}$/i + * Require a client secret. Defaults to true for all grant types. */ - clientIdRegex?: RegExp; + requireClientAuthentication?: {}; /** - * If true, non grant errors will not be handled internally (so you can ensure a - * consistent format with the rest of your api) + * Always revoke the used refresh token and issue a new one for the refresh_token grant. */ - passthroughErrors?: boolean; - - /** - * If true, next will be called even if a response has been sent (you probably don't want this) - */ - continueAfterResponse?: boolean; + alwaysIssueNewRefreshToken?: boolean; } + /** + * Represents a generic callback structure for model callbacks + */ + type Callback = (err?: any, result?: T) => void; + + /** + * For returning falsey parameters in cases of failure + */ + type Falsey = '' | 0 | false | null | undefined; + interface BaseModel { /** - * - * @param bearerToken - The bearer token (access token) that has been provided - * @param callback - */ - getAccessToken(bearerToken: string, - callback: GetAccessTokenCallback): void; - - /** - * - * @param clientId - * @param clientSecret - If null, omit from search query (only search by clientId) - * @param callback - */ - getClient(clientId: string, - clientSecret: string, - callback: GetClientCallback): void; - - /** - * - * @param clientId - * @param grantType - * @param callback - */ - grantTypeAllowed(clientId: string, - grantType: string, - callback: GrantTypeAllowedCallback): void; - - /** - * - * @param accessToken - * @param clientId - * @param expires + * Invoked to generate a new access token. + * + * @param client * @param user + * @param scope * @param callback */ - saveAccessToken(accessToken: string, - clientId: string, - expires: Date, - user: User, - callback: SaveAccessTokenCallback): void; - } - - interface AuthorizationCodeModel extends BaseModel { - /** - * - * @param authCode - * @param callback - */ - getAuthCode(authCode: string, - callback: GetAuthCodeCallback): void; + generateAccessToken?(client: Client, user: User, scope: string, callback?: Callback): Promise /** - * - * @param authCode - * @param clientId - * @param expires - * @param user - Whatever was passed as user to the codeGrant function (see example) - * @param callback - */ - saveAuthCode(authCode: string, - clientId: string, - expires: Date, - user: User | string, - callback: SaveAuthCodeCallback): void; - } - - interface PasswordModel extends BaseModel { - /** - * - * @param username - * @param password - * @param callback - */ - getUser(username: string, - password: string, - callback: GetUserCallback): void; - } - - interface RefreshTokenModel extends BaseModel { - /** - * - * @param refreshToken - * @param clientId - * @param expires - * @param user - * @param callback - */ - saveRefreshToken(refreshToken: string, - clientId: string, - expires: Date, - user: User, - callback: SaveRefreshTokenCallback): void; - - /** - * - * @param refreshToken - The bearer token (refresh token) that has been provided - * @param callback - */ - getRefreshToken(refreshToken: string, - callback: GetRefreshTokenCallback): void; - - /** - * The spec does not actually require that you revoke the old token - hence this is - * optional (Last paragraph: http://tools.ietf.org/html/rfc6749#section-6) - * @param refreshToken - * @param callback - */ - revokeRefreshToken?(refreshToken: string, - callback: RevokeRefreshTokenCallback): void; - } - - interface ExtensionModel extends BaseModel { - /** - * - * @param grantType - * @param req - * @param callback - */ - extendedGrant(grantType: string, - req: Request, - callback: ExtendedGrantCallback): void; - } - - interface ClientCredentialsModel extends BaseModel { - /** - * + * Invoked to retrieve a client using a client id or a client id/client secret combination, depending on the grant type. + * * @param clientId * @param clientSecret * @param callback */ - getUserFromClient(clientId: string, - clientSecret: string, - callback: GetUserFromClientCallback): void; + getClient(clientId: string, clientSecret: string, callback?: Callback): Promise /** - * - * @param type - accessToken or refreshToken - * @param req - The current express request + * Invoked to save an access token and optionally a refresh token, depending on the grant type. + * + * @param token + * @param client + * @param user * @param callback */ - generateToken?(type: string, - req: Request, - callback: GenerateTokenCallback): void; + saveToken(token: Token, client: Client, user: User, callback?: Callback): Promise } - interface GenerateTokenCallback { + interface RequestAuthenticationModel { /** - * - * @param error - Truthy to indicate an error - * @param token - string indicates success - * null indicates to revert to the default token generator - * object indicates a reissue (i.e. will not be passed to saveAccessToken/saveRefreshToken) - * Must contain the following keys (if object): - * string accessToken OR refreshToken dependant on type + * Invoked to retrieve an existing access token previously saved through Model#saveToken(). + * + * @param accessToken + * @param callback */ - (error: any, token: string | Object): void; + getAccessToken(accessToken: string, callback?: Callback): Promise + + /** + * Invoked during request authentication to check if the provided access token was authorized the requested scopes. + * + * @param token + * @param scope + * @param callback + */ + verifyScope(token: Token, scope: string, callback?: Callback): Promise } - interface GetUserFromClientCallback { + interface AuthorizationCodeModel extends BaseModel, RequestAuthenticationModel { /** - * - * @param error - Truthy to indicate an error - * @param user - The user retrieved from storage or falsey to indicate an invalid user - * Saved in req.user + * Invoked to generate a new refresh token. + * + * @param client + * @param user + * @param scope + * @param callback */ - (error: any, user: User): void; + generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + + /** + * Invoked to generate a new authorization code. + * + * @param callback + */ + generateAuthorizationCode?(callback?: Callback): Promise + + /** + * Invoked to retrieve an existing authorization code previously saved through Model#saveAuthorizationCode(). + * + * @param authorizationCode + * @param callback + */ + getAuthorizationCode(authorizationCode: string, callback?: Callback): Promise + + /** + * Invoked to save an authorization code. + * + * @param code + * @param client + * @param user + * @param callback + */ + saveAuthorizationCode(code: AuthorizationCode, client: Client, user: User, callback?: Callback): Promise + + /** + * Invoked to revoke an authorization code. + * + * @param code + * @param callback + */ + revokeAuthorizationCode(code: AuthorizationCode, callback?: Callback): Promise + + /** + * Invoked to check if the requested scope is valid for a particular client/user combination. + * + * @param user + * @param client + * @param string + * @param callback + */ + validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise } - interface ExtendedGrantCallback { + interface PasswordModel extends BaseModel, RequestAuthenticationModel { /** - * - * @param error - Truthy to indicate an error - * @param supported - Whether you support the grant type - * @param user - The user retrieved from storage or falsey to indicate an invalid user - * Saved in req.user + * Invoked to generate a new refresh token. + * + * @param client + * @param user + * @param scope + * @param callback */ - (error: any, supported: boolean, user: User): void; + generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + + /** + * Invoked to retrieve a user using a username/password combination. + * + * @param username + * @param password + * @param callback + */ + getUser(username: string, password: string, callback?: Callback): Promise + + /** + * Invoked to check if the requested scope is valid for a particular client/user combination. + * + * @param user + * @param client + * @param string + * @param callback + */ + validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise } - interface RevokeRefreshTokenCallback { + interface RefreshTokenModel extends BaseModel, RequestAuthenticationModel { /** - * Truthy to indicate an error - * @param error + * Invoked to generate a new refresh token. + * + * @param client + * @param user + * @param scope + * @param callback */ - (error: any): void; + generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + + /** + * Invoked to retrieve an existing refresh token previously saved through Model#saveToken(). + * + * @param refreshToken + * @param callback + */ + getRefreshToken(refreshToken: string, callback?: Callback): Promise + + /** + * Invoked to revoke a refresh token. + * + * @param token + * @param callback + */ + revokeToken(token: Token, callback?: Callback): Promise } - interface GetRefreshTokenCallback { + interface ClientCredentialsModel extends BaseModel, RequestAuthenticationModel { /** - * - * @param error - Truthy to indicate an error - * @param refreshToken - The refresh token retrieved form storage or falsey to indicate invalid refresh token + * Invoked to retrieve the user associated with the specified client. + * + * @param client + * @param callback */ - (error: any, refreshToken: RefreshToken): void; + getUserFromClient(client: Client, callback?: Callback): Promise + + /** + * Invoked to check if the requested scope is valid for a particular client/user combination. + * + * @param user + * @param client + * @param string + * @param callback + */ + validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise } - interface SaveRefreshTokenCallback { - /** - * - * @param error - Truthy to indicate an error - */ - (error: any): void; - } - - interface GetUserCallback { - /** - * - * @param error - Truthy to indicate an error - * @param user - The user retrieved from storage or falsey to indicate an invalid user - * Saved in req.user - */ - (error: any, user: User): void; - } - - interface SaveAuthCodeCallback { - /** - * - * @param error - Truthy to indicate an error - */ - (error: any): void; - } - - interface GetAuthCodeCallback { - /** - * - * @param error - Truthy to indicate an error - * @param authCode - The authorization code retrieved form storage or falsey to indicate invalid code - */ - (error: String, authCode: AuthCode): void - } - - interface SaveAccessTokenCallback { - /** - * - * @param error - Truthy to indicate an error - */ - (error: any): void; - } - - interface GetAccessTokenCallback { - /** - * - * @param error - Truthy to indicate an error - * @param accessToken - The access token retrieved form storage or falsey to indicate invalid access token - */ - (error: any, accessToken: AccessToken): void; - } - - interface GetClientCallback { - /** - * - * @param error - Truthy to indicate an error - * @param client - The client retrieved from storage or falsey to indicate an invalid client - * Saved in req.client - */ - (error: any, client: Client): void; - } - - interface GrantTypeAllowedCallback { - /** - * - * @param error - Truthy to indicate an error - * @param allowed - Indicates whether the grantType is allowed for this clientId - */ - (error: any, allowed: boolean): void; - } - - interface RefreshToken { - /** - * client id associated with this token - */ - clientId: string; - - /** - * The date when it expires - * null to indicate the token never expires - */ - expires: Date; - - /** - * - */ - userId: string; - } - - interface AuthCode { - /** - * client id associated with this auth code - */ - clientId: string; - - /** - * The date when it expires - */ - expires: Date; - - /** - * The userId - */ - userId: string; - } + interface ExtensionModel extends BaseModel, RequestAuthenticationModel {} + /** + * An interface representing the user. + * A user object is completely transparent to oauth2-server and is simply used as input to model functions. + */ interface User { id: string; + [key: string]: any; } + /** + * An interface representing the client and associated data + */ interface Client { - clientId: string; - - /** - * authorization_code grant type only - */ - redirectUri: string; + id: string; + redirectUris?: string[]; + grants: string[]; + accessTokenLifetime?: number; + refreshTokenLifetime?: number; + [key: string]: any; } - interface AccessToken { - /** - * The date when it expires - * null to indicate the token never expires - */ - expires: Date; + /** + * An interface representing the authorization code and associated data. + */ + interface AuthorizationCode { + authorizationCode: string; + expiresAt: Date; + redirectUri: string; + scope?: string; + client: Client; + user: User; + [key: string]: any; + } - /** - * If a user key exists, this is saved as req.user - */ - user?: User; + /** + * An interface representing the token(s) and associated data. + */ + interface Token { + accessToken: string; + accessTokenExpiresAt?: Date; + refreshToken?: string; + refreshTokenExpiresAt?: Date; + scope?: string; + client: Client; + user: User; + [key: string]: any; + } - /** - * If a user key exists, this is saved as req.user - * Otherwise a userId key must exist, which is saved in req.user.id - */ - userId?: string; + /** + * An interface representing the refresh token and associated data. + */ + interface RefreshToken { + refreshToken: string; + refreshTokenExpiresAt?: Date; + scope?: string; + client: Client; + user: User; + [key: string]: any; } } -export = o; +export = OAuth2Server; diff --git a/types/oauth2-server/oauth2-server-tests.ts b/types/oauth2-server/oauth2-server-tests.ts index 56216edc8f..7df8f2a22f 100644 --- a/types/oauth2-server/oauth2-server-tests.ts +++ b/types/oauth2-server/oauth2-server-tests.ts @@ -1,18 +1,101 @@ - - import * as express from "express"; -import * as oauthserver from "oauth2-server"; +import * as OAuth2Server from "oauth2-server"; -var oauth = oauthserver({ - model: {}, - grants: ['password'], - debug: true +const oauth2Model: OAuth2Server.AuthorizationCodeModel = { + getClient: async (clientId: string, clientSecret: string): Promise => { + return undefined; + }, + saveToken: async (token: OAuth2Server.Token, client: OAuth2Server.Client, user: OAuth2Server.User): Promise => { + return token; + }, + getAccessToken: async (accessToken: string): Promise => { + return { + accessToken: accessToken, + client: {id: "testClient", grants: ["access_token"]}, + user: {id: "testUser"} + }; + }, + verifyScope: async (token: OAuth2Server.Token, scope: string): Promise => { + return true; + }, + getAuthorizationCode: async (authorizationCode: string): Promise => { + return { + authorizationCode: authorizationCode, + expiresAt: new Date(), + redirectUri: "www.test.com", + client: {id: "testClient", grants: ["access_token"]}, + user: {id: "testUser"} + } + }, + saveAuthorizationCode: async (code: OAuth2Server.AuthorizationCode, client: OAuth2Server.Client, user: OAuth2Server.User): Promise => { + return code; + }, + revokeAuthorizationCode: async (code: OAuth2Server.AuthorizationCode): Promise => { + return true; + } +} + +var oauth2Server = new OAuth2Server({ + model: oauth2Model }); +// Authenticate user with supplied bearer token +const authenticate = (options?: {}) => { + var options: undefined | {} = options || {}; + return async function(req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) { + var request = new OAuth2Server.Request({ + headers: {authorization: req.headers.authorization}, + method: req.method, + query: req.query, + body: req.body + }); + var response = new OAuth2Server.Response(res); + + try { + // Test async method of accessing oauth2Server + const token = await oauth2Server.authenticate(request, response, options); + req.user = token; + next(); + } + catch (err) { + res.status(err.code || 500).json(err); + } + } +} + var app = express(); +app.all('/oauth2/token', (req: express.Request, res: express.Response, next:express.NextFunction) => { + var request: OAuth2Server.Request = new OAuth2Server.Request(req); + var response: OAuth2Server.Response = new OAuth2Server.Response(res); -app.all('/oauth/token', oauth.grant()); -app.get('/', oauth.authorise(), function (req, res) { - res.send('Secret area'); + oauth2Server.token(request,response) + .then(function(token: OAuth2Server.Token) { + res.json(token); + }).catch(function(err: any){ + res.status(err.code || 500).json(err); + }); }); -app.use(oauth.errorHandler()); + +app.post('/oauth2/authorize', (req, res) => { + var request: OAuth2Server.Request = new OAuth2Server.Request(req); + var response: OAuth2Server.Response = new OAuth2Server.Response(res); + + oauth2Server.authorize(request, response) + .then(function(success: OAuth2Server.AuthorizationCode) { + res.json(success) + }).catch(function(err: any){ + res.status(err.code || 500).json(err); + }); +}); + +app.get('/secure', authenticate(), (req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) => { + res.json({message: 'Secure data'}) +}); + +app.get('/profile', authenticate({scope:'profile'}), (req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) => { + res.json({ + profile: req.user + }) +}); + +app.listen(3000); \ No newline at end of file From 6561d810444c1f6b6fb76dc3633ec20eac1fb83e Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 20 Jun 2017 15:30:46 -0400 Subject: [PATCH 2/2] add lint --- types/oauth2-server/index.d.ts | 173 ++++++++++----------- types/oauth2-server/oauth2-server-tests.ts | 64 ++++---- types/oauth2-server/tsconfig.json | 7 +- types/oauth2-server/tslint.json | 3 + 4 files changed, 119 insertions(+), 128 deletions(-) create mode 100644 types/oauth2-server/tslint.json diff --git a/types/oauth2-server/index.d.ts b/types/oauth2-server/index.d.ts index 5b37754596..d328e06fc4 100644 --- a/types/oauth2-server/index.d.ts +++ b/types/oauth2-server/index.d.ts @@ -1,15 +1,9 @@ -// Type definitions for Node OAuth2 Server +// Type definitions for Node OAuth2 Server 3.0 // Project: https://github.com/oauthjs/node-oauth2-server -// Definitions by: Charles Irick and Robbie Van Gorkom +// Definitions by: Robbie Van Gorkom , +// Charles Irick // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/* =================== USAGE =================== - - import * as oauthserver from "oauth2-server"; - var oauth = oauthserver(); - - =============================================== */ - import { RequestHandler } from "express"; import { Request } from "express"; @@ -21,33 +15,33 @@ declare class OAuth2Server { /** * Instantiates OAuth2Server using the supplied model - * - * @param options + * + * @param options */ constructor(options: OAuth2Server.ServerOptions); /** * Authenticates a request. - * - * @param request - * @param response - * @param options - * @param callback + * + * @param request + * @param response + * @param options + * @param callback */ authenticate( - request: OAuth2Server.Request, + request: OAuth2Server.Request, response: OAuth2Server.Response, - options?: OAuth2Server.AuthenticateOptions, + options?: OAuth2Server.AuthenticateOptions, callback?: OAuth2Server.Callback ): Promise; /** * Authorizes a token request. - * - * @param request - * @param response - * @param options - * @param callback + * + * @param request + * @param response + * @param options + * @param callback */ authorize( request: OAuth2Server.Request, @@ -58,11 +52,11 @@ declare class OAuth2Server { /** * Retrieves a new token for an authorized token request. - * - * @param request - * @param response - * @param options - * @param callback + * + * @param request + * @param response + * @param options + * @param callback */ token( request: OAuth2Server.Request, @@ -77,68 +71,67 @@ declare namespace OAuth2Server { * Represents an incoming HTTP request. */ class Request { - body?: Object; - headers?: Object; + body?: any; + headers?: { [key: string]: string; }; method?: string; - query?: Object; + query?: { [key: string]: string; }; /** * Instantiates Request using the supplied options. - * - * @param options + * + * @param options */ - constructor(options?: Object | Express.Request); + constructor(options?: { [key: string]: any } | Express.Request); /** * Returns the specified HTTP header field. The match is case-insensitive. - * - * @param field + * + * @param field */ get(field: string): any | undefined; /** * Checks if the request’s Content-Type HTTP header matches any of the given MIME types. - * - * @param types + * + * @param types */ is(types: string[]): string | false; - } /** * Represents an outgoing HTTP response. */ class Response { - body?: Object; - headers?: Object; + body?: any; + headers?: { [key: string]: string; }; status?: number; /** * Instantiates Response using the supplied options. - * - * @param options + * + * @param options */ - constructor(options?: Object | Express.Response); + constructor(options?: { [key: string]: any; } | Express.Response); /** * Returns the specified HTTP header field. The match is case-insensitive. - * - * @param field + * + * @param field */ get(field: string): any | undefined; /** * Sets the specified HTTP header field. The match is case-insensitive. - * - * @param field - * @param value + * + * @param field + * @param value */ set(field: string, value: string): void; /** * Redirects to the specified URL using 302 Found. - * - * @param url + * + * @param url */ redirect(url: string): void; } @@ -229,191 +222,191 @@ declare namespace OAuth2Server { interface BaseModel { /** * Invoked to generate a new access token. - * + * * @param client * @param user * @param scope * @param callback */ - generateAccessToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + generateAccessToken?(client: Client, user: User, scope: string, callback?: Callback): Promise; /** * Invoked to retrieve a client using a client id or a client id/client secret combination, depending on the grant type. - * + * * @param clientId * @param clientSecret * @param callback */ - getClient(clientId: string, clientSecret: string, callback?: Callback): Promise + getClient(clientId: string, clientSecret: string, callback?: Callback): Promise; /** * Invoked to save an access token and optionally a refresh token, depending on the grant type. - * + * * @param token * @param client * @param user * @param callback */ - saveToken(token: Token, client: Client, user: User, callback?: Callback): Promise + saveToken(token: Token, client: Client, user: User, callback?: Callback): Promise; } interface RequestAuthenticationModel { /** * Invoked to retrieve an existing access token previously saved through Model#saveToken(). - * + * * @param accessToken * @param callback */ - getAccessToken(accessToken: string, callback?: Callback): Promise + getAccessToken(accessToken: string, callback?: Callback): Promise; /** * Invoked during request authentication to check if the provided access token was authorized the requested scopes. - * + * * @param token * @param scope * @param callback */ - verifyScope(token: Token, scope: string, callback?: Callback): Promise + verifyScope(token: Token, scope: string, callback?: Callback): Promise; } interface AuthorizationCodeModel extends BaseModel, RequestAuthenticationModel { /** * Invoked to generate a new refresh token. - * + * * @param client * @param user * @param scope * @param callback */ - generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise; /** * Invoked to generate a new authorization code. - * + * * @param callback */ - generateAuthorizationCode?(callback?: Callback): Promise + generateAuthorizationCode?(callback?: Callback): Promise; /** * Invoked to retrieve an existing authorization code previously saved through Model#saveAuthorizationCode(). - * + * * @param authorizationCode * @param callback */ - getAuthorizationCode(authorizationCode: string, callback?: Callback): Promise + getAuthorizationCode(authorizationCode: string, callback?: Callback): Promise; /** * Invoked to save an authorization code. - * + * * @param code * @param client * @param user * @param callback */ - saveAuthorizationCode(code: AuthorizationCode, client: Client, user: User, callback?: Callback): Promise + saveAuthorizationCode(code: AuthorizationCode, client: Client, user: User, callback?: Callback): Promise; /** * Invoked to revoke an authorization code. - * + * * @param code * @param callback */ - revokeAuthorizationCode(code: AuthorizationCode, callback?: Callback): Promise + revokeAuthorizationCode(code: AuthorizationCode, callback?: Callback): Promise; /** * Invoked to check if the requested scope is valid for a particular client/user combination. - * + * * @param user * @param client * @param string * @param callback */ - validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise + validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise; } interface PasswordModel extends BaseModel, RequestAuthenticationModel { /** * Invoked to generate a new refresh token. - * + * * @param client * @param user * @param scope * @param callback */ - generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise; /** * Invoked to retrieve a user using a username/password combination. - * + * * @param username * @param password * @param callback */ - getUser(username: string, password: string, callback?: Callback): Promise + getUser(username: string, password: string, callback?: Callback): Promise; /** * Invoked to check if the requested scope is valid for a particular client/user combination. - * + * * @param user * @param client * @param string * @param callback */ - validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise + validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise; } interface RefreshTokenModel extends BaseModel, RequestAuthenticationModel { /** * Invoked to generate a new refresh token. - * + * * @param client * @param user * @param scope * @param callback */ - generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise + generateRefreshToken?(client: Client, user: User, scope: string, callback?: Callback): Promise; /** * Invoked to retrieve an existing refresh token previously saved through Model#saveToken(). - * + * * @param refreshToken * @param callback */ - getRefreshToken(refreshToken: string, callback?: Callback): Promise + getRefreshToken(refreshToken: string, callback?: Callback): Promise; /** * Invoked to revoke a refresh token. - * + * * @param token * @param callback */ - revokeToken(token: Token, callback?: Callback): Promise + revokeToken(token: Token, callback?: Callback): Promise; } interface ClientCredentialsModel extends BaseModel, RequestAuthenticationModel { /** * Invoked to retrieve the user associated with the specified client. - * + * * @param client * @param callback */ - getUserFromClient(client: Client, callback?: Callback): Promise + getUserFromClient(client: Client, callback?: Callback): Promise; /** * Invoked to check if the requested scope is valid for a particular client/user combination. - * + * * @param user * @param client * @param string * @param callback */ - validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise + validateScope?(user: User, client: Client, scope: string, callback?: Callback): Promise; } interface ExtensionModel extends BaseModel, RequestAuthenticationModel {} /** - * An interface representing the user. + * An interface representing the user. * A user object is completely transparent to oauth2-server and is simply used as input to model functions. */ interface User { diff --git a/types/oauth2-server/oauth2-server-tests.ts b/types/oauth2-server/oauth2-server-tests.ts index 7df8f2a22f..be8fa83705 100644 --- a/types/oauth2-server/oauth2-server-tests.ts +++ b/types/oauth2-server/oauth2-server-tests.ts @@ -10,7 +10,7 @@ const oauth2Model: OAuth2Server.AuthorizationCodeModel = { }, getAccessToken: async (accessToken: string): Promise => { return { - accessToken: accessToken, + accessToken, client: {id: "testClient", grants: ["access_token"]}, user: {id: "testUser"} }; @@ -20,12 +20,12 @@ const oauth2Model: OAuth2Server.AuthorizationCodeModel = { }, getAuthorizationCode: async (authorizationCode: string): Promise => { return { - authorizationCode: authorizationCode, + authorizationCode, expiresAt: new Date(), redirectUri: "www.test.com", client: {id: "testClient", grants: ["access_token"]}, user: {id: "testUser"} - } + }; }, saveAuthorizationCode: async (code: OAuth2Server.AuthorizationCode, client: OAuth2Server.Client, user: OAuth2Server.User): Promise => { return code; @@ -33,69 +33,63 @@ const oauth2Model: OAuth2Server.AuthorizationCodeModel = { revokeAuthorizationCode: async (code: OAuth2Server.AuthorizationCode): Promise => { return true; } -} +}; -var oauth2Server = new OAuth2Server({ +const oauth2Server = new OAuth2Server({ model: oauth2Model }); // Authenticate user with supplied bearer token -const authenticate = (options?: {}) => { - var options: undefined | {} = options || {}; - return async function(req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) { - var request = new OAuth2Server.Request({ - headers: {authorization: req.headers.authorization}, - method: req.method, - query: req.query, - body: req.body - }); - var response = new OAuth2Server.Response(res); +const authenticate = (authenticateOptions?: {}) => { + const options: undefined | {} = authenticateOptions || {}; + return async (req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) => { + const request = new OAuth2Server.Request(req); + const response = new OAuth2Server.Response(res); try { // Test async method of accessing oauth2Server const token = await oauth2Server.authenticate(request, response, options); req.user = token; next(); - } - catch (err) { + } catch (err) { res.status(err.code || 500).json(err); } - } -} + }; +}; -var app = express(); -app.all('/oauth2/token', (req: express.Request, res: express.Response, next:express.NextFunction) => { - var request: OAuth2Server.Request = new OAuth2Server.Request(req); - var response: OAuth2Server.Response = new OAuth2Server.Response(res); +const app = express(); +app.all('/oauth2/token', (req: express.Request, res: express.Response, next: express.NextFunction) => { + const request = new OAuth2Server.Request(req); + const response = new OAuth2Server.Response(res); - oauth2Server.token(request,response) - .then(function(token: OAuth2Server.Token) { + oauth2Server.token(request, response) + .then((token: OAuth2Server.Token) => { res.json(token); - }).catch(function(err: any){ + }).catch((err: any) => { res.status(err.code || 500).json(err); }); }); app.post('/oauth2/authorize', (req, res) => { - var request: OAuth2Server.Request = new OAuth2Server.Request(req); - var response: OAuth2Server.Response = new OAuth2Server.Response(res); + const request = new OAuth2Server.Request(req); + const response = new OAuth2Server.Response(res); oauth2Server.authorize(request, response) - .then(function(success: OAuth2Server.AuthorizationCode) { - res.json(success) - }).catch(function(err: any){ + .then((success: OAuth2Server.AuthorizationCode) => { + res.json(success); + }).catch((err: any) => { res.status(err.code || 500).json(err); }); }); app.get('/secure', authenticate(), (req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) => { - res.json({message: 'Secure data'}) + res.json({message: 'Secure data'}); }); -app.get('/profile', authenticate({scope:'profile'}), (req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) => { +app.get('/profile', authenticate({scope: 'profile'}), (req: express.Request & {user: OAuth2Server.Token}, res: express.Response, next: express.NextFunction) => { res.json({ profile: req.user - }) + }); }); -app.listen(3000); \ No newline at end of file +app.listen(3000); diff --git a/types/oauth2-server/tsconfig.json b/types/oauth2-server/tsconfig.json index 0345961931..fdafde9f35 100644 --- a/types/oauth2-server/tsconfig.json +++ b/types/oauth2-server/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "lib": [ - "es6" + "es2017" ], "noImplicitAny": true, "noImplicitThis": true, @@ -13,10 +13,11 @@ ], "types": [], "noEmit": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "target": "es6" }, "files": [ "index.d.ts", "oauth2-server-tests.ts" ] -} \ No newline at end of file +} diff --git a/types/oauth2-server/tslint.json b/types/oauth2-server/tslint.json new file mode 100644 index 0000000000..f93cf8562a --- /dev/null +++ b/types/oauth2-server/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +}