diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..d9ee790 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,22 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# We recommend specifying your dependencies to enable reproducible builds: +# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +# python: +# install: +# - requirements: docs/requirements.txt \ No newline at end of file diff --git a/docs/api/errors/access-denied-error.rst b/docs/api/errors/access-denied-error.rst index e561c5b..11e61ec 100644 --- a/docs/api/errors/access-denied-error.rst +++ b/docs/api/errors/access-denied-error.rst @@ -6,7 +6,7 @@ The resource owner or authorization server denied the request. See :rfc:`Section :: - const AccessDeniedError = require('oauth2-server/lib/errors/access-denied-error'); + const AccessDeniedError = require('@node-oauth/oauth2-server/lib/errors/access-denied-error'); -------- diff --git a/docs/api/errors/insufficient-scope-error.rst b/docs/api/errors/insufficient-scope-error.rst index be3539d..b19e2ac 100644 --- a/docs/api/errors/insufficient-scope-error.rst +++ b/docs/api/errors/insufficient-scope-error.rst @@ -6,7 +6,7 @@ The request requires higher privileges than provided by the access token. See :r :: - const InsufficientScopeError = require('oauth2-server/lib/errors/insufficient-scope-error'); + const InsufficientScopeError = require('@node-oauth/oauth2-server/lib/errors/insufficient-scope-error'); -------- diff --git a/docs/api/errors/invalid-argument-error.rst b/docs/api/errors/invalid-argument-error.rst index 650e1d9..11b554e 100644 --- a/docs/api/errors/invalid-argument-error.rst +++ b/docs/api/errors/invalid-argument-error.rst @@ -6,7 +6,7 @@ An invalid argument was encountered. :: - const InvalidArgumentError = require('oauth2-server/lib/errors/invalid-argument-error'); + const InvalidArgumentError = require('@node-oauth/oauth2-server/lib/errors/invalid-argument-error'); .. note:: This error indicates that the module is used incorrectly (i.e., there is a programming error) and should never be seen because of external errors (like invalid data sent by a client). diff --git a/docs/api/errors/invalid-client-error.rst b/docs/api/errors/invalid-client-error.rst index d25a493..5ddd0a4 100644 --- a/docs/api/errors/invalid-client-error.rst +++ b/docs/api/errors/invalid-client-error.rst @@ -6,7 +6,7 @@ Client authentication failed (e.g., unknown client, no client authentication inc :: - const InvalidClientError = require('oauth2-server/lib/errors/invalid-client-error'); + const InvalidClientError = require('@node-oauth/oauth2-server/lib/errors/invalid-client-error'); -------- diff --git a/docs/api/errors/invalid-grant-error.rst b/docs/api/errors/invalid-grant-error.rst index 8f2a9ba..7931714 100644 --- a/docs/api/errors/invalid-grant-error.rst +++ b/docs/api/errors/invalid-grant-error.rst @@ -6,7 +6,7 @@ The provided authorization grant (e.g., authorization code, resource owner crede :: - const InvalidGrantError = require('oauth2-server/lib/errors/invalid-grant-error'); + const InvalidGrantError = require('@node-oauth/oauth2-server/lib/errors/invalid-grant-error'); -------- diff --git a/docs/api/errors/invalid-request-error.rst b/docs/api/errors/invalid-request-error.rst index 119ab40..bbb38c4 100644 --- a/docs/api/errors/invalid-request-error.rst +++ b/docs/api/errors/invalid-request-error.rst @@ -6,7 +6,7 @@ The request is missing a required parameter, includes an invalid parameter value :: - const InvalidRequestError = require('oauth2-server/lib/errors/invalid-request-error'); + const InvalidRequestError = require('@node-oauth/oauth2-server/lib/errors/invalid-request-error'); -------- diff --git a/docs/api/errors/invalid-scope-error.rst b/docs/api/errors/invalid-scope-error.rst index 801930f..01c70d2 100644 --- a/docs/api/errors/invalid-scope-error.rst +++ b/docs/api/errors/invalid-scope-error.rst @@ -6,7 +6,7 @@ The requested scope is invalid, unknown, or malformed. See :rfc:`Section 4.1.2.1 :: - const InvalidScopeError = require('oauth2-server/lib/errors/invalid-scope-error'); + const InvalidScopeError = require('@node-oauth/oauth2-server/lib/errors/invalid-scope-error'); -------- diff --git a/docs/api/errors/invalid-token-error.rst b/docs/api/errors/invalid-token-error.rst index 21ffad8..fc0da03 100644 --- a/docs/api/errors/invalid-token-error.rst +++ b/docs/api/errors/invalid-token-error.rst @@ -6,7 +6,7 @@ The access token provided is expired, revoked, malformed, or invalid for other r :: - const InvalidTokenError = require('oauth2-server/lib/errors/invalid-token-error'); + const InvalidTokenError = require('@node-oauth/oauth2-server/lib/errors/invalid-token-error'); -------- diff --git a/docs/api/errors/oauth-error.rst b/docs/api/errors/oauth-error.rst index c7f1d86..83be465 100644 --- a/docs/api/errors/oauth-error.rst +++ b/docs/api/errors/oauth-error.rst @@ -6,7 +6,7 @@ Base class for all errors returned by this module. :: - const OAuthError = require('oauth2-server/lib/errors/oauth-error'); + const OAuthError = require('@node-oauth/oauth2-server/lib/errors/oauth-error'); -------- diff --git a/docs/api/errors/server-error.rst b/docs/api/errors/server-error.rst index 13f436e..7a2dcf9 100644 --- a/docs/api/errors/server-error.rst +++ b/docs/api/errors/server-error.rst @@ -6,7 +6,7 @@ The authorization server encountered an unexpected condition that prevented it f :: - const ServerError = require('oauth2-server/lib/errors/server-error'); + const ServerError = require('@node-oauth/oauth2-server/lib/errors/server-error'); ``ServerError`` is used to wrap unknown exceptions encountered during request processing. diff --git a/docs/api/errors/unauthorized-client-error.rst b/docs/api/errors/unauthorized-client-error.rst index d04cb08..9d104ca 100644 --- a/docs/api/errors/unauthorized-client-error.rst +++ b/docs/api/errors/unauthorized-client-error.rst @@ -6,7 +6,7 @@ The authenticated client is not authorized to use this authorization grant type. :: - const UnauthorizedClientError = require('oauth2-server/lib/errors/unauthorized-client-error'); + const UnauthorizedClientError = require('@node-oauth/oauth2-server/lib/errors/unauthorized-client-error'); -------- diff --git a/docs/api/errors/unauthorized-request-error.rst b/docs/api/errors/unauthorized-request-error.rst index 495f5f8..9ed2467 100644 --- a/docs/api/errors/unauthorized-request-error.rst +++ b/docs/api/errors/unauthorized-request-error.rst @@ -6,7 +6,7 @@ The request lacked any authentication information or the client attempted to use :: - const UnauthorizedRequestError = require('oauth2-server/lib/errors/unauthorized-request-error'); + const UnauthorizedRequestError = require('@node-oauth/oauth2-server/lib/errors/unauthorized-request-error'); According to :rfc:`Section 3.1 of RFC 6750 <6750#section-3.1>` you should just fail the request with ``401 Unauthorized`` and not send any error information in the body if this error occurs: diff --git a/docs/api/errors/unsupported-grant-type-error.rst b/docs/api/errors/unsupported-grant-type-error.rst index d2fe49f..1e812ed 100644 --- a/docs/api/errors/unsupported-grant-type-error.rst +++ b/docs/api/errors/unsupported-grant-type-error.rst @@ -6,7 +6,7 @@ The authorization grant type is not supported by the authorization server. See : :: - const UnsupportedGrantTypeError = require('oauth2-server/lib/errors/unsupported-grant-type-error'); + const UnsupportedGrantTypeError = require('@node-oauth/oauth2-server/lib/errors/unsupported-grant-type-error'); -------- diff --git a/docs/api/errors/unsupported-response-type-error.rst b/docs/api/errors/unsupported-response-type-error.rst index 28974eb..c9ee0fd 100644 --- a/docs/api/errors/unsupported-response-type-error.rst +++ b/docs/api/errors/unsupported-response-type-error.rst @@ -6,7 +6,7 @@ The authorization server does not supported obtaining an authorization code usin :: - const UnsupportedResponseTypeError = require('oauth2-server/lib/errors/unsupported-response-type-error'); + const UnsupportedResponseTypeError = require('@node-oauth/oauth2-server/lib/errors/unsupported-response-type-error'); -------- diff --git a/docs/api/oauth2-server.rst b/docs/api/oauth2-server.rst index 48acf53..38cf6bd 100644 --- a/docs/api/oauth2-server.rst +++ b/docs/api/oauth2-server.rst @@ -6,7 +6,7 @@ Represents an OAuth2 server instance. :: - const OAuth2Server = require('oauth2-server'); + const OAuth2Server = require('@node-oauth/oauth2-server'); -------- @@ -94,7 +94,7 @@ Possible errors include but are not limited to: :doc:`/api/errors/unauthorized-request-error`: The protected resource request failed authentication. -The returned ``Promise`` **must** be ignored if ``callback`` is used. +**Versions <=4.x note:** The returned ``Promise`` **must** be ignored if ``callback`` is used. **Remarks:** @@ -139,7 +139,7 @@ Authorizes a token request. +-----------------------------------------+-----------------+-----------------------------------------------------------------------------+ | [options={}] | Object | Handler options. | +-----------------------------------------+-----------------+-----------------------------------------------------------------------------+ -| [options.authenticateHandler=undefined] | Object | The authenticate handler (see remarks section). | +| [options.authenticateHandler=undefined] | Object | The authenticate handler (see remarks section below). | +-----------------------------------------+-----------------+-----------------------------------------------------------------------------+ | [options.allowEmptyState=false] | Boolean | Allow clients to specify an empty ``state``. | +-----------------------------------------+-----------------+-----------------------------------------------------------------------------+ @@ -158,7 +158,7 @@ Possible errors include but are not limited to: :doc:`/api/errors/access-denied-error` The resource owner denied the access request (i.e. ``request.query.allow`` was ``'false'``). -The returned ``Promise`` **must** be ignored if ``callback`` is used. +**Versions <=4.x note:** The returned ``Promise`` **must** be ignored if ``callback`` is used. **Remarks:** @@ -252,7 +252,7 @@ Possible errors include but are not limited to: :doc:`/api/errors/invalid-grant-error`: The access token request was invalid or not authorized. -The returned ``Promise`` **must** be ignored if ``callback`` is used. +**Versions <=4.x note:** The returned ``Promise`` **must** be ignored if ``callback`` is used. **Remarks:** diff --git a/docs/api/request.rst b/docs/api/request.rst index b8f8963..7d5f4ca 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -6,7 +6,7 @@ Represents an incoming HTTP request. :: - const Request = require('oauth2-server').Request; + const Request = require('@node-oauth/oauth2-server').Request; -------- @@ -50,7 +50,7 @@ To convert `Express' request`_ to a ``Request`` simply pass ``req`` as ``options :: function(req, res, next) { - var request = new Request(req); + let request = new Request(req); // ... } diff --git a/docs/api/response.rst b/docs/api/response.rst index 48cc36d..2c5d332 100644 --- a/docs/api/response.rst +++ b/docs/api/response.rst @@ -6,7 +6,7 @@ Represents an outgoing HTTP response. :: - const Response = require('oauth2-server').Response; + const Response = require('@node-oauth/oauth2-server').Response; -------- @@ -46,7 +46,7 @@ To convert `Express' response`_ to a ``Response`` simply pass ``res`` as ``optio :: function(req, res, next) { - var response = new Response(res); + let response = new Response(res); // ... } diff --git a/docs/conf.py b/docs/conf.py index d9aae79..a621e90 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# oauth2-server documentation build configuration file, created by +# @node-oauth/oauth2-server documentation build configuration file, created by # sphinx-quickstart on Thu Nov 17 16:47:05 2016. # # This file is execfile()d with the current directory set to its containing dir. @@ -272,5 +272,5 @@ highlight_language = 'js' def setup(app): - app.add_stylesheet('custom.css') + app.add_css_file('custom.css') diff --git a/docs/docs/adapters.rst b/docs/docs/adapters.rst index c302d34..bec9ce6 100644 --- a/docs/docs/adapters.rst +++ b/docs/docs/adapters.rst @@ -7,9 +7,9 @@ The *oauth2-server* module is typically not used directly but through one of the .. framework-agnostic but there are several officially supported adapters available for popular HTTP server frameworks such as Express_ and Koa_. - express-oauth-server_ for Express_ -- koa-oauth-server_ for Koa_ +- koa-oauth-server_ for Koa_ (outdated, maintainer wanted!) -.. _express-oauth-server: https://npmjs.org/package/express-oauth-server +.. _express-oauth-server: https://www.npmjs.com/package/@node-oauth/express-oauth-server .. _Express: https://npmjs.org/package/express .. _koa-oauth-server: https://npmjs.org/package/koa-oauth-server .. _Koa: https://npmjs.org/package/koa diff --git a/docs/docs/getting-started.rst b/docs/docs/getting-started.rst index ff2c115..1a55f18 100644 --- a/docs/docs/getting-started.rst +++ b/docs/docs/getting-started.rst @@ -9,16 +9,16 @@ Installation oauth2-server_ is available via npm_. -.. _oauth2-server: https://npmjs.org/package/oauth2-server +.. _oauth2-server: https://www.npmjs.com/package/@node-oauth/oauth2-server .. _npm: https://npmjs.org .. code-block:: sh - $ npm install oauth2-server + $ npm install @node-oauth/oauth2-server -.. note:: The *oauth2-server* module is framework-agnostic but there are several officially supported adapters available for popular HTTP server frameworks such as Express_ and Koa_. If you're using one of those frameworks it is strongly recommended to use the respective adapter module instead of rolling your own. +.. note:: The *oauth2-server* module is framework-agnostic but there are several officially supported adapters available for popular HTTP server frameworks such as Express_ and Koa_ (maintainer wanted!). If you're using one of those frameworks it is strongly recommended to use the respective adapter module instead of rolling your own. -.. _Express: https://npmjs.org/package/express-oauth-server +.. _Express: https://www.npmjs.com/package/@node-oauth/express-oauth-server .. _Koa: https://npmjs.org/package/koa-oauth-server @@ -29,12 +29,14 @@ Features - Supports :ref:`authorization code `, :ref:`client credentials `, :ref:`refresh token ` and :ref:`password ` grant, as well as :ref:`extension grants `, with scopes. - Can be used with *promises*, *Node-style callbacks*, *ES6 generators* and *async*/*await* (using Babel_). +- From version 5.0.0 fully native async/await implemented - Fully :rfc:`6749` and :rfc:`6750` compliant. +- Supports PKCE (:rfc:`7636`) - Implicitly supports any form of storage, e.g. *PostgreSQL*, *MySQL*, *MongoDB*, *Redis*, etc. - Complete `test suite`_. .. _Babel: https://babeljs.io -.. _test suite: https://github.com/oauthjs/node-oauth2-server/tree/master/test +.. _test suite: https://github.com/node-oauth/node-oauth2-server/tree/master/test .. _quick-start: @@ -46,7 +48,7 @@ Quick Start :: - const OAuth2Server = require('oauth2-server'); + const OAuth2Server = require('@node-oauth/oauth2-server'); const oauth = new OAuth2Server({ model: require('./model') @@ -78,7 +80,7 @@ Quick Start :: - const AccessDeniedError = require('oauth2-server/lib/errors/access-denied-error'); + const AccessDeniedError = require('@node-oauth/oauth2-server/lib/errors/access-denied-error'); oauth.authorize(request, response) .then((code) => { diff --git a/docs/index.rst b/docs/index.rst index 4a7c341..f88c4b4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,13 +1,13 @@ -=============== - oauth2-server -=============== +========================== + @node-oauth/oauth2-server +========================== -oauth2-server_ is a complete, compliant and well tested module for implementing an OAuth2 server in Node.js_. The project is `hosted on GitHub`_ and the included test suite is automatically `run on Travis CI`_. +oauth2-server_ is a complete, compliant and well tested module for implementing an OAuth2 server in Node.js_. The project is `hosted on GitHub`_ and the included test suite is automatically `run on GitHub CI`_. -.. _oauth2-server: https://npmjs.org/package/oauth2-server +.. _oauth2-server: https://www.npmjs.com/package/@node-oauth/oauth2-server .. _Node.js: https://nodejs.org -.. _hosted on GitHub: https://github.com/oauthjs/node-oauth2-server -.. _run on Travis CI: https://travis-ci.org/oauthjs/node-oauth2-server +.. _hosted on GitHub: https://github.com/node-oauth/node-oauth2-server +.. _run on GitHub CI: https://github.com/node-oauth/node-oauth2-server/actions :ref:`installation` @@ -17,7 +17,7 @@ Example Usage :: - const OAuth2Server = require('oauth2-server'); + const OAuth2Server = require('@node-oauth/oauth2-server'); const Request = OAuth2Server.Request; const Response = OAuth2Server.Response; @@ -84,5 +84,6 @@ See the :doc:`/model/spec` of what is required from the model passed to :doc:`/a :hidden: misc/extension-grants + misc/pkce misc/migrating-v2-to-v3 diff --git a/docs/misc/extension-grants.rst b/docs/misc/extension-grants.rst index 1fbe55a..4ce22bf 100644 --- a/docs/misc/extension-grants.rst +++ b/docs/misc/extension-grants.rst @@ -6,7 +6,7 @@ Create a subclass of ``AbstractGrantType`` and create methods `handle` and `save .. code-block:: js - const OAuth2Server = require('oauth2-server'); + const OAuth2Server = require('@node-oauth/oauth2-server'); const AbstractGrantType = OAuth2Server.AbstractGrantType; const InvalidArgumentError = OAuth2Server.InvalidArgumentError; const InvalidRequestError = OAuth2Server.InvalidRequestError; diff --git a/docs/misc/migrating-v2-to-v3.rst b/docs/misc/migrating-v2-to-v3.rst index 9d03c8f..8d1290c 100644 --- a/docs/misc/migrating-v2-to-v3.rst +++ b/docs/misc/migrating-v2-to-v3.rst @@ -11,7 +11,7 @@ Middlewares The naming of the exposed middlewares has changed to match the OAuth2 _RFC_ more closely. Please refer to the table below: +-------------------+------------------------------------------------+ -| oauth2-server 2.x | oauth2-server 3.x | +| oauth2-server 2.x | @node-oauth/oauth2-server 3.x | +===================+================================================+ | authorise | authenticate | +-------------------+------------------------------------------------+ diff --git a/docs/misc/pkce.rst b/docs/misc/pkce.rst new file mode 100644 index 0000000..cb52f1e --- /dev/null +++ b/docs/misc/pkce.rst @@ -0,0 +1,141 @@ +================ + PKCE Support +================ + +Starting with release 4.3.0_ this library supports PKCE (Proof Key for Code Exchange by OAuth Public Clients) as +defined in :rfc:`7636`. + +.. _4.3.0: https://github.com/node-oauth/node-oauth2-server/releases/tag/v4.3.0 + +The PKCE integrates only with the :ref:`authorization code `. The abstract workflow looks like +the following: + +:: + + +-------------------+ + | Authz Server | + +--------+ | +---------------+ | + | |--(A)- Authorization Request ---->| | | + | | + t(code_verifier), t_m | | Authorization | | + | | | | Endpoint | | + | |<-(B)---- Authorization Code -----| | | + | | | +---------------+ | + | Client | | | + | | | +---------------+ | + | |--(C)-- Access Token Request ---->| | | + | | + code_verifier | | Token | | + | | | | Endpoint | | + | |<-(D)------ Access Token ---------| | | + +--------+ | +---------------+ | + +-------------------+ + + Figure 2: Abstract Protocol Flow + +See :rfc:`Section 1 of RFC 7636 <7636#section-1.1>`. + +1. Authorization request +======================== + +.. _PKCE#authorizationRequest: + + A. The client creates and records a secret named the "code_verifier" and derives a transformed version "t(code_verifier)" (referred to as the "code_challenge"), which is sent in the OAuth 2.0 Authorization Request along with the transformation method "t_m". + +The following shows an example of how a client could generate a `code_challenge`` and +``code_challenge_method`` for the authorizazion request. + +:: + + const base64URLEncode = str => str.toString('base64') + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=/g, '') + + // This is the code_verifier, which is INITIALLY KEPT SECRET on the client + // and which is later passed as request param to the token endpoint. + // DO NOT SEND this with the authorization request! + const codeVerifier = base64URLEncode(crypto.randomBytes(32)) + + // This is the hashed version of the verifier, which is sent to the authorization endpoint. + // This is named t(code_verifier) in the above workflow + // Send this with the authorization request! + const codeChallenge = base64URLEncode(crypto.createHash('sha256').update(codeVerifier).digest()) + + // This is the name of the code challenge method + // This is named t_m in the above workflow + // Send this with the authorization request! + const codeChallengeMethod = 'S256' + + // add these to the request that is fired from the client + +In this project the authorize endpoint calls OAuth2Server.prototype.authorize which itself uses AuthorizeHandler. +If your Request body contains code_challenge and code_challenge_method then PKCE is active. + +:: + + const server = new OAuth2Server({ model }) + + // this could be added to express or other middleware + const authorizeEndpoint = function (req, res, next) { + const request = new Request(req) + req.query.code_challenge // the codeChallenge value + req.query.code_challenge_method // 'S256' + + server.authorize(request, response, options) + .then(function (code) { + // add code to response, code should not contain + // code_challenge or code_challenge_method + }) + .catch(function (err) { + // handle error condition + }) + } + +2. Authorization response +========================= + +.. _PKCE#authorizationResponse: + + B. The Authorization Endpoint responds as usual but records "t(code_verifier)" and the transformation method. + +The ``AuthorizeHandler.handle`` saves code challenge and code challenge method automatically via ``model.saveAuthorizationCode``. +Note that this calls your model with additional properties ``code.codeChallenge`` and ``code.codeChallengeMethod``. + + +3. Access Token Request +======================= + +.. _PKCE#accessTokenRequest: + + C. The client then sends the authorization code in the Access Token Request as usual but includes the "code_verifier" secret generated at (A). + +This is usually done in your token endpoint, that uses ``OAuth2Server.token``. + +:: + + const server = new OAuth2Server({ model }) + + // ...authorizeEndpoint + + // this could be added to express or other middleware + const tokenEndpoint = function (req, res, next) { + const request = new Request(req) + request.body.code_verifier // the non-hashed code verifier + server.token(request, response, options) + .then(function (code) { + // add code to response, code should contain + }) + .catch(function (err) { + // handle error condition + }) + } + +Note that your client should have kept ``code_verifier`` a secret until this step and now includes it as param for the token endpoint call. + + + D. The authorization server transforms "code_verifier" and compares it to "t(code_verifier)" from (B). Access is denied if they are not equal. + +This will call ``model.getAuthorizationCode`` to load the code. +The loaded code has to contain ``codeChallenge`` and ``codeChallengeMethod``. +If ``model.saveAuthorizationCode`` did not cover these values when saving the code then this step will deny the request. + +See :ref:`Model#saveAuthorizationCode` and :ref:`Model#getAuthorizationCode` diff --git a/docs/model/spec.rst b/docs/model/spec.rst index 953c281..b622d9c 100644 --- a/docs/model/spec.rst +++ b/docs/model/spec.rst @@ -2,7 +2,9 @@ Model Specification ===================== -Each model function supports *promises*, *Node-style callbacks*, *ES6 generators* and *async*/*await* (using Babel_). Note that promise support implies support for returning plain values where asynchronism is not required. +**Version >=5.x:** Callback support has been removed! Each model function supports either sync or async (``Promise`` or ``async function``) return values. + +**Version <=4.x:** Each model function supports *promises*, *Node-style callbacks*, *ES6 generators* and *async*/*await* (using Babel_). Note that promise support implies support for returning plain values where asynchronism is not required. .. _Babel: https://babeljs.io @@ -14,9 +16,9 @@ Each model function supports *promises*, *Node-style callbacks*, *ES6 generators return new Promise('works!'); }, - // Or, calling a Node-style callback. - getAuthorizationCode: function(done) { - done(null, 'works!'); + // Or sync-style values + getAuthorizationCode: function() { + return 'works!' }, // Or, using generators. @@ -32,7 +34,7 @@ Each model function supports *promises*, *Node-style callbacks*, *ES6 generators } }; - const OAuth2Server = require('oauth2-server'); + const OAuth2Server = require('@node-oauth/oauth2-server'); let oauth = new OAuth2Server({model: model}); Code examples on this page use *promises*. @@ -41,7 +43,7 @@ Code examples on this page use *promises*. .. _Model#generateAccessToken: -``generateAccessToken(client, user, scope, [callback])`` +``generateAccessToken(client, user, scope)`` ======================================================== Invoked to generate a new access token. @@ -66,8 +68,6 @@ This model function is **optional**. If not implemented, a default handler is us +------------+----------+---------------------------------------------------------------------+ | scope | String | The scopes associated with the access token. Can be ``null``. | +------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -85,7 +85,7 @@ A ``String`` to be used as access token. .. _Model#generateRefreshToken: -``generateRefreshToken(client, user, scope, [callback])`` +``generateRefreshToken(client, user, scope)`` ========================================================= Invoked to generate a new refresh token. @@ -109,8 +109,6 @@ This model function is **optional**. If not implemented, a default handler is us +------------+----------+---------------------------------------------------------------------+ | scope | String | The scopes associated with the refresh token. Can be ``null``. | +------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -128,7 +126,7 @@ A ``String`` to be used as refresh token. .. _Model#generateAuthorizationCode: -``generateAuthorizationCode(client, user, scope, [callback])`` +``generateAuthorizationCode(client, user, scope)`` ========================================= Invoked to generate a new authorization code. @@ -150,8 +148,6 @@ This model function is **optional**. If not implemented, a default handler is us +------------+----------+---------------------------------------------------------------------+ | scope | String | The scopes associated with the authorization code. Can be ``null``. | +------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -163,7 +159,7 @@ A ``String`` to be used as authorization code. .. _Model#getAccessToken: -``getAccessToken(accessToken, [callback])`` +``getAccessToken(accessToken)`` =========================================== Invoked to retrieve an existing access token previously saved through :ref:`Model#saveToken() `. @@ -181,8 +177,6 @@ This model function is **required** if :ref:`OAuth2Server#authenticate() `. @@ -255,8 +249,6 @@ This model function is **required** if the ``refresh_token`` grant is used. +==============+==========+=====================================================================+ | refreshToken | String | The access token to retrieve. | +--------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+--------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -311,7 +303,7 @@ An ``Object`` representing the refresh token and associated data. .. _Model#getAuthorizationCode: -``getAuthorizationCode(authorizationCode, [callback])`` +``getAuthorizationCode(authorizationCode)`` ======================================================= Invoked to retrieve an existing authorization code previously saved through :ref:`Model#saveAuthorizationCode() `. @@ -329,8 +321,6 @@ This model function is **required** if the ``authorization_code`` grant is used. +===================+==========+=====================================================================+ | authorizationCode | String | The authorization code to retrieve. | +-------------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+-------------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -388,7 +378,7 @@ An ``Object`` representing the authorization code and associated data. .. _Model#getClient: -``getClient(clientId, clientSecret, [callback])`` +``getClient(clientId, clientSecret)`` ================================================= Invoked to retrieve a client using a client id or a client id/client secret combination, depending on the grant type. @@ -411,8 +401,6 @@ This model function is **required** for all grant types. +--------------+----------+---------------------------------------------------------------------+ | clientSecret | String | The client secret of the client to retrieve. Can be ``null``. | +--------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+--------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -460,7 +448,7 @@ The return value (``client``) can carry additional properties that will be ignor .. _Model#getUser: -``getUser(username, password, [callback])`` +``getUser(username, password)`` =========================================== Invoked to retrieve a user using a username/password combination. @@ -480,8 +468,6 @@ This model function is **required** if the ``password`` grant is used. +------------+----------+---------------------------------------------------------------------+ | password | String | The user's password. | +------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -500,7 +486,7 @@ An ``Object`` representing the user, or a falsy value if no such user could be f .. _Model#getUserFromClient: -``getUserFromClient(client, [callback])`` +``getUserFromClient(client)`` ========================================= Invoked to retrieve the user associated with the specified client. @@ -520,8 +506,6 @@ This model function is **required** if the ``client_credentials`` grant is used. +------------+----------+---------------------------------------------------------------------+ | client.id | String | A unique string identifying the client. | +------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -542,7 +526,7 @@ An ``Object`` representing the user, or a falsy value if the client does not hav .. _Model#saveToken: -``saveToken(token, client, user, [callback])`` +``saveToken(token, client, user)`` ============================================== Invoked to save an access token and optionally a refresh token, depending on the grant type. @@ -577,8 +561,6 @@ This model function is **required** for all grant types. +-------------------------------+----------+---------------------------------------------------------------------+ | user | Object | The user associated with the token(s). | +-------------------------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+-------------------------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -650,7 +632,7 @@ If the ``allowExtendedTokenAttributes`` server option is enabled (see :ref:`OAut .. _Model#saveAuthorizationCode: -``saveAuthorizationCode(code, client, user, [callback])`` +``saveAuthorizationCode(code, client, user)`` ========================================================= Invoked to save an authorization code. @@ -663,27 +645,29 @@ This model function is **required** if the ``authorization_code`` grant is used. **Arguments:** -+------------------------+----------+---------------------------------------------------------------------+ -| Name | Type | Description | -+========================+==========+=====================================================================+ -| code | Object | The code to be saved. | -+------------------------+----------+---------------------------------------------------------------------+ -| code.authorizationCode | String | The authorization code to be saved. | -+------------------------+----------+---------------------------------------------------------------------+ -| code.expiresAt | Date | The expiry time of the authorization code. | -+------------------------+----------+---------------------------------------------------------------------+ -| code.redirectUri | String | The redirect URI associated with the authorization code. | -+------------------------+----------+---------------------------------------------------------------------+ -| [code.scope] | String | The authorized scope of the authorization code. | -+------------------------+----------+---------------------------------------------------------------------+ -| client | Object | The client associated with the authorization code. | -+------------------------+----------+---------------------------------------------------------------------+ -| user | Object | The user associated with the authorization code. | -+------------------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------------------+----------+---------------------------------------------------------------------+ - -.. todo:: Is ``code.scope`` really optional? ++----------------------------+----------+---------------------------------------------------------------------+ +| Name | Type | Description | ++----------------------------+----------+---------------------------------------------------------------------+ +| code | Object | The code to be saved. | ++----------------------------+----------+---------------------------------------------------------------------+ +| code.authorizationCode | String | The authorization code to be saved. | ++----------------------------+----------+---------------------------------------------------------------------+ +| code.expiresAt | Date | The expiry time of the authorization code. | ++----------------------------+----------+---------------------------------------------------------------------+ +| code.redirectUri | String | The redirect URI associated with the authorization code. | ++----------------------------+----------+---------------------------------------------------------------------+ +| [code.scope] | String | The authorized scope of the authorization code. | ++----------------------------+----------+---------------------------------------------------------------------+ +| [code.codeChallenge] | String | The code challenge; hash or plain. Only present in PKCE requests. | ++----------------------------+----------+---------------------------------------------------------------------+ +| [code.codeChallengeMethod] | String | One of 'plain' or 'S256'. Only present in PKCE requests. | ++----------------------------+----------+---------------------------------------------------------------------+ +| client | Object | The client associated with the authorization code. | ++----------------------------+----------+---------------------------------------------------------------------+ +| user | Object | The user associated with the authorization code. | ++----------------------------+----------+---------------------------------------------------------------------+ + +For PKCE requests, see :ref:`PKCE#authorizationRequest`. **Return value:** @@ -742,7 +726,7 @@ An ``Object`` representing the authorization code and associated data. .. _Model#revokeToken: -``revokeToken(token, [callback])`` +``revokeToken(token)`` ================================== Invoked to revoke a refresh token. @@ -772,8 +756,6 @@ This model function is **required** if the ``refresh_token`` grant is used. +-------------------------------+----------+---------------------------------------------------------------------+ | token.user | Object | The user associated with the refresh token. | +-------------------------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+-------------------------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -797,7 +779,7 @@ Return ``true`` if the revocation was successful or ``false`` if the refresh tok .. _Model#revokeAuthorizationCode: -``revokeAuthorizationCode(code, [callback])`` +``revokeAuthorizationCode(code)`` ============================================= Invoked to revoke an authorization code. @@ -829,8 +811,6 @@ This model function is **required** if the ``authorization_code`` grant is used. +--------------------+----------+---------------------------------------------------------------------+ | code.user | Object | The user associated with the authorization code. | +--------------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+--------------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -854,7 +834,7 @@ Return ``true`` if the revocation was successful or ``false`` if the authorizati .. _Model#validateScope: -``validateScope(user, client, scope, [callback])`` +``validateScope(user, client, scope)`` ================================================== Invoked to check if the requested ``scope`` is valid for a particular ``client``/``user`` combination. @@ -880,8 +860,6 @@ This model function is **optional**. If not implemented, any scope is accepted. +------------+----------+---------------------------------------------------------------------+ | scope | String | The scopes to validate. | +------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -929,12 +907,13 @@ Note that the example above will still reject completely invalid scopes, since ` .. _Model#verifyScope: -``verifyScope(accessToken, scope, [callback])`` +``verifyScope(accessToken, scope)`` =============================================== Invoked during request authentication to check if the provided access token was authorized the requested scopes. -This model function is **required** if scopes are used with :ref:`OAuth2Server#authenticate() `. +This model function is **required** if scopes are used with :ref:`OAuth2Server#authenticate() ` +but it's never called, if you provide your own ``authenticateHandler`` to the options. **Invoked during:** @@ -961,8 +940,6 @@ This model function is **required** if scopes are used with :ref:`OAuth2Server#a +------------------------------+----------+---------------------------------------------------------------------+ | scope | String | The required scopes. | +------------------------------+----------+---------------------------------------------------------------------+ -| [callback] | Function | Node-style callback to be used instead of the returned ``Promise``. | -+------------------------------+----------+---------------------------------------------------------------------+ **Return value:** @@ -989,7 +966,7 @@ Returns ``true`` if the access token passes, ``false`` otherwise. .. _Model#validateRedirectUri: -``validateRedirectUri(redirectUri, client, [callback])`` +``validateRedirectUri(redirectUri, client)`` ================================================================ Invoked to check if the provided ``redirectUri`` is valid for a particular ``client``. diff --git a/docs/npm_conf.py b/docs/npm_conf.py index f86915f..41b0381 100644 --- a/docs/npm_conf.py +++ b/docs/npm_conf.py @@ -40,10 +40,10 @@ def get_config(): 'name': package['name'], 'version': package['version'], 'short_version': get_short_version(package['version']), - 'organization': 'oauthjs', + 'organization': '@node-oauth', 'copyright_year': get_copyright_year(2016), # TODO: Get authors from package. - 'docs_author': 'Max Truxa', - 'docs_author_email': 'dev@maxtruxa.com' + 'docs_author': 'Node-OAuth Authors', + 'docs_author_email': '' }