{"_id":"@noreajs/oauth-v2-provider-me","_rev":"65-4814d1001fe2a9a1de8f58ec33f35df3","name":"@noreajs/oauth-v2-provider-me","dist-tags":{"latest":"0.5.3","next":"0.3.0-2"},"versions":{"0.0.1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.0-8","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"670e486c170f2af084a63d28bb53381dfcec0599","_id":"@noreajs/oauth-v2-provider-me@0.0.1","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ymZF9O1Uz5WxnhXfbsKO4sxtS6cxuLBCiY1p9IM7iDaRiW3aIxzbDRrLStvLTOicHfwpo70MtWPrgbK62/820Q==","shasum":"acd303131f2301d3b169e2fb1daf822d29ab33f4","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.1.tgz","fileCount":100,"unpackedSize":287488,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe7of2CRA9TVsSAnZWagAABoEP/R6MgAuz8eTTVU+3NMhA\nt9kKlfPCUfIIfE7iaDWJaLRoYkpyVs/rW4JP19rmy6Ie5Q1pygsr4WIWeG7p\nImqwAdSrmp570JnePPLXOn1UpvhnbdCu5Hx55GMfIMd1kpYPhNp4HrSRhDd4\nmw+UNAgIGYxXAaDlnCGM2hUmSjGKVRVr79Lo+nP/zcEBITOBUwiBv96SNEW6\nri/LgwkuzMiTH3U9OS7SBf3714K5Fc4n5uGfhXK7/1RyPz5Gm6XHje+fv2kh\nNRA2bfY+bLtus/K8dhT6CyS8UEXXMIiqcLWp8BGX8JaYXyCHTFpaIuuB78iu\nfSIrlKTpr5J2eRwruM9xMC/pFYZ+2OWXMS0nPwPSxKRkQyYmqbF/oOm7mwO5\neZFF9EEqr/G2DajFKbvXgYIfL15uISpeiHV7NKIXrknt6W4snDzyCOpczB/u\n5uT3coUPUzLBSr1dIFG4UiR6RDySBE1PRIKYUyp+baLlRSwC+ttraxyCjN13\nkHHpEU/Cw4o1y4YM+PLZNNG+mdvI/mJ8HvhgMQLvCHzygkbNA2V8iL+ugw5E\nOkDX1Bzp2cgP9RH+6RPB+MOvcxRyHWsK6nqf+Psscc9obff72aSEPMGanHZs\nF9iCHgO6C65b8EHL/qQfnrZJ3fSuQXVoePaS0LiwrgyqP7ZEmtptnKgYlTrt\nRhSa\r\n=MQXw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCH14V573pHAEyU81nhCKrCb1hubteb0UJEcb6YKQVu04CIQDi7m6sLQImjzPWXboOw5LPFxxQXEgSgvz2E3j+3zudCg=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.1_1592690677644_0.5637479102791534"},"_hasShrinkwrap":false},"0.0.2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.0-8","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"e278f8fb47253b38749f1a22ce04c7ad6da24241","_id":"@noreajs/oauth-v2-provider-me@0.0.2","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-b/FYaO5oZc7t9z6Chvx0pF24bMEDp8UPZSPBkeq4ULSnFdgxwycBFCRR9loCG4RqOF1Q6yxcrV9Am0Jopwy4oQ==","shasum":"2662b8cc1439fab732119646621194aa294f62e7","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.2.tgz","fileCount":102,"unpackedSize":290937,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe7pdsCRA9TVsSAnZWagAAlb8QAKADK1Vrhws2UazNgBmk\nkDUKlby4snnkSOCbGuGk3A3yP09SHprACkMCCj4rjAMRQ9bEh6PEXyDHgKMv\nc0JRD7P5JVbl24NLoatEj/XYN7ldUMNojL0bURVg+LqrblTKQsktRodpy192\nShd7KhKbWr2ULmUNPe/5Fk6UGojoQyrrhkoWxxdTXtya97cFSqZwoVz6lzc0\nfaNedlxu9FHGS+AUSTQ8EYJQAEO2naSTm0PeodluWGLH4GsG06NSWbP01fVm\nOaZNNGMF+hrwjxx+3J+DPlp0+WDYujUVd4vmmy24oTquHKX7lOIywgiU7QDx\nzGKxW6G+mIUdlFTF4zVU19kZTV3CEZYwNLxLt7O/2VC/vfa/c5rXqzD/JR6I\nDMI0Hx9vMZvjqshTsusyj5urYIneeZ8Qb9ZyHP4ORy6/iOGgNDsETvZk4Ixs\nfMoMOr3Rt5xWNlZoBsxub2Ubhxntw2d2c3X4D2GVA0OeVHyyGDxV30Wq5xeW\nYC6mddot//yI/sZQkIlpEiHS8QyZb1uXWwkafQz2Ic8IxyiZFby68VxSokol\n9cbTUeCbr+m3375gYm+gRDtQ2LYJ6a37lnO4JITTBm9h3fVYrmdhF7fWG8Yq\nmRVCAfABzVQfjeWQz7Stum0oGlNDG1HuuH2iWJ7D9eyiMpI/bh2zcwtrTQTc\n/cXM\r\n=ix0C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwEuq6hSE7A9yGcyv6rA0di219s8374y1nsInNh917TwIhAIC0Yyu+LTNwT8kwnJjottyfyCRVszl7efrtOobaYxq5"}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.2_1592694635729_0.24712961534587685"},"_hasShrinkwrap":false},"0.0.3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.0-8","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"2ce48a1d4b423af58a67a9be87685b78b2788689","_id":"@noreajs/oauth-v2-provider-me@0.0.3","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Kt/sSQgX588+KCdXtho812aVj22GPe3XBvcI7IU2c+Ty72JjDQH81yDSvug8jDfYIWaoT6Xx64dEPV0Sdbp3gA==","shasum":"b5fe01880aff67ed3f9c4eda5a20052071398697","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.3.tgz","fileCount":102,"unpackedSize":290913,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe7q48CRA9TVsSAnZWagAA804P/3+nLOQHGx3t/Fc77gRb\nlKARAUXMpYp0aNUGcOTjUGtuv/dI26iRUFXZqU4TGJF6MgI6uihXLvqOF2CO\nb+HlyE+XlN/Loww2CzMOjN7iR1Yqpw3++5SnQssZwOqHcY9X+sRDMwNQEmoq\nOwO1JAk2HvEyyZQLAA7rYZqVkLKkcss9GvU8e1yc8+/pG9y9bv+4wE+n7dri\nJ56aK0p4GgoH9hbOjcrsTD62Dx9CHpUXSuOxjzm0Gsv2XvG/w9KLrPyMnB0W\nLyvx08wPzcHVeUirhW6x/0NZTrsYyLseZcjIGvD+AGdF5XJKwlI2QD/9DXmA\nL5ay6OIW7GCU6YIDCJQ8anZW2p8DIGZ4HlAimPp/1geC+4wo0KYbWdAI/yx4\nUduzjOGFI2VyeJzpiAUGfmTMln99CzDRYZfyxVYKhVFJwjgG37bh5qA0Wsbg\nELsQMweZZsmk9Zfqqs2fq3CR0UDGO1DdYJ1MuOGJiXb1At2o79Eg3kEGD7WK\nkI2TRxga8DW8ZlXK2K1VnDwYkmsjj90/sCwm8o6XMvDq8atjS2f/JPnujIvG\n59/wPnhrTdNc97Y43L2RVEhPjI/cJf3emDXNFRlsXXFoubmCRxOLrdj0MTiI\n2YVnmpXcC9glKpJFW5DwcElcSbNvwguIUgmF3TmZAyR7LhwGy5XPEFScpNYq\nFgo5\r\n=ryur\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID681ghN0gnogCv4DngjIf/37ilu1hg3rzIbizi59eHOAiEApuT1mRxxqJAAbs4us5VjmJfB4iwOzb+qVEpht5Q8UhE="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.3_1592700476010_0.06596698799229195"},"_hasShrinkwrap":false},"0.0.4-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.4-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.0-8","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express) - Experimental\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"acba36efba1a63fac50b359cdbb7cf78d86b9430","_id":"@noreajs/oauth-v2-provider-me@0.0.4-0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-EE+gF4v+iKas4vuVT5cYkMDLmsSJE+cQhN+pfsCerOMBmO5acs2T6xbqNkb9xaBm3UgWNCmlp0X3RkpaTbKv3A==","shasum":"f07b882553b02ca80d93b29e82dce360e65e4ef6","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.4-0.tgz","fileCount":102,"unpackedSize":296694,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9gyVCRA9TVsSAnZWagAAkQwP+wfDL1fQDCh3mZsTESYU\nuPJc2ikrgIZovYc5y14ofoMcV18cZWMMHxZv/+T35hiUt8R+lOkJgNJcFYOn\n/wCs3k3IBOmxfvdfdhYhWY8fCGXhnk+NUUMtXawGLnDQIKOYLGuO+jbf2Wno\nGpNftMRklByBoME/YMKoh8xwiDEtD8tR5K6dkd+QYDYuvXB7rgfmB8muRCy6\n5dj6G0XwivVkvoG51m2uQAXPIqZlt1A5wzoR3Mt5RVpMQfJhbb909Ov2qLPz\n9yIVM9cgVz3Q+vCjiV4/JdpI4UMq7glzXG4q8VpzGqKEaDxSg09tK9vTlPE1\neFDF/ULTV7gLuQ7fnomAzLzYLWk6qG3o6KG2NfKrC4WIthcyS+UDJsqcSgWa\nMiZAXfaKl9wFpkwuvKOQ04v54hXRDzCcMvCYTwf5bRMXY6yjWEBZrz1UUxBG\nFSldnflu7JKcLC514qrfjAunm3PTrenzVigwD0TBbveesOActEX6hsitsTGH\n3n5ISdL9Hirsg3CAlxEWxoZj06S+Ci9W0EpB921xlIUNCsFEp7M4iH+p/LVY\nkZy6GIUnvatUJOks1WwzwfCXf4r9VEjfcXgBEmtmAxf6EAm7U6TFVrFClVTt\n9Z9zY7FW0ddVE/0CAzWfA9bvBy/O0FJwFrgjQysrJiK40N+KR0J5Q1OCDmkt\ngnTg\r\n=negg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDpRVEJF8T7GBUonmMDh2wFTIXx/EE3ZoObU5iWEP6wwAiEA5qR8Hip1sC9nPtSx+iqUL/Uy8jf5OkQCnS1maUQdJyY="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.4-0_1593183380746_0.9598355342169467"},"_hasShrinkwrap":false},"0.0.4-1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.4-1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","colors":"^1.4.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"c138115f19b7b661535d4a140ac2c6d9677501ae","_id":"@noreajs/oauth-v2-provider-me@0.0.4-1","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-u3pBuAPO/LZndemyq7Vw1TxwXwV6uKvTBRUGRKKJAKpd2i+3KTi2LMV/6cjH/GSGCWcsoXaNU4Fz4VJH/cbSbw==","shasum":"15e87d5c1d5c1fb5b82e9d07575510f7d6af758d","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.4-1.tgz","fileCount":104,"unpackedSize":301954,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9tMqCRA9TVsSAnZWagAA5qoP/RQg6kVMkwpKlD/fW4HK\nDAWWgKmxWHEOwSWUDUTsN0/Tfa4CEKC0Jv2zBZhTq73+EiYkMx4odjEl8vHM\nVVuL1LzjYv+6O3FqtOUmL1oz4JZdLlqBvmxvH3Ja46dXMeC3YXeE+v5lI4fZ\nJ6T9rkOn8IWQbol1ldWHa/hrfPmZP/DeLeLyXobL3qhcLpXAKidebBV52Aaa\nB2EgCC1BsUND5ea2N9h8h3s46e4Av7nJF/rBvLfm2vfrzZ3TLAKa19btnuqO\nl4TBSLgTWFs4ZptEx3QIT4mpLMahYUb+V0w+LSNU5qz3GrsUOdP+vG9LsbbL\nOE6OPzI9auZp5467ZfcQIPUTdvy4FWwyTwVzBnXlkMmkZ0e/2NxKyujg4cen\nwv31fRruGo7ZAxawUTgWM5yhMm7OIt73dFlczarfBfeL1/2aJJeUL515ohzx\nLNxeE1Yps07rJ6F4ICBIz0FXuu7Y5SMiBRGYxCBtddh+tKK/eMH9XtPt5m6u\n3dtt1cKll8QcPu4FRdj9h6AC/LI/4FuoItp/GqwJEJKYu55YIFzkszLssllx\nexY2L5waYvTZfgYL0Y5fPcpVOYCeKbuaZ1Z/Sg26h6Qxgwt2/QbI03o5u1Vc\n57kHr0SGGvEynTQz2S7LUcYuXrvTN/2EVh3knBK1wiHymsg7wjLU8RK3geA7\niARK\r\n=+lZD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC7l3Vkz04BGE4W04bgbJcwdu3vW98AhvXtegDE9pdhpgIhAOEqzH5ZjRLt/uWvNnOEGJw+XKK+Wiri0fuq5BS2N4C9"}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.4-1_1593234217504_0.520702775507297"},"_hasShrinkwrap":false},"0.0.4-2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.4-2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","colors":"^1.4.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"c28f8199d227fe0521f5655d04a26c38fd1b92fa","_id":"@noreajs/oauth-v2-provider-me@0.0.4-2","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-EXAEQAQ8btTBdontsnSkk15fWWDi4U8LXV9NsDfvWzgAXI5yNf/8u/KTUdYR+6PnBkB8/cRmpzUUqS9hWwKEdg==","shasum":"6542f8b1f9786a3f8e547bf37142064b755515e5","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.4-2.tgz","fileCount":104,"unpackedSize":301879,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9+6bCRA9TVsSAnZWagAAFdUP/2uRY43AQVjM5o7Sjwvf\ninhg2yhlqp+S9Hk1mRiUaeuZk2HvzwQ4iklujN1pir7XRQRcXrDA3b8Qr6HM\nNs+XJ6gUc10yhnrIua4huDGY+foK1rDnm9DRiPASinqZ6aED/qi6gZxUiHBa\nhA2BbYgovdjbbqBtjPJ6KP1ofwOtjem3K5zW1bKcJIITsIfDQUicNjugIzZN\nPeWDo4ow20uXmhe/daAo0Zbfuxr1aqV6MEU9IRP8ZeEoHUUOg4xVOitUQCe7\nr6/brMtYutUcq4HBwAIbDXERDmvtgpUBqCuqjOcHGATeL1LkLiX65ZUYOhoI\nFAg8XR3plXf9a+4Vl4j6et8vVtPQJgfrQhO9ou+lTlHzo07XP1hdq/khEnTl\nu8eqDj1X/TWA0gA4Hj3rg6xZiOLR4WkKSVxubYMACT5ii2zP5Vp7zMwxdxKz\nUpcjvEDkpd4y2s1LOaopVEdWHEUT542u1TDKfM5gs8ibMl1rrULHfovuiEll\nm5FqTYZgqo7buO00SwcG5LgR1QOCoyLaWFlgmc8h3/cXusW9OcktiV8LBBNi\nm2wk8u3cuMrAdwi/9qf96oUAQXHKeenf7FMf+lcdVMrwEZvdCQIBoQCYUu3t\nvRyydtEF186gbO43fcxIdqlEwv6CvBKtVJjDMwncTkvuCQR9usGWeXtgexnU\n3IjZ\r\n=JtaP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDi8gO0iXVameMMrAit7WATNfsTr6mfbKyNkbtSXnWPGAiEAlAsC5aYDHT2CyKnx35j1tHtLbs/K5FRt57cy9Uc0qJY="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.4-2_1593306778859_0.8140136895804015"},"_hasShrinkwrap":false},"0.0.4":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.4","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"13520c941cff677656d149938b0b22c408fca9d1","_id":"@noreajs/oauth-v2-provider-me@0.0.4","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Zt0W1m94WYlrNZfuWY0G/0vZDtEe+BFIHmSM/tcaFqaT/tDo1k62Y61moDkakjZYSOSQKazODKiGipcNQmmL9g==","shasum":"5b6da0c748d3646a8a76359187037240df83a4b7","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.4.tgz","fileCount":104,"unpackedSize":303742,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfdxMsCRA9TVsSAnZWagAAGS0QAJVcbWXAO5Nak3/RsLUK\nGdaZZ5CMBMHDTjk6zwgh0t3cNgtMpVAVOZS0/Dg7mkwM6ARHTz89LAVb8Ejn\nl4OaFE0mesCc56gl8YoMnVL3/YStB1BIT/X4+MNSU0Z/keuqm9L5R1wjJoTu\nkBBwv0FqOTotYXgiRkcjm60VrkqPZbvJWnbAkhPr1H+yEs2cv5jGYgB0GUq8\noJON8zn6glR+6nVjaMxmFfYADkT15KmQm9ZSV3r8w4CuJuH1ZsOguGiL0TTr\nmvlfk6mreT94/zeK9zETHQcxD2Zppink60hsOvhf2qLhWxj0T/9DDqT25d/D\nF88ZtZOl8ZdAbFjZ2dxoCfRKr6SctHBLyXsvJbYt83KrrDzCg1mEaAMnIXUe\nY2H/nsdK9eKq/xbV2v15cm8EOQYfPO8E/X4NqTxNES/phKW5SFzqguNslS8B\nep3aTycZzPUlE/s/5+h2pksMyXi2KCHJ06ad92Te4GDBfxlEbElsQ7YTAPzK\nlxJ+UutVgW73T/w5OAfgNv1HzV2alLzVl5sZ0kx8j5/W3vbOYwpo2vxSOmRn\n8JzrUbSGivdiJMJWEDvehTB+T+BhOLtBNGFKUMuPt+oaygwNDt7rODUeVba5\nPPgnAPJ9d8JSPrtmGhxNqeaPwnORy1GURrDxr6vr075wfRH8PI6btOkcmK0H\nkUbe\r\n=2umY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC017EsT+p7F2r28IjjUN+zZq+PO36ksjwYNe05eiRE5gIhAIn1mIX8vkjuX/lPo0N2lRctHPwi998sY/JCzDEC7aPp"}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.4_1601639212224_0.3133754327466609"},"_hasShrinkwrap":false},"0.0.5":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.5","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.3.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"87bcf19734974eb6386eaa87ea69918b253627be","_id":"@noreajs/oauth-v2-provider-me@0.0.5","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-U+3hJ5zJSF+uwpzBh4S7sDDD9jd7+c5WtPiCBMBeCr8yUfZIzcPkDVXNmEXTfyF/MAnIx2G6FZt7jNqlSkkU2w==","shasum":"d21f66f548e26860ab10f9b9d3a55a7969559f75","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.5.tgz","fileCount":108,"unpackedSize":325312,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhqXvCRA9TVsSAnZWagAAC1QQAJ8EzOpXMMcvTmJ5kjcX\nex1eYWDXx5b0zLyBhY1J05dwE+DDMqqX1n7QcIMv/7yjV+G6MRpqXwzbELnU\nYmOwJoLoqJGsR7wdxjC+hTztqgbxInHhQ2YzlwMlf3eD55Qgdx2qzCAp44HM\nwncJrgoFUbVahe9U9HlmJ+Ln9FWsroQVhjLmnOp4tagVf9LpxToScoh18oxG\nKMWnRrx7ooMVtsEofyhpoykkUMOiK/Vv844kN/lnoZvSIx4kex1bCV8s2A0h\nvNwHxUM8Yuae5Imal8lo+DInhh+FvbpwUm+W+JIEHEIqjIdKxb97UyKa5NPR\n+rYJTuxeT2xGbokspEL21Tafmsikooz6pyD8RPSMZyOI0ORtiFnVifd+Q4+E\nUqndFRtdCJXX4NgAFgDBTB0E7UeEux2mF92yVkn0kZLyLNNQ5BP7cBoiuD6Q\n2MWLlP80ook9vwgMa9rXKZLp8hsLEGAqjd4v4UyPGtDHXDBnTZSfoPNPCh1l\nijlLgB/SnYQhKLw8r0Prz2Ht0478Fz019g18tCHOxcH+o7GYQev6oUbFaoIF\nToX408uAy5+8L4D06L6ToyePs8qzxjiYBN4UmsmX9fDKpUAoB76iDtiFUp1I\nE1xF6+A0hweAKVS1qmCfCcQB4Wd2lgCBv2LR5smrSV4EAziR2YrG0Fz+uh6y\nuAxC\r\n=ECJa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCdx4qL2YknbS48+v48CzNmzJUB/D3yk60c6Vl6BwIFEgIhANYZ/tcrj6g65QElA8kjfmyVBAJsLJDM2rqFhLllOemr"}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.5_1602659822374_0.21934167515979408"},"_hasShrinkwrap":false},"0.0.6-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.6-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/typescript":"^2.0.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"128dd2cec816344edff0a482e3c1cde1a7d86a15","_id":"@noreajs/oauth-v2-provider-me@0.0.6-0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-3XyZnmp44bOBZD4cNal40qv7bmSUXJ4V1pUH5ImtgBkzsrIArCmx/GGBPUPXhjX/hDHPFgHYiwmAt/SpYaTlEQ==","shasum":"b0efe0b27163b84405fc82651ad8bc8341fd4bcb","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.6-0.tgz","fileCount":119,"unpackedSize":359856,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfi+/UCRA9TVsSAnZWagAA2TYP/jN+M48mgT7pzBBsLA8Z\nG1s1BD3kaWTCjGXe2/aoukZmeiu+E/PL51HxTwbbB28AFmAxo/OBS+GqEv7d\nCw5hvXIsAdo6BqACvC3zlc+UXPx/6LMCIane9Y3r1KVaJp4VTLlhiroK36LI\nAwZgDSKz3YkHnNXuyQq1V3tbydtGAabs5nfI8mJuj2h/ipHzz6Lu2aKsJsOy\nQzYjQ3gMrMPFyx+AxpqngWt4wXQfVYnrdOQAvTFXuOX5xKsMDdGIHd9GM6Oa\nsl/jYiMzxDhvQ0nBs8OXhaJnKwklCcDSlJO5tO7jvfBV7mZBrd8ye9hKYEAT\nJ8452r/45MGZwSkAWz1QDu2GHhPhtYkWU/K6b0NCcMqk/2nGzdewZ43hVmzw\nYiT50JjMaxzg+YRod0xwohs1VcNSMFM9khgPkz2Nh+eIWkcRXkvOrbLYHxgl\ncVTRfIWJFKjn5MXpQRjH27nKpXh8H1x6qC5i85tDjfPY12IjQbDk4yCKhLOf\n7ictliqj92pZYPKl98zOR1drvOJ+CneoXw7wUXkcZ7HNkpPpiVtyYXUa0suH\nBhNTbfYFWjvzv2cLucMP4Fq/2bgJO4Ts3/B4tnKAMo+JXKot987ACDXWOIy9\nfjdVNOmGqA6XN+7BqLk/mVcR4jnL1/B92zTsSSiPM6hrUFuomoRXIUPb/h1j\n6tYv\r\n=ID2l\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGVZRWCHz0rQ5QEnogsj90wZH6Iuz5yiUbCSHSZqC8I3AiAXkUCoyv+SpdhktiIl4SlIbRPo8Bsgv50VyIkwOZhmyQ=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.6-0_1603006419953_0.9934576927224861"},"_hasShrinkwrap":false},"0.0.6":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.6","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"ab2442d9876edc0e376503fb02f278b41a7a148f","_id":"@noreajs/oauth-v2-provider-me@0.0.6","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-KLXjbq5Vph3/c917N0/UOjBp2Y9K79CVyOUvWkXrCE/6qcLWBrWWdDbB8NVsCASYDeCuUAafvhhip39WEKcUFQ==","shasum":"f7a4141fca4eca1a719329611582e6f1efbd2811","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.6.tgz","fileCount":119,"unpackedSize":359379,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmBqjCRA9TVsSAnZWagAAb3IP/2bDgqRGS7QaxlDjvgus\nBNE08Oe4+1Ct9qqVC3ADV0l//+eZ2xmVtwKkejobazU+thg9I5FJs0TvS2Vx\nLFf16cU//+VfAU7M2YBS0zQQY1MYr9vwbXGrJSdTKJ4pH+R4SkB365ufA2TR\nr9HZq0+oQKBeyumZvmJ+kD7gLvMw7tEFX3B76Si7Rl6X6dLvzi6MSHAf/z8J\n9cpZmQD7zqrfFbvpzq496e98HSHirnqM4NJ+skj1YkLIRE9QpPgQEG669vNa\nlaZnb7feCClz0WuHmsaRrbbBrmT03YjU7Pp3BL+Ybw0GUJ1ZxK6EGH7LAXJU\n/OT7K4/5cWQPG9DJZxDRtHDiBenG1bBmyQo6f0mPPqBcWExht/M03bpA/tHQ\nflv5pfX+mQFgKCW/B/r3ixrADYpM8xFAn+WRgMWVvSq6j72TJhpcIAMdrEk1\nnFfKqKPj2v+ZzJAI8Q3suqUS9hRdOCWXnf11UtXJsM49hLf2xR0HKWonhW6p\nTkdXNO1duzS6/A9IgIxNQXz7mM3KaCUwL43pckzPt+aQHQVCxguvgVrTu7r2\nd+R/7hyJuWtblTBu6VGw3Q8yTuPg32tyANMEI8qWMHc/7cL6z3FtS7vYs3tk\nQ8Ed4/A36ogmbI2W/AJvuyTmpcK57QW60M4fnKQlds4QLWjpZeYxm+1zA0I5\nxstw\r\n=UhK+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjRT6NWoW9bYSN22Y5mystAn1OtYOVN4Dmz6mpvHemIwIgI0U6gOqzpbz8bsXFjEfKMIGTVgLWep9DfR26p8qG87g="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.6_1603803811254_0.8079235503239499"},"_hasShrinkwrap":false},"0.0.7-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"03b4ecd1fd1538ffc2d880a6b66a8785e6348c8b","_id":"@noreajs/oauth-v2-provider-me@0.0.7-0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Rr9PfjBhOryRlh1YzXLJGoYYmljyaePAIuSHJbEV5qS2b9mInXsDp8h/DbZdSLdChBf9K4/PftQoG99U9YxAng==","shasum":"9262412b7cb1e2b423737b895f418a6ea84ff228","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-0.tgz","fileCount":119,"unpackedSize":359448,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmCLwCRA9TVsSAnZWagAAF9kP/Ahg9+oG6fo8VN1dxm30\nmawbGHp2EQi6uz83kfqBJABE4f0YwumTo4bcLgWuTSXh2RictRgUqBeKp718\nHyjSf3IlHzT87yOj7ujOlntSHscB2Bde0WJHoMMeO95GkjPUXMuWYKhY1kDf\nlytL4ssmm1Njub9FI/j6iNt2kGzqqFwKX3eAb9vpF1xNrHtYykkNvuUPJ3nV\n2gWFSS9EtQrEuA+ttkSo7E8MG2YmHfBrOEwylPzG0BbPWCFql0hderPZ8pPW\ni9RYz326T2+2Ye8i2MHyyppYtlN34MdpHuyx9fHqEwzUvpKnjVEiyhyf8sh7\n7dW6u8IyBh/XRk9z+aRnmOoz7Z3ZdGxJeFDbSpamhGUcj7GF58C+jV1hyDuj\nxR+kCWjSU0PsJPaa9JRdmellHFmPrJSeok3yvPcQ7Bp1U6Y4M9ar/XoPyu/x\n6m50/Ojb4Gziia2p6/T4hWJ0ngrB7UONmJGOR3JuB+vUjui2FVQMlPkqeWKC\nYcze1X0V7NfTnYryknEVvrYBLLXYdm3pnfJ0rluYpVtOu7o5aimZW7EXh14B\neKODQbRW9ii0ZEl6G9axkAcfxSnJ+DCSG2eSgbhxNvZjuObScI4uWq49flJ6\nv/Wi0JgrkLXQdH0T9N9C3fCaIVxzhIaGRrhdV9oQVvRAlB96UAtK04VrB2NE\nTfgQ\r\n=TDnk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICMIgBvgYdYJoORCWAh5iLqnBYkpiqeDBpQY3SvhY+rvAiEA0XxJdPo/i1WYPJ1UzksMvsaD6wEuSpUFQVJHANac1so="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-0_1603805935880_0.3360578033899182"},"_hasShrinkwrap":false},"0.0.7-1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"3614c78d0d9a2ac8910b6775bcaac7e5c71ebdee","_id":"@noreajs/oauth-v2-provider-me@0.0.7-1","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-q/bNDISLNctTgK4Arh7McKMRYdr8CfoifeURv/c6sBY0GHtGwAxi6bBdf1UTC/Qr6yRYMedibTQjD/Eauq0jCA==","shasum":"0f9f20d0e857b1c60001cf1a75d1c009f0a873f0","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-1.tgz","fileCount":119,"unpackedSize":360039,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmDWmCRA9TVsSAnZWagAAZ5EP/A7U9GSSFQoNiXnz6C28\ni6JrYic+mi7hPDZtwQkIdiEohiAZRO8rAPA1WEVvRl2nBXgXo9Wj3/gx9dFA\n1SGBu1wOeDzZV59x7Jek3IypAtAJT2TXxVxAQ3df1y72MhFYAT8LIVP7SFqX\nor2ZDJWZsv8rl9uAEoMzvGfYkmytGaA8yiBVlWWYqVOdlsfpbXy1fjyJ9bav\nHEWMFoCpoXkOJ3vnPNPbFRf1dakSLenJwJ7Huc/BQ7eef8h+TM0qs3MPF+Xa\nRaQvmEMkKHGrnvmYxRtIyLgsznc2EmzRU2ZpHTB2w60bvv7Wye1YkPYH741+\nfWcTSlBRo8BjKBCeVBadkTdTYHn5JLEWLmvXlqZ4Psw6QvXJQ8O4sE/go1je\nKM6xfPspe7X4Dqm/g9WpnqYKQJFwsi96RvzdXcelQ3m0JmmE9nBBqr1jKouC\nZopTfHFmNYIfQDYp/FnsSOxZgv2yjL0aKKmsn8SUtaTQKTNc9QXjKyZ28qGl\niTXp84DevzDTo7MvJOX5MRYp6/AyXXyuBIITCQUcEHHIKvNCTpSABDjiIiAu\nt62qD6ZWR0Z1DaNL6xGfrr4qebibPNtUiUvxwq+50KWHqnF8KFAh+dbaRXUy\njyeRwNxFY/+4lz6pWb8ktjfYvXeOzepxzJ42mET8KYsQWndvowdeup4LXgrd\n1Hr1\r\n=RjT3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICtZq2cau3Xdg1q0HkOFy1o0gTBh9r4TU8QDR/34vKADAiEAhDmiI9iRrr7mq0LrI0bsXlE0UfMrTsiH0ahCwZs//sc="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-1_1603810725868_0.8140777195748006"},"_hasShrinkwrap":false},"0.0.7-2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"1f7cb3f5341cc87a9339519c6b34585d1137b219","_id":"@noreajs/oauth-v2-provider-me@0.0.7-2","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-JWeKMqHVi95/4yUQ9Sm3XYYn4RBoFfj9SIABWpm9ukcaBvoSRrFIaPdpTIJl5uzRRpcV+O4inTQ1y2jspcynrQ==","shasum":"b6791457e7ed06cb0ea11ab1343871184b4b76a4","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-2.tgz","fileCount":119,"unpackedSize":360363,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmDf8CRA9TVsSAnZWagAAzsMP/ik4YOX3QS1nkAI2klV9\nUcDT6F392a/iBH2GzbIJXV1c7kxBh+nRV8atGa0Ou8iEIJ1y/tUGsXpORG8F\nzQfV5BdCAXVyfuZmC4M1O+mOAFQTJcZRhqkxbFX9RY3UE1uIzcJsKocbWw8a\n2zzT/CoOg6LsBVZACn8XCgC1VpGTZkg3iR5ugluFhXxZtKmvTcETeBZ4SJtZ\n1VL05b7phaSedX0wJIuasakbvL17qiBe4Jsq4nVpDRYvUHIDcCh7BcxtFmnl\nEqbBmjRCJp6rneF9kKl/MZmJ2KrLmW4lv4V16v2EUD9cLVX2WOFABj29SD8Y\nLBmWhl6j9BCRVoXHx67PJJLToMwDudBhQmhRa1Ws6bFkXCirWugj29sq2oDv\nJOu1eYqOF64PZ3ceVuPnOedozUseMwsXYou3g1ZOrr7P9IvnEbg5SLR80010\non189W00WuWsc5dGRMYc/kOwle4JefnvCcTACZZoJbhWw8xSGEPyjuKhPXZx\nGyWFPSKYYRljsgD3mxPpZ4dfO4mN1j6KCMasjptwGKYfQypsOtTbXiKBrp49\nC7CZxq8FTbpDd4P07TfFExf6SfkjoSscfdo7y4VzLiyqdIwpi/45M31v2UuE\nMLtrMgZNIkr4Bu+ktMoFocx7bdWV0Bitb8JBMR7F3ydOaIzQpPucjtAJ+vuY\nb1nW\r\n=bjjb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAOd/c0IzGCxUuHjLemma0GQWupax96hhTazL+pKh8TsAiB4Sw/+tlGoiQUYzLAWoim0hOJjq74a3CyWSteriuJfCQ=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-2_1603811323622_0.01686564792245937"},"_hasShrinkwrap":false},"0.0.7-3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"6734d724289ccde2b77c551faeb073b8a4a7d1e2","_id":"@noreajs/oauth-v2-provider-me@0.0.7-3","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-6lckF6McqCg9QgCEne+QrnTK2RAd8tswM7z0tHKldzm72kgGUHVrZ7XhOPezXh2cgTyTe6Cu89RQlcdb1jBLmw==","shasum":"ddbf6c03c6cf0251177258e374af83d12bc56143","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-3.tgz","fileCount":119,"unpackedSize":360637,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmDpFCRA9TVsSAnZWagAALDcQAIbVR8WY9MeSpdDwnPXK\nxSPueTcPC80YX90EoMGelLC/U2krwVV5DBqMMBUqnAOtVVvnzdoAUxjybeKl\nUHPBIX9/1zUAwB5aCX8J8YAdhTs/+wInBcO36e8F2E1ggGpvkj3AgxeBRPU5\nMPJikCU8zky5V8bHpJTZDstfxJzHvpBtt5KYnm2W1mGwqh8ZZdlINNxaUk2G\njAT1hK0Q9nusBAnmy0Q3o0whmXQg0bMinr24x1Ilj+m0VFRVVFZ2L4HgcZmM\nRxSUNVA1Fr6h5q8YeXUFJtiU9yPOKQLzCyin7Pu8RYr4LdyPajX0oc3VSDch\nGN61mtAD1Xxzxv767t4DAXndkAwghlxnQE3ubYnTQxiLehfGZwPfxYboRPaE\nRJgti+aSPmop6nEfDXxEFgt5gWGcn75nsgVsuXTM1ac5WCtfuLYlQmX8aDao\nzRvs3z4oF6BE3QHru5clEud3bjlduwPFaJg6Z7ynh3ap7u85MqI+1syfwXl+\nOgUYkvh0mtRspKKEUc3nqAlYuemGqe9/sM3Jq6zVot6feZAEe+p8n4KgtcBf\nufa4hIRaYzhnBB9aMaAi1QJv5LOIN6ct5b8OkqO3XSzLt8rXkR+dHn/qm/9A\npoOTitJSNgBkcHw1NLlp0LMs/qrKOTm9noFat0F2dXdIH2fshjegaSTHI4zU\n7MQP\r\n=oL2V\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAGOxxpn77eJ5jqSUvDtSzOsldViRdm0l3vm4v8HB4PjAiBrzkTcKu1fDEZgh8QkD5c+TXw4Cn87de2CGLlMQJumKA=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-3_1603811909179_0.8416925854262216"},"_hasShrinkwrap":false},"0.0.7-4":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-4","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"9138bbbf536a4163c633ea9a6157e171cd5ea015","_id":"@noreajs/oauth-v2-provider-me@0.0.7-4","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-v3kcw+o7sG07NY8kwXk4oj6CFdrqIkb41udSSbMIxHUiSjRYj93S426HyZfBQR44fqzIN9YZdVnrEAbpve+nCg==","shasum":"1ea2e66a488ed6c42e9723a26bf0f57584d56c92","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-4.tgz","fileCount":119,"unpackedSize":360230,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmDzsCRA9TVsSAnZWagAA3oEP/jQF0/rsPbfUZNcYunrS\n9BDbxIE0+wnbDa00cIfKU/qPwX/0hLi69gH9BZRctk8YXJKcwklqJR40lBNe\n+JE8kqol7RNE/N8xzWXnBPkkOHD990NUYoS0fIZLbV48t6MoxH9EPNe0ac/+\n/on35xCzi0e625hEP+fvFvMGki7+xp+QML3HGV8m0q3NTKLM3YmdYAmSCozo\n3qjnHPFCZVoPjxrRtARpxEDwFkBEpMg9o6k34Py2poM0dWsHQ1tbb2PDpXlp\nMQMi8H1oR9GRwZyDQa5LOKBWSl5LhPonXJlPqeK1oAiSLMsrg3JukmWCJecn\n+IwmCGNCRIlB5/AADKGrQ9oCkFLcIuKzKD00z+RJ7/Bup/a+YQq9W+DvO2tI\nhfjAcwIG6tiDFfp+3aSXyx7pp0Ry8QIS2vYMyYPPhdLGlMIQ2FMmrWrr5JG+\n/gNY/2vFMAcTXvnUuxH7g60w+7Ww3vwLC7s9FMuvYaj6g1G0J+6BI1AlBmqh\naPFO+gUMSjdeUD5nGcLDXwEb/eIsTG+6sE2KSSQPME4IhHLBK6KUX1ADNETt\nJ6co/6zxuMJrvdUj9ihhvTZuZ6f9xv8kNufrv2oXLBJngwfKPX1vi9X9I9i4\nMXY5v/aSbkb5ScF86xl2DqpK+vAoEdfSR/bFDDpO8QtbnLPTQwgtlgCnqRP1\nIvW2\r\n=qaO8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDhndkV582KGG7K7+JhUJHQTzRzypKZK21nwyKtsAsfGgIhAMKJyzpnQGPQNKbGL1YupuSC3YW80UKd7PMoyLVOG7t0"}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-4_1603812588214_0.9489189225949564"},"_hasShrinkwrap":false},"0.0.7-5":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-5","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"82127bad333e8cf0573bd4d9e9887ac028c02570","readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","_id":"@noreajs/oauth-v2-provider-me@0.0.7-5","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-wu8+t/jr0kK7a5+p0la6gnLmnYwwDn7QsBUJXr94fzvG8UDIV/4OT89P+IxzGK+go3sB1TOGMPWIJsQSguRM8A==","shasum":"93fd525717bdc8652cff08959ea3200a0387d16b","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-5.tgz","fileCount":119,"unpackedSize":360324,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmQsOCRA9TVsSAnZWagAA91MP/3aZ+rkpSdCZO/IGpykV\nISVRqKPEYU5Ibxpy0ohoPxOPZurqFFuZpP2SbYo03Fzh0uYN9TavdPe2hj/w\n0KtPrtqOqcfsWq3FPngC6hi3e723EL+DR36rLWxBnvkRh3azji1Ikl4spJoo\nHXBk+YkbIVMu/5Eu+Mw7thJMNmck1zu/gf0FVq9dPUQ7jCVvXYzx8xAC7wXG\nN/DlNl2c8OJvGQ/h7smMPcM86m2QJEpOGzRoqEPfKG469hn5qGH0UtKV417S\nI36izTYxEn5crYCwLECqpDMaagp7VZ5abxWgXoAU7cWzwV7HnwxF3E3sMnKH\nQkdrj/8Bc+PqaKCvG/njJAUeIrSUVFrCg/VIH53YQSXSgLdIMknCDK6Td1yK\nUr8FYnp3vtaylGSH/A6AobNlHwAl88MZU84KsQL0uFpe1pZ3apRTMIclaHnt\nfc0qXH4tIYd6ydKtCKcmWOGpme+IluaX/tlQ7TiebZUct7nNZpf9dn0JvUoQ\nXVHUe9ke2YP8Qa3NnTporw0jkoGpj4HUrotaBvSrFXhaFaKCvZqk0HMypjvT\n0rU4RUqLYLcloqP1JXWp1vIY093qVL3FrI/KXQZDqXe0e7Q/LMQNStfUdaeO\noX+AxswGkiob1S0YBgHLfVpCyKQXDpxc9uh+tNiFbroIraukI20P1HkEcYH6\nG0t3\r\n=V5v7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHn7AVcVQqlf5T0uSI3KDWnnaz7KC4n+JjF7uXiKfevkAiBrOXZby7QKa+gl4xVfMDHF3vfPefheqtSF3NkLdOoHaw=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-5_1603865357644_0.9236220769819086"},"_hasShrinkwrap":false},"0.0.7-6":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-6","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"8d0aa2ce1ae5185efee9b33bd1f1c7beb749cc5d","_id":"@noreajs/oauth-v2-provider-me@0.0.7-6","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-1JapTxfwdXWcul8x0nzIYgnGW1ICpdv6Vsy+LRMKHSUzvqAortdfTAr7p5oMV7uUVMy0ysQZ0hVNOEfRdZynVA==","shasum":"e42919424619b21188bc750bb8acc6cb039be1d6","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-6.tgz","fileCount":119,"unpackedSize":360389,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmQ9YCRA9TVsSAnZWagAAiMMP/iNKK+fAxbjHeFbK/Wv1\nGkx4hgf4dKqxsjiLJXHa1osDnR6kAtnRFUZdw2EvE1YugTBgx5CA+Cw2D/U7\nq4ftndMkibCaz1bZXbVuhAvxyI9cyNuIHdauDd52S5dqQqUv+rlClRPWt1fb\nRFvoWTjnc6+i/bFBPIXAR05wFvBJkrSPXU6nult8qzfMMVHPemp/lWHSOO0R\nLajCvXi4HB7dI/RkxN41N8EfeIx9r8/3KUSkwphwo+I8c1YgqP0MGna0c8wZ\nsdWFPN0lfOv2KUU/466tgmZoDJtYKWbrJ1RwC4M8UpR4N4CLFdj1vfjFAX02\nYY71me/3ElqzTiJQQ6WtmvR9tsm5b44M13uza8NAIpjbynmdTeeNNO1eaKQz\nAfrYS8xESGvyf2uE/MdW+GGfu85mqTUO+CjJDTYMhwEetrVRdlqwcoJZkyQ0\npzynwxNxjYfbW1bB986/cHTzFq2zGQOfMx4UE3kb9Xj2Zny1MWaYJpOgvtib\n+ELgtWCDFmDNjvt4jOm9LVx9M+F+QLv25SYF+eNAxcGvN/WFfy8TWcf6LJc/\nboDQ4amBllTh8/VZeMkoVY0yqvqcFt2ifl9DgfGuYK1NhXk8F4sg+ekmSpX0\nsTgXKmve7Qd+d8y1TS3APXsGlDVhXfTj5WSloQ4yGD2Zp1nZVqGSfHiUkxm0\nC0Lv\r\n=X6ta\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIElQXmNvqlXC1fJmfpwNk6h4AQwyax+3a/4r6hFApaerAiAht+De1+dJfoxFHDF8gLnOaDhhKFZnJZLUKW67UlidZQ=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-6_1603866455972_0.40218071348247886"},"_hasShrinkwrap":false},"0.0.7-7":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-7","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"870ccb9cfc3820387d0f184b1cf9326616de9323","_id":"@noreajs/oauth-v2-provider-me@0.0.7-7","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-QgmjrFEDfWLWbzdyGZs/tHRkzjQxmBXansmLb6nK+SRZ9/+uNOdwNaMMdl3l6EAyAqUfrc3fTkQ/U9AqxsmBXg==","shasum":"0daa633e47bd50bb2008c1109e23dd05eeafa006","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-7.tgz","fileCount":119,"unpackedSize":360814,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmRO1CRA9TVsSAnZWagAAuGIP/0pt75ml6B9gO4SwwK6B\nkZOfcSeW7uXRa2VzS6yha/PDo/tDEBv84V1jZicq0uZIV+4clU9ey6qCiAZq\nW+FhvRUrQsGhLCNNzuLIf6pNqYYPcVe5RY3ZKh3St7vBoYx06a0c3OmkZ/ob\namexfwrpBFoh4+vcsfTEr7SIzx8qAnH1J6J72BNbdyGR+coH6xvWr6wCDL/D\nh6rPpUsrLybSKky2ECXUSD6mXTZ3PnF4306RL62aZz6HHOxD7rfHZdYNt1DO\nxKR5HvwmQlTsJ8HLPn8HtLJOlW6ZrSSmxnkz8E/PEVD7+RML7WC2dkm7rA5V\nT8KGPFYuP6Obpctnk2MQ/M99rum8TySO16WYgWwJC14a+/kfKaZgjkVpv5dm\n9rqEVUnUOgilJxtflbhOeRaubmQPkRqgSUwOc+RngaBW1LNGYMQRA7na6HDF\nq34wcMllGu444iXJa1G1iVfs/2RSaQI6xXgVy0Nqxdtoosiyxz/TVvmc+y3M\nhXQqn7xwIy6eAPeKoK0PWxMBj1CmjgYI9P5zY1ZyrWmhMIbNZso7OSd5rndw\nkfUKCRI862sjzwAiMJmHEoAJ/uWQWjqePCzp2D7ROYeQXT6OoRfrhkR0f9yR\n9OkgaxxtFn6dk51igbysn2cbfIYNfv5GLzlxLfJkvq5DLPrAO+Oplr/fdglu\naH+o\r\n=xCeV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCds75xsQi5nAHM1h3bbXPsOZg1LP+UGa773Od72ZhSVgIhAPhXXp7N04quYejPO63Jex8gqfIXMKBCCBNQL50M+jy0"}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-7_1603867572758_0.3350035696092033"},"_hasShrinkwrap":false},"0.0.7-8":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-8","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"5348c9dc0b5ec76ae9c0689a5f2a829bc1fba4cc","_id":"@noreajs/oauth-v2-provider-me@0.0.7-8","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-+HGHgW9bfgg3lPOcv3C8OJFpdo6RuGrA5q903oi0b32q/IG9Xaacq6jP0B2fMrDACDEA326aw4u5jbtjKr0wIg==","shasum":"9f862654da879cd6cb3e0c996e5ca4d86d23ac50","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-8.tgz","fileCount":119,"unpackedSize":360819,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmRUtCRA9TVsSAnZWagAAAbkP/3zfGXArJnvrXHhejW55\nlKEQjzCaO7IEYqzO9Ai0bleW1pDTDeUDTbnGw+ZrH5WQoQMF8d54pZ5Y3KqF\nOQ+Xl1fUPWLW3qtaeNcSgOTtQUf20hgvvKP1kaif4iWhkowpNykoM7GGS3Xq\nD0FgsJ0WO99lEqtUP1wn2Xx0J9jHcoVn66g5go/F7O3Kvv62BuKcUmLBrmS7\nD/OPAQlwDAXkv6GBvBzZ1lBtKdTYDrD1S5n8uRBwQrSNzmgxxMiZglnl/IiV\n/N0Bcf06JtDP6tuSgB0kLMzYrjlCYVm8t9QZE/jgvf+HvoekH6UNERy2qKvk\nB4MQ7S4u4wxfCL3Hh+4EixnUyAnNaOmf38WEi5mVWYk7CH+6N+nJH4v4tnmp\n+89WtqHwkvQxqgk0sYbpeYhQnICtV1EQU9Pl8OZqXWo9IBkaIVrIQdguDtYk\nRDfGrKKTVqwLkd0vZtT8mr41IsOEHyv+v4vOzTWBPII74HahUm0W02Pza4kd\ndIKbUhXadXxChRCHj2H7k7Hn6BZax9m/J2l6x0yV9DQWCfy00Tk9AZAPjl7d\njL+hG5UaARWSxeQtRWb44aEktN3rVOVw0e9zpbwKRnnt+a94QLwwgrOgBNwQ\n7JpySWorcSm/C8wm5l9vw52fFwWHOutvxsR9zOXwakE5Gwvwj1GwIWdZl9Hl\nKR6f\r\n=cY6C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEshF72zHIGN/51MtBdMNkiRxtJhkYYAUXVd65/JH4JyAiBY0hREaDpwi34D7gVxU35zC8JikJ7VtpdzLM4UTWnoHg=="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-8_1603867949417_0.07124652811467458"},"_hasShrinkwrap":false},"0.0.7-9":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-9","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"b56f96376e03817284bb1f430a08a577100938bc","_id":"@noreajs/oauth-v2-provider-me@0.0.7-9","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-8vzmSsgCHGp5dp50nts+f5cB8GzSY5eR/r+z4BxUa+IeqlAmrItJdqVbmMxKPBOnfTy4Ufl8/2pmzhphayg30w==","shasum":"caf433644fd157851a2e54b611093f5e6189a406","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-9.tgz","fileCount":119,"unpackedSize":360302,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmRemCRA9TVsSAnZWagAA188P/jNovQUD1geMm0g1FkBg\ngKgn0buxyuQulsHJ2Uypjcx2DSYPn9zmbg7GnRPgoyDTvCQYUsWpCFQtRdlJ\nZPJPcjSs4VZlkcgnru9ge9t0ttcPYgy7VytmySJr/l1jqzS6lBQ9Y7EaCVaG\nxfc4prENUqC6M/g/PBnudWPVh7D5CzMS15OgUx6N8Q4m0UXTq8ADn8JudAqT\ngDJIffcPB0LlkLxpgWm18YaTaJ/TPtpWSBkbyhS8ho6hiqA0V/r/aYc4FBEw\n02mvTUQ98G0R8IlYd2hWC2az2m/Uzj8RTSYMd2U1ZDP2I54O610+5vSUezfB\n4rqM0GXzyvyhwFHRYkyPoX2Kp4g8kjAjZ5KUA6hNIUphcJ0AqX5jbjmnwRX2\n8KDxuYw8Gi1APcaY35irpKr9X2hFmZPjRHmeECJpAuFvn6wPxtiO5yIEi57e\nhckNxwPr8OkVZYuKxU8zywh4plGbhXZQH0u3HmB3DDIuggq6+Y3aIXOanIhW\nXr+BrJDhaQnyq1g5HiKug2RX/QBSaKMZh1ITEx4JQbn4QRO71TYo7fTFg1qo\niflI6Rx9t7KRIsxGaFmfjoevWAtDmxw01wWyYH3DxVAhpoB/Z6vX/YqZgO2F\nhf5BNHRW1nZiFwcgOt6ZwchWH1Mdb/8Pz8P7TzjJDHDy2gvlgva0VCgCKXle\ni5+F\r\n=Lz1Z\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBWko8Us0YPnOa4eq6lusfe7OvhXIB7FWAxeDKCGDEmCAiEA868ZsYTKETwKPViS6Sc1Tg2jqe3zVvCXSlPOEcaVn60="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-9_1603868582107_0.7463341548563136"},"_hasShrinkwrap":false},"0.0.7-10":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.7-10","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"47737aa4a90ffc3d547cfbfa28e99054e0537471","_id":"@noreajs/oauth-v2-provider-me@0.0.7-10","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-N2RQ8046kKbSxTc4Ud8dmGUY/V/NCJkZyhnV4WewxTsz/TMyDKsBvV/7J9P4SLnuYh1u5+RErilskb/ytZuAbw==","shasum":"6818d40019697935afce37c97cbf665463a0e710","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.7-10.tgz","fileCount":119,"unpackedSize":360532,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmRoyCRA9TVsSAnZWagAAj6gQAKJ89QWHslAcoXh3sihS\nlfhEznhsnC2Kbrk8xtf2vyb+LvpXpk0Ap5lllDSfStSnBwPosx/ydXvlcfKB\nhX5jzbMTg2ooItRBgzfbWhpRd30jIprvTdyvjs/DQQ3pI33Uic+jJvCJ21s6\nlahW9kZWIdwxsUfPDUXp2DGTbNwGrPAOPpkd5wsMSmfSG/R9cdjwHBw4W0BN\n7I90o/MhuYP7wA2uGcAXnlsaf1FRHb3TOEzhuFy5SsmRd61pND5G/335DckJ\nhpEUl/FOQV8ky+uhgpzS+9FOnL9aPGztyz2hxyo5aRsUYetme9jm2MpdjXrI\nfWpF776Ef+kYdiF4UwZC4aNnNfGLapH7g5amZwskSyC4PnVDRgWDwKLpjFhB\n4p+bhgmRChUmnAZpJJ56R27c1ODDiRHNFLhUEDthdkvliepw3FZYF1+xYOKu\nwvNlDmMCdWJr5qm2/MbeEv2m8m7zt4+AzQisfaAH3F99JgwFHvBkQ7QbhAuy\nsko0kZ6RshyFXYTS2HKAT2Bmc25KSgLk4yS46Du4KjJ6gBsLDvChG4sptjkQ\nTOuFS2fAacpUcRcpg/MhxjQKKShcWAiaBIkqk5u8LI0GHXA78kwAzveRaDPL\nJ1zxxC+2A6CZGeqBVokNeEmGgoIZqDnspzEMMkxj140nMHUXjf1MvEksVQHD\nDslT\r\n=Fwvs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB37sV1dHjSfn+89ozZrzy21ogYv9rMKslIfOVL5zZ4bAiEA4ZMn7QFmSuT02p+lVcfZBY1r6tqp3kMJcbN+X2HVHlY="}]},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.7-10_1603869234219_0.6565655307317186"},"_hasShrinkwrap":false},"0.0.8-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.8-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.0.18","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"c66742d048d79ad1329b36adfac8839ac6e800c4","_id":"@noreajs/oauth-v2-provider-me@0.0.8-0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-pwJUAYLm45mCSJnMILThBQ78ffg//pkZsfSkWRsI6lpXK7UKjoNXfHzBb1p4nV5w/BhnormTmE8CKwh9EqF8Ew==","shasum":"982abe168fba9bb3101e701afb1612ee41720e81","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.8-0.tgz","fileCount":119,"unpackedSize":360445,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoo3cCRA9TVsSAnZWagAAARQQAI8e0NWkDffb/fX7G4X7\nDeYvfulG//hoeOAGO9Ud6WAUiBI3tpPbbBMXhePmFF6R/MGr2teD/kzux/hV\nqlp+QeILw4vxkssDVzjv3pzKN2ugBvjGOePoukOo1HPHGUsw/aGUZh+1byYa\n8CCQH23FP3qWOKvkNeFLThAKg75OiTpeP+yNAXmZq7Vpr+kQAxAtxgggjBZF\nMVP05Hh47SzP0M4kNJSKFF4BCgPBSMu++T5Ts0j2jlqkTiPSZvw7++X9+E4T\ngPSiUZxdH1XiWrug+ogQgpHQkVE9dBq5tf08tRenbS67lFwRSijWHdK2SZ1Z\nLZ42I4Rfzbo41mDOnSlI+B31hnGqd/CkdEg/m+CPKnONjangEtdPxkG0Xyaq\nUJfFNzZ4Jc1Np+2FqrCPJ2tLJYFjZRFBTTaehWrP2uQlyTvzugK6ozGqieyg\nzJjIIZ/sUl3b7D5ww1YZFgLbE0MkE7XfyPZRnyvdf1TVKps5Ey8eMrOOhVzc\nLKXVCn6fJEN2rt++ibDalQNHCqgFMVAr9/ND8lgKQhtB/hWo5k1t91U0oQwj\ngN0qqI0aAZeaxkjxlAzzrFuKGuUAaAocaDkRsPwuP4+sD7PUSP9V5F4ugK5j\nPWQ4GOmg79AXg0GL5Q4BXmqJ4V3sAiA3w/T0urXFkKTWQULHK6OD9kzE2wXD\nwqRP\r\n=0w+O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+ZQmNGTdPgjHlUbP3fCv1FnnEhho+hOFsHQbNFmIjNgIgYvKRs4OsMBbGDsuKGJdxkzM9MILWBSTLYaL8HLj4gsM="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.8-0_1604488667650_0.5223545924532786"},"_hasShrinkwrap":false},"0.0.8-1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.8-1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.0.3","@noreajs/mongoose":"0.1.0-1","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"893da0a9843b3663cdcc7686a5ff17675932f197","_id":"@noreajs/oauth-v2-provider-me@0.0.8-1","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-0keqIMx6aMmT90QYLKGrgsMX/BLNy7GEI71QMryIng+ePzy7fOk88OKugnc/BAE2BpNEc+YJ1ILkVVuy+jgPNQ==","shasum":"afda538c676835453e9c2245d905138dded3149c","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.8-1.tgz","fileCount":119,"unpackedSize":360458,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoqyJCRA9TVsSAnZWagAA+DoQAIcDdxTBqCGahysvHwtO\na/apntB+ftTxNwutcBrl9Wf1WX+k4nw76obkmq2OAJ5KSqAbjczsdx2PqkAH\ngeFTIRmSn1MTQs0L+/GQ4ynjDUzJ6owWbqjLOtk3bkrvecRlKh7w7ahmTUM9\nAaUIK9zb/+mD18QI9UPJfCD6GWEWS59Yy2yizZ9g/19TVI4PUvopshqzbesh\nDyEXZaGC5gCrMBxisNYy3f9ci+oWcCht5bcSBr1afwG8RIa5EeeaLTo9EBQm\nd/TDPCMmreIeRsd5jGQ6V9pKKOLB2Aih9cRInl/Wz+mGdFKVjKD3460o1ZRn\n1umzzEFqniJ3Yqn5+J93tcNanDXc6f8+rRaRJh14AzPBNSFQkWBuLVlj4W4a\n8O1JbZDqfQQKgmilOByiBJ0T1RjafzfqFyOGMWSCSFnva8GRhJIXTsAIjMTi\nY1JjVpSYFTK8zR5KzGirx1/9807Vb9SdwHR7VJriboB7kVDUwPSNJaWkSNi2\n/qXx5a/Zjs62HyCreydkuB0KQGKmoWCeyu/VZDn/q/QzN/e2WNM+Brsh1xY/\nbaXr5mxuDdh7VgcnhEzAqZu1ccA+mVGaup7iNomq+fiOPFgJ2Lb6HG/M2XC1\njNhccHorK9NOsKwgZTDoOqKKK0GxbVY2gsLCKKPMQW3CSClO09+U0KeUx9sr\n27hP\r\n=i1wZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFMr7isgpGpgdqz76gLiqzGt+Nc38XxWUgZa/Hd2NpBqAiEAyhJO9SsTEylqVERNWxyUPW5S4iu1Skk7r9ve6xTpBlo="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.8-1_1604496520808_0.5076671017450947"},"_hasShrinkwrap":false},"0.0.8":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.8","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.2","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"4abe93a50717f11a919cf932c59a84b097cba34d","_id":"@noreajs/oauth-v2-provider-me@0.0.8","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-5e3aPiEKQaqGTbI0MItKtlVpk0L0Yf7KFKHncLQRNczXYxDTayTYP49zO4NUAN3BCyN3lceeyFyB+k9LL3mStA==","shasum":"ef5fc1f3dd9f8266fb3e88add0b86adc08678717","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.8.tgz","fileCount":119,"unpackedSize":360455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfuoDSCRA9TVsSAnZWagAANdIQAIek77ch0vAVLoAMUmNI\nlmELNHex5GqaHozOq7Qs7UOfNxmrH67ZjRPdWzNCwenuXIixF1F6gjzx7g/i\nUpNzITcUXI3XMwmJWn172EckNghOnaPw5miHwFcgRcqn5TB8ZfsxNeuQlZfG\nrRiLjeWEOgy4D7jtj+6Ax/aVCHi09kFhC6+fyaQpsyFOyc4h3Q1lpeIsSzn9\nIH5RRDPpSJfojLARkj4dOPMSVCNPywC/61WWldf0POfR3tOf1TH67VGReVI5\nJQpyMBOlqGU0YxuOkOwO1iF0r8RYEleNO2/281RecaocWuizU0qUH5RFE3gJ\nGBN7ZqIJ3FN9De5KFGhcbi9FCB/s9gmRWKBo2pRoWa+IPqLPnNbpvym2vHV9\ngWM7RgbEFKwCQHFGnXSRQ4a4jnX/Fkcj4NPD19OZr0p3aslppR9/g4lF+WqQ\nORdT8g+ao01P1qz0aLdRJUnDCJJGA71Vt6RKbRJ1fTpEiJoqv6VmB9w/M1cH\ntjOLptKBPrVuBohb3f4DppQMFcSLTPgPB1n2qSNZJfhs0kyKkfm7FkZXbxnz\nRshkeYB+qWs3OqrTqciUis36rMgWsA2IN9PxovhcBBgC6obJJOaG5vT57iXQ\nWdmkffe7VPNT/XK7xJI6GuBdmWy24uWbyEZ7OeDAcv0Tga5SfE31h97smN75\nK0fW\r\n=JZBU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCL3fhUkzwjtElktp4ZZGvHYutsgaDF+pwfr8DDkTCDugIhAJCbISRF7lYPgAV/jXjcahAMNbc7vkVe81DeSc7wAnIt"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.8_1606058193418_0.6343326289127793"},"_hasShrinkwrap":false},"0.0.9":{"name":"@noreajs/oauth-v2-provider-me","version":"0.0.9","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.4","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"ce8ca418d330fa7496a28435515b634506aa36ef","_id":"@noreajs/oauth-v2-provider-me@0.0.9","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-L/y9LCRQd+YsMDVfYHidYyaIw7sdJKbPyExo7/PEWrOs12262i3dZkw1QoBuSVOC+fQ45z28ioFl3xF91N8Cww==","shasum":"254b57ac2b3150513be108a3dcb4781b045ac5c3","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.0.9.tgz","fileCount":119,"unpackedSize":360455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxLt7CRA9TVsSAnZWagAA9IYP/RTUZgzKbcbCRyo5Vt04\nupOAF7LPPltrUfbNOnWJRRMQkwqxzLx8cxuXTZCgOeobvXdkCblUpAAuaVoh\n6sGgI6fT9Ra9YuDxePR2ef31h9tL0wAKvdV4q+VesQW029uibeK7w1rr3CBu\nufkipS4JQGNtVO755/Ua7N3D5gwwtc1tAEvJPWbj5TqLj9MEqe8Og64fJVuv\nvJcO29qG4dtdeT8ZM7n+kzwQGXd3+d6bZrO2pU02kFTIPdqgh1i7TY0fkiXw\nSq3AZWedTs3HDM3Moa3jJ4f9FFbXJlqS2vtX56VAml7ii9QFMh+XFDUcVTyn\n1TeInRKjtzYbuGLv0CBt/zLYv2qv5DVEOzyzv1hj9GkGM1f9d0qOHJKNVETR\nLobpRtA8mo84mnQzSsS86G8B5ZUvreXJPSYoQ1jP/8AHKz0Wb06v4z3ECQpm\nDByGXv4tFRW9BKnnsQMNJzBa28fpOze8LrGY87X58H0ATgSdWhUiTJun5EyN\n6GeREThyARfTjF35Fgr/bwFK/Powfu40MZ43Fkg0JnNnj0KSpqsGpwwig40F\nP+kzAE/N5E51xGyk43xRUq9jR+4ERUIgy6o8YWQQlH4TTkmILaXZhM2pjnao\nyUU8zSCSnVpOESg0ofvlo0dMsGeuhQampmqlnmfjqr4w6jNiV2mlf6N2Cj07\nbD4I\r\n=Pfzb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCIBDwaLD5YbaRFmh8GARM/KRQwo9EqQR9pO/la8muUTZdAh9cRvxUGwJiPFY7rqjlqBHO0EtdL79XuvVDaYknPhNA"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.0.9_1606728570899_0.8514418152839109"},"_hasShrinkwrap":false},"0.1.0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"e54003224dc602174ea7b57fae041fda2d97fba0","_id":"@noreajs/oauth-v2-provider-me@0.1.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-qYpgaYZKjilQvXvQ7hVMXz3HbIGsTv9xmxRWjGDH47U8vY0K9+ecL/DWXHqrBLKRjObCD7WNswGuznfC1xqhZA==","shasum":"2f8fece8df1615b871cd5818cafb9b1131f92376","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.0.tgz","fileCount":119,"unpackedSize":360455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxMoXCRA9TVsSAnZWagAAi1MP/3pNliVL4yNEtFrSfsL6\n5NPdoinAxFAIy8BfjGQFKH13NBCkvTYUQrsFpIEzSHXlUmVGQ+SxB8HOt5L/\n6IpSijWgrysKLkAxQb5QTQlE/gokQc5mSSlo7Rr1WZFBgl8TuDbuQ8yR4tv2\nsvMwJ6Su+0VeFy5/A2oi7PMWA+wLXXobyrpzaqXyNt9wGAtgFhX22un+9F2d\nUtc3StmVF/9078EvoQpielE7ZL//5FylVRMqgxsDnSCmiQjKVSiyVLBdhqkp\nc4sAusuYEwAVcIuxcirvIesxHa1deX6+/IM0DKXJ6Y8TIctInOTTkAF15FTN\ndTRbEz4XpBhRyJRpCEtpQJUL6+iFz5AJsxfDCJVjT4ZUE4/yvvcqeDgbwi7x\nNeN4MiqOdHeOvZj1hwLnXP7sHFRbV+gmFI1l7fsO6sb2EMeIDlHWMQw0NLQQ\na2+oNz4+PeoRFtI6YJIasNfY66LhW1FBZcIPy2wEzA+igWO0dglHGeGDZV/Q\nr6EziJzDVyuOpwahQoqhoFBjDTtFWJb+30oimAbpXtoGM9Ld6/gt1Ds9Qjr5\nl9S0UckhWn6c9xJ9sHHQ0zNGkttyu9Y0CktEzKPFbnnm9Gnrihr6PsQshzVf\nXwARYnfd8Z3WGvHY4LrP6arlbHs3dJRHF7Kkck08+yesuu6RLYx3OvktIfeZ\n9w30\r\n=V4cS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFhDybe8vijEOEPI3Qi63JFD2rhboc41UtJVOIelmkWcAiBc3Ztuop3/adj/wdtuQIGRSj+j6qIhWTNMWw3EgFheLQ=="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.0_1606732310558_0.4961656832757464"},"_hasShrinkwrap":false},"0.1.1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"a8e5d9d81abe5f058bc60fea3bd66ccd3d095596","_id":"@noreajs/oauth-v2-provider-me@0.1.1","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-BcpsiNhuaroRjyqpWTB5OfGj+qkRRz8r63PBRpAbzF5KUcyZMphRDLrfo9m3Dhth8vcMnPxmufBEOUaAe9N10g==","shasum":"df6f23890b6e9acae80fd5c95dc348490d36a290","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.1.tgz","fileCount":119,"unpackedSize":360405,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzg7mCRA9TVsSAnZWagAA/YYP/1S36pGRYx3pRpS5zW40\nNX/7UbD7TSvmlc5aFBWxnGru+SQQ3rd3cSuvxq8Ih4oDSc/aFDw8ZPYikLhO\nyV4BUg+YrDJZgTAkEDZzOFm0oZOJ7rG6P/L7z+qpu7RhpUHfuUQmatFrWaQr\nPdVHl74auvKcj0DtYTpEN+JhELC3DSaa1XB8jOdglhGmFD4HZUizoenSBZNe\nXvrPWCuI5dcnw5RJFq2Llw8f3VS97Vf9l+BMrBBT/fq1z4GEXfrz1faDYcFq\njSjHS8aet0B9siXCnmeRHcjvf3KsEGDodyr01/dOnN7FxdRSbMCPY57Qhl+s\nNg5tMmGena8vWHmY46308+baUxng3fa+6A4dyU8JZcLz7GyUsH2qF5Fxt7M6\nixgfISuhA3xsQEuS98VOvDH7EcLE3qZTnnPD+nWmItWHwWDK9IhLUj70lEXj\nm4hpPNSi7ileHmwFNcalOUSFh+62jf4Bx1gqPsLwDw+ck1Zsj2uzuwRNS7sG\noQ53UXv8pXdSdC83aIyc4kv4raT+GMcOV42nbAr76Qr6Dy85Xx6NFPcqtzYl\ndWZOudE5NpQu7/Hc4Uc3yHk2n3Tn4BAx/Unc/eCf2gs7flgsC5wwbaNleU7n\na/4qQMdpdLP5IBOruAx/15SnjTnW4lbbdh0TW+UoxGmkeFc3SXljac6BmZaH\npndE\r\n=VWBk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHoZf+wxC6fTkcGXBLdMOLrUc8x6B98m0yJrxoY1YySwIhAKaWJ+mWQNTFuRtJM3P5mIQLEnwcRzGtgLCeQF+9tV98"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.1_1607339749721_0.06135608096783951"},"_hasShrinkwrap":false},"0.1.2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"456ef8be53e529ffc2ef22437dc73fe0e0bdc8dc","_id":"@noreajs/oauth-v2-provider-me@0.1.2","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-AAavtR0Jzl06Am5vK5xAzRNmdDe7cd29gLPgUGxoTYH2ahMUkVSJ/qg3mx4F81nygD5K6v0qVX8xD+8qLuqjjA==","shasum":"f21b24fab04b5feebfb5983574a9d2366a8c51c5","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.2.tgz","fileCount":119,"unpackedSize":361269,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfziy3CRA9TVsSAnZWagAA00QP/2fwqWnO98gCg1YedNEJ\nY/H3d5KNh6Cu9u0+X689zaxFEI6858yxVxY9Mztc8Iant/QlP9hDl7hu+FZv\nnuJkmJE9YsRAqQJP9Kr4J/4nouMvoc2bQ0SZA/wtxxKlBXzXiRhyblu+OW5s\nx7JSNQI1kto/oFKFa5oWksCsKvAToaLVBEOuL10rajwAlFaUr0r1En2/O0wf\nK53CqVsOKRHiUpeNlVFy9PanCjy1ZtPmRt16IVOOV5SoWSMJ42oyC6ybqeCZ\nzST/XrCQMYML6dGT4Bj3FnuvTwYZUwc33VURv3YwEFEM0APecqxICp2Rf6SI\nLDuiVPkLQGFL5yngO/z4iq93P+goHBDBuXQAoxkTu2j68b88OwpCcIoMf7rC\nmzcRuSWe4/fOYxXOJBYy5iBmHv7HjJRt1Hy16szaj6V0vHuFlAmtEkbM7eBJ\nTf9vfWov5ccwEf/CofrX18U5h1nQrerG9Gw6plNvizJsYa6lllWczjySfr9c\np/JRs6aSihGGNR1tsr1Q1unIFKMSTFUaZCkKgY88qwUn64dUE0AZqlP8IEHW\nbnXwfdkFxtuEwKurBQoeL06SJENcbdevphbsiBA2Ozw4EinxWdiwiWckEzJ5\nvrVwyBVA39/OvqZU2WbO6mfg41GNmekhUh7kK9Y6UfVN/lgpPT1bhGy3FIFF\niBgu\r\n=hTYD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGaYPydGxAm8P97x5ctS25OIT4VT/KyRKRfcMlX8K4HqAiEAhgWsPOXUUGYDFzp1rFK7CsFdhwarA6E2gTtcjYtBN3c="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.2_1607347382963_0.8341868089505444"},"_hasShrinkwrap":false},"0.1.3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"bdcdf0c8564f18050fe00788d2e6db1811b63c03","_id":"@noreajs/oauth-v2-provider-me@0.1.3","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-aNcD8zOQCGCm9H3Eiq0jh2uePZm9gn5iksGaJV9/p+Z5ksbyr4D3/UsKZtvbDamgXQpBEaoZ3Yq0nUTnZurFOw==","shasum":"0fe9f9fe9527a7ef796c2ad65e95cda41c4618d6","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.3.tgz","fileCount":119,"unpackedSize":362044,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzjZXCRA9TVsSAnZWagAAh9IP/iwxoFtNnwXJgEurlkoZ\n5zjFE937uWcLrwRqsVkapUTKk3aGWA0LL+zzziVuX06fsVe5JwNJKG5Ws3pA\nOKGvYNmlyVUo/xdq+cUsbdNjdU4U+L1D9g1DbGucp3aaBMu3hfZrfvAofdlI\n6WrqAaQ/LyFgVJyE5+JU49QPbN79Cua+fIgaZNtKCx3Q4S8xYoppMJsY8FdO\nIualW8yURr6gf1EskfrCZl89RZ8t6aJzWNw6YkwbjIKwSfl6MsSl7chhB8AJ\nzICa7Oy8Fcn2JJrXXIANJPYbMxRZDysFivcxXUgjZmC8/oLI9NiQzWYPpGTU\nIipb5sXplgf0ggcoNtOXVVy2rUlf3MrP4/iT4J2EMeu8dxWlxpp8uVtUWxr7\npipSduK5A5LWVGLz8Sbjm0VHGFRqw0F7kz0YLAzzPZoBnIp2XlO+JwX4E9rh\nv4AaquWX89jTm8xtmGf1zCsHAyLT1OKauMOfz92iz0lQVrGHFDYhzsH+u+6h\nJvit5+A7DLoI9mANrGePpxFxXaxd+MR+3Pp5X0EeDuDtA2WOAeyUUWdYTn1f\nqCMffYuN5B+eQaiKOgvJjVXqTSQPDsWFnMebEzXViaBf4jKz5lZhCB4eNMbJ\n7cuMyKElGhVP0olT4MZOqQBuNdParaYWrk12iaEtH/XJkwb1eXuhitDvEHRe\nvEP6\r\n=OOYS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChoMHvGY1zqPP+mNhPbqvQcwFYsKBWK9yvRpbRX59SRQIgXQie99NQnqiQu+lXilwF9e52qlrr9JzAGtoHheYjLAM="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.3_1607349847390_0.9952242142542336"},"_hasShrinkwrap":false},"0.1.4":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.4","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"77105354d2a7695327ce74126dabc97496913109","_id":"@noreajs/oauth-v2-provider-me@0.1.4","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-Jke4Pnqf205+ixKCeev4GzRpSXAAdwxjWpMXz/kMFBpKa6k2TibHytGX32g1rvMxdl841LZYKnZmTFcw/z32nw==","shasum":"39beead8a13ff536899c5aba2954b0b72c818390","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.4.tgz","fileCount":119,"unpackedSize":362019,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzjoJCRA9TVsSAnZWagAA9f4QAIBd2r08zJ7FldCkJTlP\nMNW8yYttVtnOCM1tigtwTaIPy/KUh3OWEzlBs5lx9kQae0G2V+JF/RL+l3C7\nyQ5Ohg/61xKb7P0n7N8X8pIz5BI3AYUjHvP01FbP5fj7MfgLu8GqVkKtOhgn\nRfrjWi1aOOc9XqzVmv/UlTquVvN9A0I6KlpheMYSPv41libuv0ny1kYMYOT+\nlPplr92tjfzx1cafSK39yNqsk4ot43aiqRviQjnN4X850H7ZFDTSlQtpJLHB\nqrHcm8cOR8SnrE8TdbIwYhEfomrA5D0q//iDCeOldg/OMRXrnyZgDUV3CMzi\nq7Cuhdjl2pgF1OjbpzAO11FYXpbJJD8aOcdYNSY+7U+nk525PKGpXj7T2k/3\nFOM8JMLF7M2tuoFyrSqt7zcGQ2af8rOZ5C6FTc9Kph1ZxbSYcF/hKssA5AAB\nXNEtTzGsv8sM7Vr3iZTAWXTSGl7BXCUakghL1OpePL83Gl9DyhzbkJSmstbp\nNbom3lkf5PzvebhSIPnoRJurpQVcm910LEiYgQ+xOhmum//X4X1lajRQMo1q\nSjlJ0BEiW9kBv7ZDDv/2+JWEUYObDQhpNhN3CYGaNta7UBrVItj33jfS3n+4\n5EyDWX4nEaAlNw9RxcdOYsgCbLM8kodX7LeRftwoX52+x9qXfqnl7HGWwmUA\n0f7w\r\n=FD6o\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQ9+8It77POOze9NIrygwAqZjdbU6FXBoowLC8czuJZAIhAJaP+rTHrYUblO6zHMipw4b3X7LlGJFeOtFrKcl/AG5t"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.4_1607350792503_0.8423308015018149"},"_hasShrinkwrap":false},"0.1.5":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.5","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"8c729eaa2a8727110120f78c21c6a8123a071315","_id":"@noreajs/oauth-v2-provider-me@0.1.5","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ZJ5Qs/elWzlie8a6n0u0LIZoqBe+oU4r09HTWJ+eHjLXlyeFnQF1H/a+SyBofU8ROHkB+vo6ByAgyK/zvKknwA==","shasum":"f6de71d0df253423b17b7c7e1ece7bf03eb26a18","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.5.tgz","fileCount":118,"unpackedSize":358671,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzkCXCRA9TVsSAnZWagAAPjgQAIVH7cZNCjT0riTUaSS6\nZO7SedwB/FcoW12uNWY4l7EcRBHf1hrzcBawd0Eo1VBFVHkAWmS9uJiLyRMf\nndnznRzIWLwWNdR9Mk9ML+ezeZ0LT94zun89VjxAoDWJpx6CZ2C/JoDV4kOL\nEJB+6SVghmvJvaVOieTi2MBBkQNFwQfIfGfVDh3iMX+KRYpgoQ+hqd7gPDa4\n4/HPKcBI9awe1bfnKz/zen6XWvWqxWVNk6wCbOvqG1QFeqwa9ZVCPwo56095\nV7pb0DTr4GcMP48YNvQ9d05kp6pbe+MP9gmLgbqhIk6sQ1xjPr/KyKFTQMSG\noNjaKZ2a0+NoOVquPd6QEvft0qpldt4aub84CkuHeuB0x0JtpNlgSY1Zm2Me\n2ghprX+eEqfqTQ+eralNP+sLfEUCZS82Mb4Vx8h2T5hBhDnXuvo955xD1uLd\nX/kMA26Eze2FcV8MEYZTMHKPwL8Fh3HUnH93glVNjnBlxNEKjkBIvBZX78wy\nVJM4UuqymBw/73sbM1jUhr4u/YubNlmafGjgAEydDyJHhOOplzOJuDSZm1/+\nXaC4OxwuhjRp4m84C3xteJGAj5sq83mpbdcSwE9NsuFl8rMGuXFCPJ4KPPds\nnlZzP6tUvdnvg+uF83qN5urnSiybEVEisyIwfIjCTd2x4W5ofnfkmVSAmPhT\nahST\r\n=lO6t\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGjXbDgXj7tasKILMHczRJZ35IiTHgJ34SFFpeVmIm6WAiEA280nWxTBov/ea8+kVGeMeDVHaFXDlPtFDltEQDpHFaI="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.5_1607352470549_0.6178450529287807"},"_hasShrinkwrap":false},"0.1.6":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.6","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"ce609af0a1c442acb09b5d49deb4323d3a930d35","_id":"@noreajs/oauth-v2-provider-me@0.1.6","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-OBlOrwh56JCM4GQokYmLreUK5r0JryNCqpVOsVID4x7E4FDbs2a9hweNtuF6GCpBRBxh/vdiKaellFxMo24fuA==","shasum":"7d45eb3caaf8d7a860571d8d658b3f1d5c1f89ef","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.6.tgz","fileCount":118,"unpackedSize":358603,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzkWoCRA9TVsSAnZWagAAxd4P/j3e+bPJJ6H9WhDhCxpp\n7T97FYosGHkWvp0AU2CocVREqMOsk/Ls3v6PAon6BaVVGVpBC7Nru7J8tJLH\nD8H7uC9OPgHnypp27A45xSkfX1vlyzFH8P9/KLqdT1NWurtZkz1aeJe0PLsX\ntkvMqzE+aItxB3aW9tUpAoJ3MkgQnEyeaEef0yAOiYgjQkxBzh4na9nMCV0w\ntNXNTK39da2Msusvo9SUMc6FTaZhxsEBpgnggdHU8L0SmJVi++EIiPA5I6Qf\nyjJAfVXMatzfme6jIaS0IHNVEh6lwmPS+ZULYsC74tUZb6BO0bdXiEWOSoAD\nXo13onV8ZDW9fM12Tli+70vOFQ1OvToQfLxX6nXG24WJ8LyvE2ESKeK/azDi\ndgtTkmp0KPhB80UsstOJ6v8PQgHpQgeLC9i0UDKmebsGPzLg20X3PpkGupca\nNGIUAwjaa4d3fy0LUZ1v7G2gbvhSStIPJLpeqVujDTuNxBc4jJExUYJARdkB\n2MFvtKrbcWbi6uO3P7HydX+oheAOhbjnp5Ak+dRc3+pOXtxvhrNtlvoQk0UH\nObIr85yz/oxUNDcDzES69Bt6MTPhsIeZZl5Y/22EF+SQIOjOmz0DpnE5LUaI\n2GCNkFYYtrny/TooHaqRktys+wM7eAx1yq/FSbLSg26+yPyEuLFkNo/emvKP\nEDDL\r\n=xatO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG/DXSPMhPyqd/2o3th2hE9PcEHRH1WN8u+qgNR5ryjRAiEAvvKh2rKSXkjpzFWtRAq2q9uB7VTYkH42qo+soI3rt+U="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.6_1607353767789_0.5953229102641155"},"_hasShrinkwrap":false},"0.1.7":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.7","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"1570fc1d0b9d7e8f40ccb60c4a4fe2a1c3107067","_id":"@noreajs/oauth-v2-provider-me@0.1.7","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-qveSI0w17jx5Yz0l52gxRYNg9BDlssjyIzJLnN5Lm/zGGIlc001NtlMr3JSeA17o6gVOmX0b7qR1us2EbQAZng==","shasum":"0405a38bd7cda962de81670c709c75462fea434c","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.7.tgz","fileCount":118,"unpackedSize":358914,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzkcXCRA9TVsSAnZWagAAhMsP/0l1ob0Uax3+dxruyEe3\n9zMl6+iPqlXteC3XBBfewbjRtSjdqkS1ydH3WQPr+xh3kd6SSmuJLbum+Bh0\nK5gyJf6fch5NgNboj6fxNJVYHs63BR24w0UV4asOiYtieVd9cRlCKRPR4q0c\nn/vMmwa3HdyMh0Ke/hdK5iTHmNnMVOWEBNGE/KiBKGJ5DmMSNN7NIVwkWwFa\nv8C9q5tz1rB9E2Y4eqA7MYSOIVDe4xZJjNRm7jZ8AOjWqbZuksM4NSzqK0Hb\nbDRxjsam+KfikkqhL7QYR16X5SxHkmwHKnpj8FKgvSA0cIzGCkn0Z97B5wgE\nNsEIhhzoKVV9KhyIRkM6h6OD6boTZaX3r4EL6dDXV8CzhrDTZ/hQhHdBusXS\njEVH/mC7V89qc4O+ucrw55AuRX5KYfUE68KEyn5PINAqiKrtke0u5vRLLkPk\noxR6FVmmpNxK+5ZY5DpIGfkSuJ1XAUSD8ixoqoMnDsbvrDLUuEr7zn7YWoxi\n77rK9AFuW60M4NKdzEdtD9gFKDARkvQfwtTEHGGcp79nTGfaYqsr2IAhQpxH\nZfw0Qjn699JX+XfBdAo+ecEzs0jHQgWLR4j2yDACmnDnfLjVTqqnmm3W/Vqy\nsdQL5lzr3RfLhTNdomiQ2m8esTXdrz1Ih+hEAyAL2wRj52xGJ269kFXy7I4s\nErxM\r\n=yrNc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCN0Gj9OjNrmDNaTFjT5I59zXGcQf0l09zJ9Tdg/HQodAIgAVLgGppO+3rhaPYAQJKJ7SKxxLzFidVTjSxI7JEFvXs="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.7_1607354127474_0.45339608996831227"},"_hasShrinkwrap":false},"0.1.8":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.8","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"2f3b3134ebe586e1832f63162b558e0d28d3f465","_id":"@noreajs/oauth-v2-provider-me@0.1.8","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-gz1G/TtnzzgussRlNt6ULCz4coBmxrzg32mcXp5xwwYoQpTEqSsXwP1YFlZJ5yWgooZsjEpgGLX7FoeR9l1qRQ==","shasum":"850f9715eae9e77eca265c984421088eb59b9941","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.8.tgz","fileCount":118,"unpackedSize":358898,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzlOtCRA9TVsSAnZWagAAdF8P/i8+g/3dS7xlfUTTJGxZ\nkDIXCVl3qXavrIJVVxkfuiZAef8jvY0qSNLgUnpVi/CD1pkjulJy2m1mk8+J\ndqAeejfVZM7nJ/M42WR0rAY4WXK7v5lmRA+JqrZ23H2N/gG258bBfcvBujOl\n0yKB6osFB88bTlH1ua2OZL8Ji/UuriecO/iCSAh2kW/59eiK/3/HO6jlHDHd\nOCdGg6RKrgbieXEgr9j6suqUeEV+j55qe6XrzGVuGGx7lCRKmQF3FieL5pxl\nV/Z6y4/5jwSwdAqM/nNW6WMDMJ2Y+DBPF+OOR9gYn9wS3XWVvCl/FAU6li/i\nNJvqTMymSN6d9qyhIE3y3KWvlUsbxlnS1gB7qJ1yaY3hkmbWuAKaP/Wyo5rp\nb5r26rNcvxA9YcekQxzSSRrL6bJZllo3OXJfllhlonv2KuBUTXWZu9+cH9xJ\nUT2NBOtsx/MFzpkSZ8RFMxn7cNKTgee1pJ3732rMi8QmJXLVTlRKHwFpYrkT\nLF30pWf8ictX9FOIenmCESjmJ9lgzAZ/9eJ5HDow7C4z9bQD3kfVcQYlvc0f\nUIBTszd+BjH24coOgkjLmdB0kt54XnE0EZ/mYApHrT1K8iAOXzzp7SUX9Z4z\nsWmq2juw1H0BVnrYwG17su5SW6Ctfu6iDcuMltcalnYB0DQUAErjxxGwPF3p\nAe8d\r\n=NdqC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCw9Gtgz5yYUVQrLVLjSRZshwYX17IbukzI4AES0LNVuwIgZ/xm74vl6/m0TBic6MN3Ig3NZISss5St/z3bt09vf6c="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.8_1607357356932_0.451887494393842"},"_hasShrinkwrap":false},"0.1.9":{"name":"@noreajs/oauth-v2-provider-me","version":"0.1.9","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"d6dabb936da23f0ae4df11859de5bcaf8e25bf97","_id":"@noreajs/oauth-v2-provider-me@0.1.9","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-B/ImJHWzCKkf8ctmhrucy0LLasoKng5GTJM1CAkeAPJjwkGyRW9OG9mzQEzKwxoHoHXvCjS1p+fJsITOTiJ3ug==","shasum":"30449a2b75c37b5fd48865738f9d5a9a1cb7ee81","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.1.9.tgz","fileCount":118,"unpackedSize":358477,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzljJCRA9TVsSAnZWagAA0VgQAIHP6tfEe7cJruAX7ORc\nMW7pgeFRNSdlCtVMwBT3JKuE1JyN0tUjyb3WakmHHednSGfZX/AMr1ZdH+d7\ny5vUV+Jnu3JiIwLXICxl1pkPKua9l7z9mMMxr3b3Ep7/cL6HsFYrZ0+AAH1S\nw5N1WYwsjOcsHRlfSUa+XAM0GTtFmMYp3KScN/fUb3gTW2thpLlIF4ikSKdE\nKL1ZIjzn+is+op1GyOftSZEV71ltGY+xCZGYGTyaSfqqtD0BDMR1YYl6RtrI\nhTMDYermOEhJfU4uIo7q2SXH6rQBW91X/hTj95vhvukwnhWw4DnboJEYaNS/\n0dz4uum1CQGkdMoGjNM41eRuhHgNrJuDDtUTa0E03cNK35avbyQuNTNiWuK/\nnmSzyBbdtIopZgDufuAIXQNdpQYOtOkzR8YmnImMJObRQrJMEI6l2kQ4QpHF\n1KpemmNxpKr6QeYsvHzpIMZ5fkUUch8WWjBz1tD9xQVnQNcbuaMkF1kbhpbn\nlAdIEalLLRSAaTK6sWrgZIcXPSINcoN/QW32J2x+1ZxImaPdcu1MKs832Guu\nVni9G9AJG4asY1/QkC6PoLksTzPsCmpYuiMfzgCJlSS5tAPlUuwenR+GscVF\ntWqhMelVkf0+A2BWeq4gn4hDDgz+IVnYsKtP97/O/nGNr0H4hduFO6uAq8un\naOdP\r\n=/Goi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIClLpywXqL03gtSyu0jcXSIk7gaYGn3/uNaHBeB6ADqTAiEA+PhzD90jNEVM6BuLi83kPyVF1MmCJwZK5y+2qDFGtZI="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.1.9_1607358664852_0.3945653675309484"},"_hasShrinkwrap":false},"0.2.0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"4de20870230f9fe0c0cec987e5635e7b02b16567","_id":"@noreajs/oauth-v2-provider-me@0.2.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-lqQupl+jdU3ZlbWjSgfqBvN5xa7/0gpBdaKoC3D1jtpYJs6qLzVowncresePUr4hrvwGPKd8iB6sqgKyW/D6wA==","shasum":"68282a111977c4205a29e01b9b329488e7748b7d","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.0.tgz","fileCount":118,"unpackedSize":358034,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzl6jCRA9TVsSAnZWagAABC0P/3A+/NTzW0Agliw+LLmK\n3mO7zgJEcbcvherK0MyDoHlx1i8aH7uKckcMnLcIf8O71wEf2m3RexQu47kk\nnIL2mreCVWPuUunKXM1jLRFMxp/N/UBB6EumIpkE0CtSQyN8DX1pWt46GVYX\n1btruzezeTlr8k3vt0zLnbLMZT66CjAe6Aq/zTNeyImWG50HOt7jYdtBBZAe\nMSpbBY1GgyfEz1K0q4GNPTtiDgz/h1wJHgUtukjWWi+pqnKoNM1hSEsLEaN2\n+ES2rLg2AO0+gBHlLyRJGX0Ya1KYEp9DEkdKml0tvZLosrrSsIKwdpRF46mE\nmNpu4+wXFivSAoEWL4ixTCcbEJx7ua6t4Y0GTVkhisZA3mtMMRHhFkIEZDV1\nKM3Gx7fKI0+F6pSmY11HFXNiZD+TLUbq5SxXdU2VZoIuil5+saZpC9/SHhIY\nMBJ5n7AmNcbq8rqKsohRIClFnx9JkdJ+cohOKXqKkcvFw3cXS9PV5WGV/3nu\nXGtGFxpcvKaXq4odejACxXXXsi963c3nuBn6dg3mlUcg7KSgFU4moaFeqnZ3\ns43D3MRzz28TYO4LxmX6Qwm/64Ae8oBWAnLbCmH8c/4z2YTW1b9NfpgV+Izl\nav5qqN14CSkS7p1SfOdwb97mYvWBLs4vNavbhYjJsxRT/Ck6Ld+ZwHxJ+xjw\nGpQj\r\n=cgqa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDD2VQeKustF/Y/3X/nXL4uIDZ9LFBIIv4/R/LDjYPuDQIgXm1tfTkDhRZWYjrONQYtBg5R4B0WYwfHSc+s0T9aVi4="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.0_1607360163030_0.3763635927679634"},"_hasShrinkwrap":false},"0.2.1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"eccab31a1f85715bd600dce6e8497b1e9d3d51e3","_id":"@noreajs/oauth-v2-provider-me@0.2.1","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-IPzWGCm0mNgqXB2pLRERKMfPGO8mApQ3ZU+be5S+zAOj1oQKpRrFsvYMElvHgSAF5TPrEixLS83My7O7kFk5UQ==","shasum":"92969f81fa3eb7edd7ab3f186adae7f23432f0dd","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.1.tgz","fileCount":118,"unpackedSize":357868,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzmrUCRA9TVsSAnZWagAADHsP/iHuMCDKyiCBI4Hv/cch\noshS7cRMA2wH71vZHhNl3o9jWvVD+9qzixsJYeQcBzkPo1R24gDRkk9R99RR\njeeQyRZpN7MDFhYnS5PdxODOl/YIAXjTIQnunQQOSLNJM8tMxboTeXwLkxUO\nTLI0JjjtwvDw3rcTiqWlbr5txwzaD3xFiykYnRBHlE5iCN1eMomqjnkkh37s\noSIUZ79Tg6AV5vFSLPRjnyL1fhlyhr8iAIdvhdzvSLIfK2tPYqY1N6tQk2mT\nI/shI5ezAgd9/DzsCVAER86dpJwVl7cbMlAP62OFmzg4UrdCcDAhNMCyLxII\nGU6iJH8AhqLyC9WeJhe0DT75T2VJyJp9sKpM9KYFFV4x+ZbYDFVhoYgZ0/dK\n8ch6vM5OcCrd/L3dSLWYY25Fl5wVz5gIr3y1HV6EhSG4iUg+tk2+zfRY1p1o\n9ac93EP1dgqF3OkraLieR/CEN2IU2af4AvNzn+LMbkw34DQTaoRqGAyECCwJ\ne1dZqipmOJeHd3YHlGRR6/GMFLxy7gBanAk4MmZXtKElXqx4k6VLfFy5lUeE\nS298IuSM/+zJyr+QUpD/WO7ku6W/t7w0JoX0MIIl8OErzu6fwx52QGEDKrFI\ni3EH2gV0j7h/X/evUWGSd+KU10KPX01oy4JSjrkn8OxIZC4cc42IZvyLjLg6\n8B0j\r\n=DwzA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDJsqpWqX1MPrpj6aTv3u/Bt4NfQVXB0qVPQpJuCKjWEwIgN/Gfbl7bTlrlM56ovY0uSbjTs5APWD8CaDvs2NI4hzw="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.1_1607363283825_0.9432253325114843"},"_hasShrinkwrap":false},"0.2.2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"gitHead":"740e27e33f9ecc8996d192a3662c05c248e22009","_id":"@noreajs/oauth-v2-provider-me@0.2.2","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-eG+3Z+AQa3zNZp0bonArUPBXgLiIKewxvLlnprUnEWkszYJvhIcWgeEaHjHHFxDI7Jlyf4HNU85qU2urQ3h6nw==","shasum":"6680439ba3b914686f004e1e0cea9e87c2b2dc45","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.2.tgz","fileCount":118,"unpackedSize":358281,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzm+hCRA9TVsSAnZWagAAFhEP/1Fkv9IXLy2dfhusxoHB\nW/WSVCszesKxAIiTpoIU5UMPSbd3eeUW4jbFitAwQrmo3zVlz/4pGtTjRy6w\nTI/v6RvYSr100k3uHkArKCWzrJO8zpjDni5CsputWHcIsdmGomHlRMmMr1i6\n5YaAoLvUBrBFG99gQ1Nq2Z99iP9fXQDA9e8ZOxfkIAJcD9mntqi0AgCBUCgj\nx1T6gaNDKy/n77kJvIvnxg/1hE+M74FHUDZxgMkXFdZBCe2NU8DPvTcgrSY2\nX5Ovy5lSyz+9vQpyb4oEGXAxmIEYUvslKpYS5eUPvLnyKPk2syWivTtKAmZX\ngiHezVG3+Ta9kiUvI5FPohr+DwSiBuTF0MaOtYG3XRDTnD1o+NDLOZSsAz5z\nEl13h0F0XU+wSfzkoJm4QqI+urJS4Dv2ru0y1n5p5f2//A1R4DDSwzXkx+7t\nmtpE6n6uFY8zcsbPF85cVjmRfUEep4eBxGoGED9Lql+miMGEFIyLrWVTb0TF\nVEP3RRBngi8VZiwoUOIckULPFQM0iE39ZdUaPlCwGFx12dajdKyZiqhJUg4P\n2tpHtphGF0PZUPDouSar2AOb28U72nhchjIlqIRDnpy2J2Q1ml9+6uWFpCdL\nMRVdVruS3j8U7VN73TtrCuN5DatnWzMe0bokuhE94OEs/B+Z9xLDSs+KypCC\nqGoY\r\n=XjXl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGsRiJX/3hwqoSAwICEZ2BGoBQl8vkSgKTo05meozcXAAiBVBeYmHClpduPvzXNFGGkrUlFeJsEOnN50ahfRduG0Ug=="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.2_1607364512673_0.7168749068851685"},"_hasShrinkwrap":false},"0.2.3-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.3-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"10eb5f0c024b38b8be8d65c7014a13ad898f7760","_id":"@noreajs/oauth-v2-provider-me@0.2.3-0","_nodeVersion":"14.15.3","_npmVersion":"6.14.9","dist":{"integrity":"sha512-YBCZoXu19WRrS7GC9UxhNxmmDOn9HkaJlZttvQ9NkJdJ9jGVP48pJvshrF4pfU4tFB4NXjHWLh1v76pSQMPWkg==","shasum":"2a71769bdd645f75090de61359616dc2ad9972a2","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.3-0.tgz","fileCount":118,"unpackedSize":358994,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgBvmeCRA9TVsSAnZWagAAGFUP/3qB84bz9Wf1aHPs/6/n\n9oIiTPua/hRO7EpHRC7L1yiLDR75HSQ0x6Wv8i/DO9HxrQhe7MZJIK88P153\nQPCyQG9c20fBGosXUOesPX9/VY7u37wZc7KK6Sm7GV2A4UPkQO+UmUfH9oKh\ntXVrDbkzUdU4iZINVznTDc9jUtBBbr8benX6tdLTnUxCKuLlvgXBYfYi9ZrE\ncYcRo9VvPWjh2jhneW64HUyWCBQgq7Sjod9Fl9iVuLBXmf/KpNBL45ZfNvWt\nGf7WcqI7k0vDUEyty3sDF6pMJO8ue2lVlGfJrdx8LF7SmS2JkOqJcrXLRTsg\nbDIJMYJrNlezFUeafZOPsKjLWVLjPMjV1yR3ma8Q2r9mJATKz2KNwG6PXSNu\n+rlIuL45aHVBbDUFBQjUGl5Js1QBxXrFi7cWVnbWUHmS62q4m+/gKbk61h+E\nHpgFQd/ek41dSFPlz2sgIX6deTMqmAwCpgpbs2rR8MD2BLyxYoPmZU7i+vjQ\nAEQBf0W1uuMaten6MX7lZGuzc0nU0O3dMm7+fpn7v/EqIj42eGB6GZZYvGwp\nbLXGNBOVr0Xt4fQDO6tUd+MxeMfCuuFWsNMkks2BgkmVfp0+uyKU6JHJKx5u\nAZNkdzZzTvQhyHVg1x7Ol58zlQNzL3tFCGpt7UIwshPNZMtmHAwfNyeCyFFS\nJPPn\r\n=N+SP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIClCm2z+6iTVh51N+c1sYRuRHwZVLe+2/tUS/Gb3mRABAiEAkO7lyJFWyisKcKW03N3zdQI4CC0crgPXOU/xu5fcR3U="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.3-0_1611069854155_0.42848158952465965"},"_hasShrinkwrap":false},"0.2.3-1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.3-1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.5","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"6fa49b48a8cfebdcdb4bbe452343475c1342cc45","_id":"@noreajs/oauth-v2-provider-me@0.2.3-1","_nodeVersion":"14.15.3","_npmVersion":"6.14.9","dist":{"integrity":"sha512-5+b98W6SMyEjwg9fd19ubu+EMyC8uBt1gY9SNVtuVo/kNpiSohpIUOS3j8qgMIe/0uO/jIJ0aOBFFxE9bggrqg==","shasum":"06d7a891b56de76f35c8325d71a1fd9748719ce1","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.3-1.tgz","fileCount":118,"unpackedSize":359018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgBvuLCRA9TVsSAnZWagAAQqAP/i3hu26cdnAFWGwyMIEh\ns2fBnwTeHAH2gbgkWD8XvjuGSqYCGMuolcum2u4NLYz351rvNDGqNB2pVguj\nSIXoVQv6wexQwqidDM9UHZ5KuNFjHnUFtXdVzrNWie/tQWSnHoPDn0/F4p7+\nTTtTO6B/5bkLJ86X9Aj0bzpVWTjVxEXVYIRP4hTmT21qdIudQX+Gl1611d7v\nbUHcfDwbbBFv7PKN49/Rqjl22g/vyBPBJjjKNLxYp+fGEZ7fy3g+pv2QL73x\nNWNBYwYZDt/8smbi5dg/VwlkCeoYa0v7kMj0wGGjs1XaOqPq0C4mK/SUSTPG\nIJzTMq65TnW3dpyYizOAOBMI0kogBJHzb+hkTmqMljhnsi2LqViQP+4+YPRq\nY6lYyUtYFUAZkZV+ceO/fqPXkebhfNImq/7U4iYMp5aD6tr+1II7w/6rpCf5\nn399yVB04cRgxVp7Hr6IkikF9q0cgJy2D+mOBk2EBfJF4I2O3xzNwK1+S9PT\nzmNetYzrFEBu1rDMiCGqiNU1tJIJ55uudZeNGn0qRRRiOrlreNgoJ2MS3rBy\nO7rf3MWljXj/3e8MLpnPbVxOq4XLxm8XTSN3WQx0xVVgT4yHf404FfvdYKQi\n7k7DLraTBHcWZaVDhB/+Wn4LzXhaCBjo5niO1WCufERsUt6CzPbe/HBK91Xf\ng11Q\r\n=GdoR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAoZ6fa3ZAEJjEWnDdpGsqXIZuqWS5IXk0LiR4LSyCkjAiEA9mFl+rWcD+V2BdH/0DolCdODjB9Sp/H8W4lT0+/2x90="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.3-1_1611070346985_0.6381599908665696"},"_hasShrinkwrap":false},"0.2.3-2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.3-2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.6","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"909c9e691d42d2c7a03e011da43e2f071d79f9b9","_id":"@noreajs/oauth-v2-provider-me@0.2.3-2","_nodeVersion":"14.15.3","_npmVersion":"6.14.9","dist":{"integrity":"sha512-5qTa4pDnZ2jAmKv8Basb7yA05jXZhuN+Ayn+iutJdCo8XGWApSIlD2vHI0PHvNEWZJVAYqaq+z3vMfar1i+KmA==","shasum":"6c4115fdab7670be789f03f814e78fdc2c0318be","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.3-2.tgz","fileCount":118,"unpackedSize":359018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgBwNnCRA9TVsSAnZWagAAVdUQAIGHMRcEX3RzuUiJYcLW\nyPiXQiaj3s92rSaad4aAfSn1LPmTmuKJvTYXKdm7+P5CoEl4bp447d7VUvsn\nNYwvIkHJtDDrkUM/rdxKn7+nnE9QivuwLm7FBQDiMUu+vKs7FiW4Kj7o2b9v\nG2/ZR7iWhBkjjVmpWvrXcVNbC+vfkJWrGAwAQb5hpnqRvYPoWR901NA60c0i\ng1HzoW4ZaQ67fsqVU8ilRWzLA3kuJZRCF5f1Xt+/ptdbwB9tjt6vCL517M27\nEk4QkOujmVjgM/gcD79/5C9AOVMLbq9QVhwfriMlShqRoqc1q9P+Wt05vEZe\npL67NCQwrFxaevfkYw9uQRPi0lSlIUn+Z7HDrAMlQrwYeLp47rQJFee71mso\nUSFBte+JS0b7NoIFbGn/n5imsaMNot9Fu9M0IIQXUzNSxyLljZzAiQqvaAaB\n2tlChEUCqL7poVPA6fATD1MToq9yZ+VFZtIWuHSlMNdEe71+xep+IHdfXram\nba+o2T3atrBlW3Z3k61RoW8UaiV6lfEgar0w2fjr/OkHfAEcBTYTwCkDWzBJ\ntzYZeufjez/DBSy/yGSbyQScy/gJX0vu3aOiw3d6YbT3UhwGYfh1ibM2+jNe\nW3HBLE1wSt/4Ly/GHfuRh36WtgDm5Infl1P3zOE2lnNcYWRxSBZ0dCCUWN4R\nl1x4\r\n=aPro\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEb3UdbLq9VB+WJqvuQvVDwEp4sU5JRp4LxFzMFEHiGtAiEA0OC9CDgHIsn9M7dAJSSu7Tomd2hJRsBdTMcYHOY/2L0="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.3-2_1611072359258_0.32298401599324067"},"_hasShrinkwrap":false},"0.2.3-3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.3-3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/core":"^1.1.2-2","@types/colors":"^1.2.1","copyfiles":"^2.4.0","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@noreajs/common":"^1.1.2","@noreajs/mongoose":"^0.1.0","@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","express":"^4.17.1","express-session":"^1.17.1","jsonwebtoken":"^8.5.1","moment":"^2.26.0","oauth-v2-client":"0.0.6","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"5a4875d9e409425a8c0a6ee102676afcc048adf8","_id":"@noreajs/oauth-v2-provider-me@0.2.3-3","_nodeVersion":"14.15.3","_npmVersion":"6.14.9","dist":{"integrity":"sha512-ETF2Z6wrX/b+SxEDXMyMFuT8jcCqQKK0sPKyv5DkVzHJkhJSFpTCgChhE07evCZHotYA6AAbXmSJxqO4byHhRg==","shasum":"b759ea086d391c234ba0b6d2996a358ba79cd729","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.3-3.tgz","fileCount":118,"unpackedSize":358258,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgBwpVCRA9TVsSAnZWagAAtuQP/RoqTSB4mPMAEiZdGHPq\n3g0DVygVwl/8zpYQ9IYiku8422fZn9oKmyAf0MWcwRbJxPHQsfnTe20uwCwB\nrVk7BQ/jYgaBfb6atTG5gNXdPJ0Xq60TYoqBm4xxAonLLtdV6+mrE5cXBpNr\ngVPc+79+rrR2Fql/xNew9BKsgjOVEhryOtM/RB0nErtyhfaMQG5BuQdJLetC\n1PuqMgGlGPQnsduoRAR3Bhe0+XEcTOij+eNd5KbNKK4+r4yC1oFwIjyBpF25\nOKvusZX0Hje3gwQW8ISsNUQKmF+rgi55B6DitRR92I22yUdlYjPPoty9BuzY\nBh2zrINLLw++qxNg2sOqW16CDbkT+KWOJ1uGMMpKGkpM2JCeH1LTcsA/O1JU\n9JVVpgnS19uJxEgc3AKHNqyhhTfguWLsJjFuieO7xeQFohK9KeJ1HD1yl+8/\nDAVmKLreEXNFnV2UN288jmu/Ry6hntU39Q15Y0iOY3B8mZMTAL2SbBwMr2Nv\nUywhIcGs8dbcEVsOQyo82chXZ1Uts+ToHG+hEZoQpFpN04WxQkljC9+3rQqn\nUMHlv5GeRgp8IswNynN6X6wWrblk97Uo9kCgSj2t7E46viChCi/VY0GG+hSG\n0/3181ZuGmq5HfgendqR7o1JDmr4m3u1cSO7j78BlY4E9+myyYyIEvzquwYG\nQvhz\r\n=lsim\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCjn+c0OYAU07kEmDF8nzOT59gbA/baZ5LrjVt/i1ANKwIhAKsWXVaW7SQyWo7HqlJKS6FfXKm9Fj1Gvd+/1i2Ro/j5"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.3-3_1611074133225_0.531298107560954"},"_hasShrinkwrap":false},"0.2.3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.1.2","@types/colors":"^1.2.1","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"0.0.7","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@types/express":"^4.17.6","@types/express-session":"^1.17.0","@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.1.2","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"0.0.7"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"119b2622359d453ed3d20fb3f6aae56afda665bf","_id":"@noreajs/oauth-v2-provider-me@0.2.3","_nodeVersion":"14.15.3","_npmVersion":"6.14.9","dist":{"integrity":"sha512-vw/pP6aE7cEcF+70AqSKaEK4EqH94tLErgmXnj8gBEp6mqomfP5uSJ1M8yhPghdAZMidP7sLTFuyEqAx62JccA==","shasum":"39c8a58493a9207d9be20ad091c72140855d53b6","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.3.tgz","fileCount":118,"unpackedSize":358718,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgKVtBCRA9TVsSAnZWagAAXhsP/jd+pI6VnHAP/IesJUKw\nu+yhgx24phPZYe5JYwxGR4Q+sCIZdl06cjt6QJGHA3uTVsdD7fJ3Y3zV4N0N\nVFgq/HjXrpUU/mNDtP6W9ElpIEJbnFz9bXCLoeGn9VqUs/Z8r4W0iGkiYlRD\npim/tfly5S8qrpnGVoZWcwu+w9oCSWmVudIhW1m2mShW39xF+64jonJMv9jP\nOxY/XvCIoWQCk47HDDjT5K/PPyG42v8a33dDQfmhCPg2AmTfHhTBSZhAWyeC\nCMyldM2ge3rqnQAxhRapqP95yW4Er4CD6qlQK7ajcX72r7PGk+KNyWj6LiHE\nqx3HgyeaeqLPnsi+nPTZL0zlaFU6epL7WhtZvO7rLqlfPlBlmFP/kroW0bEe\ncVCApW/yHZioMnBdhpYuEI/jplThlcipz+M8zxRTXQIHfoYuMYXVVg9f+wSJ\n3Nm9vRiIpeWyYcar2O+9LHTVQIbOuDwJeSCOB5Qj0PJ4xINTEr2ZQ3cFxadM\n9XPDE1Qz8ui23qOAP5Rj+GF1MFfwcZX9PwD7As317zTaD6kLw7N7cAoEmZht\nfApa8N8O33GxeHIU9I9fIKETxyCP/V/skl7hkCuNYGBet6okgmykfe7VONOP\npUJdaci8MKI3rlFBguKS6DSyVSG3CWp5ZYahu142oUWPUiJ78wSD0cYCzpOF\n697s\r\n=eZJi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDIFiBwPvWoY8Eu8cG9xDjVUo98cERTKCZLtipGc4z8tAIhAOsMstT0PvStFodwLtT1+cWuA2cRjphni2+UnA325Lkr"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.3_1613323072864_0.6535538957553901"},"_hasShrinkwrap":false},"0.2.4-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.4-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.1.2","@types/colors":"^1.2.1","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"^0.0.8-1","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.1.2","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8-0"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"35d7bd5d7f986c5a4ed8e2a1e2072143aae5c1dd","_id":"@noreajs/oauth-v2-provider-me@0.2.4-0","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-ZNFNQINjEmASnCghtG83qChFEVuUl/SHNyov7dX6cLYuFx4d96Vvq8UEIVhmM/PS90wRlLu7aAqXXQZJZs44Qw==","shasum":"74a4294cbad573ed7bd9a936357ac46e6448fb6e","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.4-0.tgz","fileCount":118,"unpackedSize":359263,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGOXKbLVGyM0XQcTEma98ojRvflgVankgIFFI9WUlJiTAiEA/ME8MsKJtyp/OalhgQk658vu31Xai6Z62SVXGRwDVJk="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.4-0_1635621654844_0.01929919593672036"},"_hasShrinkwrap":false},"0.2.4-1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.4-1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.2.3","@types/colors":"^1.2.1","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"^0.0.8-1","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.3","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8-0"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"5657a4f6643db3e25e284b5d2378d6fafd2c0306","_id":"@noreajs/oauth-v2-provider-me@0.2.4-1","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-jQ2Lh6FDWOI8RuRPjaKkf9C02gX6fOla/XzMHRwdRYx+BLF1RxAH5W3cf9LPBcZjdrh/6XbUHDvCqlZR+Dc7dA==","shasum":"12440d33e68c4d6a923a047b46a9e9cb49be0d73","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.4-1.tgz","fileCount":118,"unpackedSize":359263,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCRdzeJQyp4D8HiD5Rmxrs5135ySUstxPxfiKWlYd7iRAIhAJQuvy2876ObK4bOxNPkgkf/dz1ooFcf8DbPKnzEWJ4c"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.4-1_1635624769575_0.641336482559699"},"_hasShrinkwrap":false},"0.2.4-2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.4-2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.2.3","@types/colors":"^1.2.1","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"^0.0.8-1","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"@types/body-parser":"^1.19.0","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.3","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8-0"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"f07b13dabb5524050999ca02946260229a1569f9","_id":"@noreajs/oauth-v2-provider-me@0.2.4-2","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-lUnkBU2Fc32iK2LrZi7tV9l112sdCmwZIboUEqokCdByvvOAMKerD2uyjmgBxgDVpTdTVnpyEzccvY9pcnnT0w==","shasum":"f8d2a1240cdcb751ca75eae319c56bea15c8f11e","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.4-2.tgz","fileCount":118,"unpackedSize":359317,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH3N9wACZGtL+695knwMnL/5oKBV51qVB6MtOhV1KQPZAiBnADoRVBgN92cRgPBgRbgRRWR8VhCyWEgUpiWANpnFNA=="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.4-2_1635628348109_0.7679663666395333"},"_hasShrinkwrap":false},"0.2.4-3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.4-3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.2.3","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"^0.0.8-1","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.3","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8-1"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"dd90fade0442950868d5be0667565810719a4a15","_id":"@noreajs/oauth-v2-provider-me@0.2.4-3","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-LKwyDdcgE+1TVdf2lOGVQG93O8DnSSUKNKqyN+JiSCwRMYKS2gwtEvNMbtxRir3IHeYVA2dLNUBAPyydmUtXaQ==","shasum":"bef7ae4a18975a12eb78e292a7d8f752e0744eb3","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.4-3.tgz","fileCount":118,"unpackedSize":359317,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGJX34T7w3303Vw8anhUdqwgCjyZtSu5jLjuqzmYzLnzAiAIR8+RWA9QMmVsj8/pgso1jwquhgn9LK4o587oQRTD/g=="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.4-3_1635630568486_0.22491399180671623"},"_hasShrinkwrap":false},"0.2.4-4":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.4-4","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.2.3","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"^0.0.8-3","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.3","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8-1"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"112ab426a18119716b551c53ba4a31941172f0db","_id":"@noreajs/oauth-v2-provider-me@0.2.4-4","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-CsAv3NTXaxHxIsUooBnvvNAFI57yiWGaeCM/zkwNTlorqD/R8VjD3JiojcXWGSivt8yYzkZ0lTX5oIfskn0Z5A==","shasum":"3e792bf9c00778e79900e1ec326e7f700745960b","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.4-4.tgz","fileCount":118,"unpackedSize":359317,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDf+am/9F3/t93KSotXxXUP9iZfUDpXiZ6Wn6IzxMVrgAIgF7QXjUar/KLh7EyFI0AFee2+QoDUEl+IXIXo/mzPyGM="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.4-4_1636686322863_0.19036579978932933"},"_hasShrinkwrap":false},"0.2.4":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.4","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.2-2","@noreajs/mongoose":"^0.2.3","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^5.10.11","oauth-v2-client":"^0.0.8","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"body-parser":"^1.19.0","colors":"^1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.3","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"484c9919404ec5896a8611bd8421852223e3ffec","_id":"@noreajs/oauth-v2-provider-me@0.2.4","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-m+dyucfMDESJzzoR0OsmtyDNCpp+rJ8sPuPkaRq9qtdxIVDOmGKnXDrNZXlLwkdOLVBWZhdS3HpKqg+G//3Wig==","shasum":"ad55ee18cb703cbe10a849ff1c3ae4793f0a59fc","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.4.tgz","fileCount":118,"unpackedSize":359311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2TnyCRA9TVsSAnZWagAAYpYP+wR0FovdCFP2NEKfjkZ6\nrm0qDHIYX7M4KHfj3cQKUhIxIrA+1/dMGTsGoC/M7tWMUX++ArwWqM76Jgzo\nwofLYYlIfimK4j/2LTg423oPxxQMQuST2oHTvR6SZ4JGAl3RW7qBbMC4SHot\ntV5SudFayzAJJqg95O41itmjVPCstXLYUlWLne3JmpTWdbsuk2l5kDKndSWe\nIn+8OcS0J+y/hCXw0a16IErnn/wpoYg0PFnHpw9quGV0mtZVMT7h3/INNb0V\na5873WTKXZFmkqqQK0AKDJkT0AOpHoDb9H0nu8HCU9W2rE9wMK1RUdNd253Y\nUlnRg4ohBuve6doZy5oRwc23yTVLqObV+Cs6G6M8S4n9yV0qaf0oxrVXF5li\n2GOnhbNvNkvb1DqMrfNFequeebqgmNVInlHL34QeG3tpbeAO9Ie3cZh4FGLV\naNspPTxvhk/MGIyiy8igJwNu8XBIGV8tdy/IFytujEZ05RRqGXLEOWVth/Oh\nHCrzfMFXjw/LqVkC+fmWJbj6c7DZeekBdI4jzvbghP0Sg3dOhG6YHbbE4EHK\ngZ81rw/Ne8h4RRGQW0xIWbrndUOYEm3DpDfSDjlJDmoKD4VVdtKc/yjye7kp\nZI6WnfyZcRIjMlTA/E1zPxZ2S2nYOl/3xzMj2xQS4I5AczuLjwFC4bxwgTAe\nWnh5\r\n=4ttw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDFuxzWgs35+CSXw5lK1g9gMK7rgFXn8jJZ1ZkPSuZxHwIhAKVk4z8JW9GaJLCnPqxQu/NfXQdL+MqzxEHK2Cp418iR"}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.4_1636687403875_0.7835901651707486"},"_hasShrinkwrap":false},"0.2.5":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.5","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.9","@noreajs/mongoose":"^0.2.4","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^6.1.6","oauth-v2-client":"^0.0.8","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.4","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"c14c4b3a022f2c707a12c1a579057d4386ad1744","_id":"@noreajs/oauth-v2-provider-me@0.2.5","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-ad80o5gYfy/HjPtGrfovuyizz/2Z+tZjfSjwOi3sFntu841tSM2q15HSA8KxhxVGyhY/NxEqPzlakJ8epHRsdg==","shasum":"ce9ba6a1f23ab31f24daaf8a5e924fea32b354ba","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.5.tgz","fileCount":118,"unpackedSize":359014,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4FgVCRA9TVsSAnZWagAAlPgP/jDcBvHY8uGuOGP6p3mM\npD3nGFEEYddhoLrJh+WTDepUVGm9yaRFEYO7IUQLJwqulBrCXkf0Je5edGBi\nDnvvoOY4F+R4GdA9wxzTM9wbBp7+LbStDdKbrGvJl416yXYUgGyyU8Vs/38o\nvN+25TPBa07LLueDiAmqEaauRTVUYAei3t1OwlEmNpe1ZcxRHwRHpGUuMC+j\n93B7cj3DyU1910O6nO4RW7L9l5uB72DG9QFFnknxh3mj0ovc4Ju6+OeAAY8r\nZoXhHAfJzAaSjfiFqg2OOE9uqoQsf5QZ3pNKiuejtPbtO/Qp3FLwOp1SAQQF\ngWpY04fK3Csi7XGSwuuhkquRIKi/Pwq5s7hpRHF0MQylUg6zVe4CaW/6qvsa\neCTVXtK18anZ66UUR0l7aRlk7eCMBcIQeRM+UIF6jbdXI9651dr0VJoL1g1n\n278N5sAtA1R5fFKgTzgfd/LaV3J/bN//5b78DBfWHbsgaS2ohoEdK6jjS4sR\nYhIHNZS4b9cKeC3zuNOoEoTeD2XMAyE6j0rfPyXKeDjWt0k6M7v+3RLBVdWj\n3wxfYxHhqVTDUX9DpnNPT+jFI0OrCUkqgFjqVvRSvt2VCmeBfAy/SJMRmjUF\n3OoXxIuCOrB0i5f08Pkh+TpvvMl5CGcS1NN3w4P4rC2RsbvJ4Mc9/es4UlmY\n6c9Z\r\n=FMth\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICzBqEwQqdKAlompI3DEY59az+y+L042tkgn8VEVuBbTAiEA2cAc/vPkMhvO/xS/hnVczN9saSq5ju4MuXXa7s/4vPM="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.5_1642092565139_0.7335648361081819"},"_hasShrinkwrap":false},"0.2.6":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.6","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"^1.1.3","@noreajs/core":"^1.1.9","@noreajs/mongoose":"^0.2.6","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","mongoose":"^6.1.6","oauth-v2-client":"^0.0.8","typescript":"^3.9.3","unixcrypt":"^1.0.10"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","moment":"^2.26.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","uuid":"^8.1.0","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":"^1.1.3","@noreajs/mongoose":"^0.2.6","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","oauth-v2-client":"^0.0.8"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"131814b30f2ef2afa3eaeb2059ba1ba02b3803d4","_id":"@noreajs/oauth-v2-provider-me@0.2.6","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-hWQIdgqy0+AyFTefGuXCMSWXZkAvD20cWwBscL/G1E8glA9D4XweGjYcKdyXdY4fHVdUfC5navKJ3SBcyrRk7w==","shasum":"fdd1d8fdb8d2de4082795187e597627c2948d920","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.6.tgz","fileCount":118,"unpackedSize":359014,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4RkCCRA9TVsSAnZWagAAlsMQAJCGRivb2uocgd0NlcqF\njAaeaf9Outg+B2hbR3qhpI1c2fuFMkSO7vNRQnll+QVDVafDc/lVg0J3M+I3\nWmkBbNJa+GXHta4BLdPPJ5AM0MC23MaxWFVxz9ByJ9UryUW/Q53RtNMwXZM4\n4OjRYXO+9x/NOEvwyhNuODsvbDjtydRID+1prlEOMREy2yUU/sJyVo4135XF\nyDf1qHrt+dPoH8gj70Wlp/ATLyVl7/+F+cWxNtz2L4swuEyR96c1OhO720+1\nggcYF45fMO0RmugmwCJ58t7O5w4NA7aquRy2Ukd6/RndHqJ6aGOcEUGqok+K\n72Rw/jDv3VAjSBMtBq6bFb+1F88Fg9NJoxE7Ulv6K7WVbJgaJgcQ0cKgZGPP\nBJCz7XHSg4J5d7Nu7getV44bxGn7pVpsy8yfZpTjOQZ6OvhJ1TJg+K4XVz4b\n9N5SYKskTL3x11KpSy5elsIFBebBXIvhNt05Ymq9dSWwqUrz9vNyw2WNdB6s\nY1ZRK9CZdxWLK6NtRy0Xqavlh9a+MPzrGglICvqsE+/lbZ9btDsxl0r8/Gi8\nRr3pYfPG0gAEg4p+9czLVLbyJwX7pdwxyMmXXeenQlZdeHnvr9YBUlB83d1g\np6VJ04aD4hzXZOCFlpJMDpQe+gwER8v9PMCUfgnh26zfu8QSykIBsU9+OClP\nSHoe\r\n=Gxik\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC3EA0v7LtEvVReTQ+VQb38wCnBaYXsfYfTk+HLnSY7WAIgfLav4PHeZj01jMIo1UDamdBMcBKbMeRT1WgDHrr4ieA="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.6_1642141953945_0.26841618059939387"},"_hasShrinkwrap":false},"0.2.7":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.7","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.1.6","@noreajs/mongoose":"0.2.6","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.6","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"1ef2dffa8eeb8a8b6186138c3b482dee6cbbd784","_id":"@noreajs/oauth-v2-provider-me@0.2.7","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-BQGVXPyYgzOjsCWVsw9xF7XjeoQ5w4EV2VFsusWRMCVpeptG/kyQy5nRA2IuV+g3kVrHEiz3Pcqoal9QooqU3w==","shasum":"fa3754bde36f0ec21536ca82827eed82fc51628c","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.7.tgz","fileCount":120,"unpackedSize":365889,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh7yGiCRA9TVsSAnZWagAA2b8QAIlRPvxSF9iEq57xvZf9\nbIdQECfdqgYsrYYRuO/S9HT1WE8aFahZ9urO/W+KusURqoz267RSzTcEvoLd\n7rPMvh2nq40VzxUSpxTJ4Csi0YTq1IYFZJ4T973TUZZKPujy5LOPPxiSszuj\ngvww7BF1y4lYJyvj2cClUvCtwd7pWAnUDjowaD1acOmYgC2+swlh8KZCnhn2\nP+A1HPAdyFaKHzC0u1Do0OpIRiYrO6YsCTzd7zObBc3fMf8j6HaxAcfgMNP4\ntWy68YuVr6ZzmQ0JfYB2kUyWk+j1q5j/mOEz8UPuMd5QHC5aS3JVjy/5Eipk\nr4++b1rHyGzc9VZikNgcdux4VCn149R1FF88kIqbxdG+HQdyJ/ytb2ZhJgEb\nrwJteNu7v0qCqdes5kW9I/1IxTV9P/pFq4Fn04v01mtZ4PM4vXbJXvd/Em7H\nzcXmA0pr3z/qZVF8h+UZ1mV9uC0zE/yU2Wd8WdSNrQFzFvjZvlJTT5o5gZAY\n5hxxVJBhiElmNoez7PQNHk7eEAshKtb7bJZVdSsd5cy8srLM0uTk55L1KsPb\naS65/EkPcsqPsoXKat74sO2pA8RYY7Ih0b0TZZQBeLEavFimxoLA4qvKtM1n\nVn4XJGETTH+jkQrgp7VU5cWIrLtxyzWSxz7dM68u+CP2lHh6CCqL9AN+Mso2\nG5kp\r\n=1Xh4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHYDnFHcjxjKSPsWy/BF4FYEqeV0q3cNFeEMtDWVqdE/AiEAi5k0lpZmMIvbqw4VSZLkGeoR/Tfee4lKYg31WQ/VAt0="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.7_1643061666430_0.4978803702348269"},"_hasShrinkwrap":false},"0.2.8":{"name":"@noreajs/oauth-v2-provider-me","version":"0.2.8","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.1.6","@noreajs/mongoose":"^0.2.7","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.3","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.7","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"3249a5ec1186e6f721941f82770ee5bacb375d26","_id":"@noreajs/oauth-v2-provider-me@0.2.8","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-K27PB9sElrpPeafT9VWV6v3To6pBoOefCP4ko8jw2YdayBx3KrzO+FIu1ei30yXQ2kCGrw0dLACEFyYWjq10cg==","shasum":"ac0e2af28f4e6207dbd46951be732d37a2caf4e5","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.2.8.tgz","fileCount":120,"unpackedSize":367410,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8Z7ECRA9TVsSAnZWagAAAOYQAILbkO2859mzDiNW6Y2f\nTajS5BwfGfGCSmjo6c+T29SD+ksWokRxMfAq8sCBDHqU5dS5S9vs2jAzEAuG\nU4vfur/HLkwXOVVPAeJ0eedjn3Ez2Jbe4CfsJDt/zI29rvGrpG1PWpeMGMOp\nwEf0x7TbaKq4ILdLCzO0pSSr37ewTthRU1WlaAxZhSzaRVLRFpqtLtnaCJsS\nu57AHouGD9vtKhz6mpxOExztXqUx6iRbODXusSx0Q/bHoqYfTE9NhmY1m7ty\ns0Ew4vCBbKMl9+MhPz+cJh7UUmGgfuljhklXjDbm+MpV3aoabu8/6AMDtLxW\nebp+jAphy5CNsDgOTQSHmXqWBg6yvQpdwafo4eFORA7OWQIL2CiH810/dSzf\nTxOUA1U6b/vkKSjsr784mIBNnIwJYkh3FgBDDMbqSdCVVHpoYpy+iWDoEyAf\n2Bk2Q0hciMuQkFDIN/GDDkfjFaG0Yh4v3wcDkSAsHhLwrEpiUYQlKjlpw0Zm\nky8lmvbY/4LUVtdOlBCLuBB5qO0kOjnh9X5UdAnTwym/pXJqWwD3Utr9zdlq\nk9ZrdT2+gDb4kZh2UOiIeMGbFIqurxYyR8smIHE1xzxlPQ+QFZyNswDApN5S\nNlh7sxRQcqGUbqVUL/11ZLL5wX1YGq7wZoM1teG4Hwx/DERCZWPF6Vkh1ww1\nIGDn\r\n=vVvq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDaAkYCZevB951Z94pI4eslVNOUHd1C0r/vr8Se+EnO4AIgHn9zwcrvOdN2jVxYWoBfmx6sjWQzLCbrAD/+0DSJGaY="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.2.8_1643224772453_0.3134629681769674"},"_hasShrinkwrap":false},"0.3.0-0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.3.0-0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.6","@noreajs/mongoose":"^0.2.7","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.7","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"b9712abd1f9b877b32c28066ddc5d0a380b31f17","_id":"@noreajs/oauth-v2-provider-me@0.3.0-0","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-mV9fX4eO+vgFBSmvIviUp7F5eZul3Rn/0TQ/uipX5/j7ZGy2bYHI4yaOXybWy/OB5jhvAc0Z/ViblZkZc5UhyA==","shasum":"f5bc7896ddc80cd3fb60fc281859537890aaecb9","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.3.0-0.tgz","fileCount":120,"unpackedSize":370419,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBqhmLo8Ok86RcrxwZHabHhHhucJhwzLH5SPleaj1jk4AiEA2eCeGnrBBUXTPCCG0eouyC+1m2l1OZ6hvxxc3MvD8Ic="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJido+0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoqgQ/8DaiQhbBR92xvNUAKfVCdRl09vvtFi1RCCqCinjGWuxQgSQwP\r\nPUHIP2hNw9bt85rHOf/NKBsIZH7y3zn3gWA3YIsfSoGUa4bsM6EAiznlGmda\r\nSj+NmsJ5NijU2hPixZ2AJcla0rKGxlqlpw3+3H9nmQkkjicwk0dX2qUjZ49B\r\notOx6nmJSYwP1HXODUGYo6V3+xtLEizNXT5tN8AYRYza5U8x6ZceWKDOc+4G\r\nLJQUFdDJA+aWaYzNux4OgcYLOwcQQcBhFwpiofZ5z8u2y0Vgvq0L1ZqQeXwb\r\n1kMp4Pb27vY37Rh0JKol6fZ18qE/rte6dLI8dwVlg8OZcUA76HvQOlJ4Dvep\r\ncSYsds3IQHOgwzxgarZlMFaxqrsDAsWuT33nusIfBoReot4eHY6femchibcn\r\nlDhpuVNmnQCI4OCZ+ihMwtouqKHUsAUuFmjZCqX4uW6yvWtxIwukaa7zs6ks\r\njpSDZzz3HyME8HvF73VSDf3oHfxgoQ6/XiqKDg0whUAOjRyKk/E7lY3TsuQf\r\nAkamkc+RfpelC3rTmAThG8Xl2mynghr9nE4CIvnmRRYZ9M6yx4/+0Vmr+ypc\r\nzp/782d20cbE4lakgqCPz57WVdFwsMbMiWIn8e338NO5yKuyvahL7mpGvLUA\r\nm1do1vCedyVk+QpmuVDqyse9b40+F7Cy0H0=\r\n=GrYA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.3.0-0_1651937204619_0.8038362851482335"},"_hasShrinkwrap":false},"0.3.0-1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.3.0-1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.6","@noreajs/mongoose":"^0.2.7","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.7","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"dc8b65f78354b43ce1fdf207e42fd75c4525d16e","_id":"@noreajs/oauth-v2-provider-me@0.3.0-1","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-1CqGnMAFjsyQ6ygcbuhLvKNRgqPXInYQuUf9ydaECBdPX96KDwmmpnCTRX/HY+sLNgluvIiQT2dwNsJzzbQFPA==","shasum":"f7cba494a96886590bd8d16391f408d18774df2b","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.3.0-1.tgz","fileCount":120,"unpackedSize":372836,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFjj+hU+8P3CboL5AyQZEpLHmknhotfp4KWcRdfvfonuAiEAj9D0KuExMrFtuLHQX/pwNGxc1lwmtoISr+FM8w8r8X0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJidp7EACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoTMw/8C8RKYb5YIWjQUCaW71VjhK29DHN+o8zCbkirZ1OQ8HVA2RxF\r\nk06rkTuMMT6keu6UgTJOoVZ9iw5hBeUJYWcQYavZie4f2+RsllUQJR9/npQJ\r\nfTIk3lhuPCPcM94KFuosVWo1OzFrr7rzNmWOi1DzioZRJTQg2SxfVRTfj7eY\r\nmcb1pOorbFndcOHldSe9iwsmRzmAvMvb1qcrMpqzemG6Jo2Y3AvHkn5FDmDp\r\nii+leSyTPDajKSLzdjkwFUrwCvG1CUhEghvdK0eO6ZJwSi+/Ut1OJl4ZWDFj\r\nSICP/+CDM2oZ8IFep8MKhFqdEZSQXAsBLQwx7+LJWyfGaAeKfp6x31p98pb9\r\nI3aynW1bUk/r+tv1rel2tAZevgNXC9xQvMwXt0GUyoF5yrIBUmqFY/S9+z9y\r\nzJcsACOdkGuqU+dMCipCg3venUrRrjon/j8omYwgzYo0Yi13kaGuQwjMlAfZ\r\now+AhqlCZhLGLTXNHaogEVcge4Ucna4lWKE1w3ty3rQsiTeNqdiRJbIk0pSq\r\nSP3PK4j07c4QarMJ+5sf75pl6AdOPwmw8PTQs9+BNwpm1Bm8PPNFAfyxsoyp\r\n/ZDj+N7CZjhAO5HwXFz2aun5CIT5uylE+srEt5lR8qrkR6ovScbn4D+rZDJY\r\nAWJ4uq+vqkvoSfWhsTaCabwpURtQ5gApcx0=\r\n=eF/K\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.3.0-1_1651941060569_0.8409595889560348"},"_hasShrinkwrap":false},"0.3.0-2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.3.0-2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.6","@noreajs/mongoose":"^0.2.7","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.7","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md","gitHead":"b258d93e152546c9d05a1a18dc7ff97f43eb858a","_id":"@noreajs/oauth-v2-provider-me@0.3.0-2","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-VnZen/LygU5opVjNFR7aUHxsHnbN1qIJp3bvgKj9GHGpR7KCO48HzJkd9G8r7wSJZYUzVMjlenO0jod/UsncLA==","shasum":"f595314f29b85df2ef51d2fe07929a5cc83c3f26","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.3.0-2.tgz","fileCount":120,"unpackedSize":373107,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFFrvrV03ARk9aiRxdpSKXR9XV6F8iX8nbm8qlY5oQHKAiBTv7iml9Z6xknUiRN3T9P5joFzYJ6zL4EP3I/CA4J8SA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJidqmcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrmcg/+Ml7RLIOLXN3LC1gZQU77hkeyvlmPmGYbRjvgNIc3SBrYTF+S\r\nxSVc57uipxJG/+8yY8Jt3fhJMrGReezMZAyo2KDQqmD6xQw87a2IXEC/jG3g\r\nL9EmaNHm1KC0TdlXFYVSCvAlPitTQQVGpvjQlRCKz4E140UQq6DEO5FKe0vv\r\nCEGgfcVUAuvN0FhMeFBKdeBE9DrLkueMeyccgxtsn4wxQhtYpO6c0cmaxdse\r\n1ZlJTGSm/h+dUY1u90IhpwoApyG9ibN2O1lOd2D9iIV+DMgiErV6lB3I0lEO\r\nLw4vVkaV1SCu5fYfLTE/0TGsiy6KTIlV/AvNruH8Nwr2H3ptFMD0Nh4sfgS3\r\nf1xiDGw0wG4chDiHnoGRITppLJi0qsPXkaamF5O8yTsTvSzEBRy+Rg/M42Wn\r\nxGgJripjDpIKDQtfTawv85ZRcBdgpK+OyZUvoNIrU4A57KQlZwLRwVvKyGUK\r\nJbFfnqFoRL8u3VBbiPGcS7LnvI3FEbztp3wr5RZ9DTF8DiVbncH2dOKuZThy\r\n4U8OA9hJ0U9VbZ+Mbei5AOJWejWRuVP70a1PEa5GvtDpBeGkqssylpp33rTN\r\nkIkTag7O5tp2ej2g3YFg0A+dxSx32paV2BSGkOALdjpHhQ+9HU+DRMQKJLU/\r\nSHt+9K0iTK5HdS6BP4j84hXCBgLPNOGLRTk=\r\n=P0MU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.3.0-2_1651943835788_0.22103647261299209"},"_hasShrinkwrap":false},"0.3.0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.3.0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.6","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"3747757f457ec981eb4699ed5c5010c142a14a38","_id":"@noreajs/oauth-v2-provider-me@0.3.0","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-Z3WystJcvJdQyiLO7zjyKohcqgbOe2q9GVZViReu6r6/C/X6bzZvDFKPIHgBK5M26CTFyX2DS3n+zxA7HJEbfg==","shasum":"adea1c4096f5dc7eb27062180977a697594f09b2","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.3.0.tgz","fileCount":120,"unpackedSize":373008,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAZ5pJW734KtW73HdLx1jQuJ3dzkR4KpAtnn70WC6NTbAiEAwiuMAir7tubt8cSv8M2m3tCCUhgXCvSrnvrupKJdmc8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJij3ALACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrZxQ//f4BSCMY0R4JSmytd2eCBMQgY50QpVGKvlSr2fmbBkKQ+4OeA\r\n2F2eJmzuwZdSgGkSgtedYq92dDVqxAuBQK2vsZ8fyF35s8bjzlpAZ8rYDi+s\r\n8AKx8gJWB7/btMXCQpKCvCzT0a/Yj95vWJYlZUlp3vP+RG0svTdRK4EbVaSj\r\nYMC55xvEy3cWMImae5WSRHPkRRtjvtuas+xRzMxeV60VzCYNTjMfaqb1hfhu\r\nReOEqQRcWNftxF2EOLXN+ltRtpElhXFrv2BzJvlIzHwAlXBwx8tjzOjEvXKc\r\nLnIAFQ1Tzp4DspSVfR1QgOnyDdLW8FVVMoS7NFSIMmUXKinpbBXEd+RFBP3I\r\nONDB9pNoSYiSToUr6WA1k0e26Izzsg7LcQEcTQKkbMNue7JvN+K5uSzQ3RH7\r\nzvA5NFBbmKWVqjCdPBw8QJhhlgcwUJYN8OdocPvdZ9LU/7n1y8VTLQS1giEZ\r\nKmh66eNu0Y4vWTUD36MPxnaad3Pks9BJrVHG3/wPtcAUZkd68ODK2NYwn3oH\r\nwgUR8W6SluG/wqznxwv037V5eIRc729qhagJImrNyo+2rluzSUTQE3BdB0Tz\r\nbo5yavnH9bHEefjk2b4kyql6Gtf98/JE0CG8IWuw5wx+hIzH/I6cgnVtEr56\r\nxZ9i5Hh3bYIHPAnsZ96/FnDfzSqrspD3Ppw=\r\n=lUzo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.3.0_1653567499597_0.9246664461001701"},"_hasShrinkwrap":false},"0.4.0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.4.0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"2672b65c71f947cc80730b40908c61aa9a7e6397","_id":"@noreajs/oauth-v2-provider-me@0.4.0","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-BUnnPRE4QCyWruxSWj0wWxt5RmoWo9df/+2fzG1ixUzLNiklNOmu23U0grbKUXWdNIfAxqPsPGVpUZhBf2GJRA==","shasum":"aff9f3d676d77cd52457a3b04c02871427df5ceb","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.4.0.tgz","fileCount":124,"unpackedSize":385558,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD7iYZuHNazRWG+jpHV9YdSFYTqux9WkIe+xqTe91QT1wIgPxfj1w3T8zjPyqp98tRLwwWywmHogeL4o2/jMhjwFN8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJioD+GACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr5IA/9E1gbomT0482LZdjaMgwZ6kbkLFyfYZMDTMaxunqtX31xRvxa\r\nhS4xDOAg5n9YTpwRdiQBOsfVUyfr20+rfTugClOk9V3GJXvxo1Gvu/HB7lrq\r\nwFEKLHUjO+dmHK9FWKGxgP0mtbgnABNzQhs+WMh+1D4skZEW/Ow4HifPXzdb\r\nSVOIYCJfzBOOKfCDRrrG/0crocD4b08K3SM7YujHM3vkxwmfafp2TWaCbH1a\r\n1NVY8WTlLnmEoTWPwlSU8Sd20AbcTsAo7x0nnYK4GmL+WXl1N63W/iCQgevb\r\nnwG+QIy2grUuPlGyuqfx9IAuVc2O9fqUlZucnBR/qYyqvDy/8e161zLZgP5D\r\nOnKfEJzCrC+9rADSmJ638Jbp3FqtavEbJUNY3/w62+eVT9FelcAtKJ5lFHxO\r\nYtiZRg3l3fEi3PlOI762qex9zvf1VVo9gqweWyf74A6Ao+4HIt/6kqLU5OK0\r\nQ/XzbWuhvmpRun/rEmO5fs1FOjHWQuimCyF4IZ0NWFOHlmVVVelBTPXeTD8W\r\naUZWmhEsDvqdK6V6rNoc6Mf9qoErb941PLTfnpSK4Jm/l39KOmNNqmCgvbJu\r\nOEKnC5tUhaF+9lKGQDwcRh8Efld9amFQdZBtG5blm+ZOdP6JjNkqjwFE8R83\r\nV7Sa9aH8/AFiRhbB9AMYBCxlPOMXHm3KKbE=\r\n=OayI\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.4.0_1654669190516_0.10642250532875908"},"_hasShrinkwrap":false},"0.4.1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.4.1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"0.0.9","typescript":"^3.9.3","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^8.5.1","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.9","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"6494cde44eb40806f27f110a298d284b3889a7d8","_id":"@noreajs/oauth-v2-provider-me@0.4.1","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-AU66nbVTjkFJUaB+3TPnY4Di2mgWHHAHpdfSig24fWvwFEkXpdQt6EbAuk9nI4INZgnIor5PTkKw181+2DnD7A==","shasum":"7bf0c0778ba5c85cad9f5f12f3b0b46ae66527f2","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.4.1.tgz","fileCount":124,"unpackedSize":385628,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFueU226QNLOzXyWr8nKvy3Ssk1SqVNQtuKju3QbxyGrAiAqg9C7vTiXQMI3kgLm8G13HjDwe+YUCjrmoeuLGTsNJw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJioE5wACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrwIw//VyIskNrflZNV7N+QyMDfoB3L+1XH13KOQpG3ptF9Oj9/zd7X\r\nDnjjvdPD+Nu6wE62YN0vq4Xx/vaMZFa2wHA0xut+YZ/YhkuuPc5BB1a47ccw\r\ni4vtl4BRPv8/LWxjXdhX43UQk648Ff30EEyqzmbjvWGAoNUleF7JYHdA/IxX\r\no04ZUFwgnAp6777bNOc1PV0Dde6gumHIbG1P+rMx2+6aZ1WGATA9wU8jTM+B\r\nZcahqfa3UaTPEFMN84j+WNFyprdiO4IHjVJYfa/q6m5ItmgMMXfxnpk3XzTL\r\ntkP57IYq6KRO1ECzs0acsoXOvQ9aSiBCS7nBHilBvdNbMvjb3xtF726JpsKw\r\nddlRWgkliKfu0nYhKcuL5NFgdjgCZDChwS15VEcKIvCpIH/oLna6fPGBUZZk\r\noJBptRoY4lzCu2Qs9dqiG22/WBpCBMUXbytiNhtEFia8A+5TIy1fIzzOV7AI\r\njFxdB7I3nggfrQH7G7BNi8UHjnJw1B5IgG9nJFiJVYaOdQvkD14N8rx5XqeQ\r\nYrXJkyVjkGC1TevuSaNkinW4c/jN6IaVJAc3jLlaAzTHwy4Czls0KMqZVzF5\r\n7yP5KSXTgpxD+gL02aeWR6KYjZC1EpgyxdN+sZSHgE73KQ7bzlyMXStDj+ht\r\nlO/8zlaNZgqR4b90zrALNBJ/H2r8uIOmKRU=\r\n=f3k9\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.4.1_1654673007768_0.12788248288107762"},"_hasShrinkwrap":false},"0.4.2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.4.2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"^0.0.10","typescript":"^4.9.4","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^9.0.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 0.0.10","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"a2f27f67eb2398171261b1f6714216206d7fad8f","_id":"@noreajs/oauth-v2-provider-me@0.4.2","_nodeVersion":"18.12.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-/jYblxwStme0AJSq+Q4rbJKh2R2igLtvga0Dr52HlJrYb1toyFsoMMLfmTllyxc1GxdImMo3Q093WaxxSdqc7Q==","shasum":"ede1786cec3dc91b82c98971b421af106c2c6432","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.4.2.tgz","fileCount":124,"unpackedSize":396378,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDygZQSoXjtcWFk9VUgvD3ZPThbISnlqBd/e+TtZkQLvQIgOes/0oVRWV1ua+FGC26wiwSmf4uF6KU0gUHtHTw7lUs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj1vxFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmou9w/+OMlJ3QdQodCykhKTKfpVqPNtnkRkUuoqLp/VxKPZqBx9+sHY\r\n7PFxg2QEEuTr4MpORpATEgMKsAmpeyI5x3z4otyHznBCbabGI5NvR3bje9nI\r\nmnrYnAiFC60urFGSKSQNRO5KVszjE93EYo0w138XCeum/JhhFocI7Dqa5fsf\r\nuX2w3//oMla5ySO6NGcFYx1W3hnpatAMlQgiThNJtyMU+z3fWf7c2Oixf8Sp\r\n1gWL3DqFG2hI+Ti1QuI34wkDpHUPUJUNw/hrZlHMOIZ/duLUtiiYpmIiJe1r\r\nrwVHJWYBkeBJMWnYsYV+0kig73b6PIg5wFNxoLLOYR7lh/GWoEPy+KjmM10q\r\n2CMG6TQSkS+fcOGvlFYNfL+2f97Zfa4oZIJQpwjRrjXds/+t58gYGoq3gfvT\r\nM+GX4sLwFSusn1vuhDJ4sGN7duwo0ozgyhDB7HG7Z+APTfvq0PwNYQjENXWW\r\nv8pF3z89tBBvcGqR90GruxXT1lEE76VnzGo8dG21hUXF7NGIN0kpD0fpGPiu\r\nFVxTRz1HMO3pMQ2toYpZGeabzlHfgHmw84Rrbfe0gnoRl1Oy2/a5jbAEQO7e\r\nhAKcxScJqw0iZLMGpAsgBqDtisYAhKfO/VuthMpMIB51Gzgx1BYs/HZoDtLr\r\nERcvsD6cgAaN6oUXOYJuP/29Mn9ge5YP+Ws=\r\n=gokv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.4.2_1675033669391_0.8452796962006703"},"_hasShrinkwrap":false},"0.5.0":{"name":"@noreajs/oauth-v2-provider-me","version":"0.5.0","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie":"^0.5.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","cookie":"^0.5.0","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"^1.1.0","typescript":"^4.9.4","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^9.0.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","cookie":"^0.5.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 1.1.0","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"a37def1416e09d8483eedca3f4a75d8cb9d0bba0","_id":"@noreajs/oauth-v2-provider-me@0.5.0","_nodeVersion":"18.12.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-Yp4deSfX5BB0h1uhBY10/Jo7fDuDqIF4WyNjcC+OC6aqGRgk2I2KQRqkcZm1BkeOiVDrqyqGjMwZl4dAwNNLgg==","shasum":"0e95df6d23ab7ac88dddd7e876ed1764dc664b38","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.5.0.tgz","fileCount":124,"unpackedSize":410743,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAmqEyW2uTMLowSNanRToV3nfDl8CGfTrqVp6PNhrpHLAiEAk9kTpNK0Xwf61f9Sso4EHLu25VFuKHv9LISyZocg69s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj3/31ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqK7xAAhEA2LzZ8bQdRF4NejI86EUOOLLno6b0h+W625deN3PyQPT9u\r\n+j4EaLTwtinV/jmgxuvLOcD+U2PdGCzECQe9/qZ+zcufIE+KtDfjrCfKb9QJ\r\nVReOjDVRr+OBeFIf76svn+4b4vN4dVIQUoAXGvpGmuxF7WDTKz53qX2UWzhk\r\nl9EC50wTlOfmI8Wiux1v1HaiZkH85Q2yVw/tM08DD88XeOcinkXpcWK7sqtZ\r\nYSeh72mnSll5DqnIDtRGOzzRd60XpYT8BQb3o/ExVheu1JAf9ElS0fd42CBl\r\nNKysJ641GjmAzzQIrcu++kDz7IFarpUVkG5ItipvJDvxStvqT/9ofWQRJk7s\r\nD6x5b+Uzl56hz8TtKw4q1CJSloMv9j1hFnJbBrHvAzPCfCKRixXqu8IHspnj\r\ntvUC0wvagedpR9xJ0w2V4f8nB7l2hIX4jneQsUutTvDvwurD/h+qqFHndZPV\r\n3Hoa/yrrBJb28RpzUgdGa7/sAHyMUSjowGjJl3LO+iAmfpnO48EMNqQS9tk4\r\nDPs/k/Ma/MSkLEL0yJWxV192MHq5ukbKqTgmPF0IjYV44KSYoTnjd5wtyJFN\r\nNJj+r5CdDu+6oUJs7nnbWdIKaU1nRtv4yXIkQ21IvwwKxv/g2fwNoBEnnwos\r\n7cflaRGy+JwW/qGjKUS+UC2Hop+E3+zbNSA=\r\n=fq8x\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.5.0_1675623925373_0.9656962393542352"},"_hasShrinkwrap":false},"0.5.1":{"name":"@noreajs/oauth-v2-provider-me","version":"0.5.1","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie":"^0.5.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","cookie":"^0.5.0","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"^1.2.0","typescript":"^4.9.4","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^9.0.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","cookie":"^0.5.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 1.2.0","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"d7c9a4ce0fdb73bc3b0192e2de2f1c0eb5789178","_id":"@noreajs/oauth-v2-provider-me@0.5.1","_nodeVersion":"18.12.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-UWcFfu0XGGlp7knuzbd7JJYtkHtMcZ8gVtFeExiVoYmcvQGsecJ2ca9r1PWAzPxwwekn/vE+QV3gtf07jhN6Bg==","shasum":"74f38f6c3a73a6aa3fd2a10c2f1365e3a1af4e6d","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.5.1.tgz","fileCount":124,"unpackedSize":410743,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEaCgATCPQFYKVY+lVQ7ICT/ZLmYfBnmpmjBD8eo7cMsAiEAnRdQI/yJ9FuROKfAiGoJmKEYgFYUvK7vLKWZlR3viOQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj5CbRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqqKQ/7B/Nm1j8dkkP1QGaSwreh8MhF5TZUcW3EsN71w5IYWSlfr8cX\r\njffp+g4PLVUZEQjoEKhMplUbI8KC+J3Lf2drh52wvuYxYW0aG9+ll+a3SfIR\r\nrDTERAHtQFglmgt5KPwm9JL86ztm9VZB4m8t9RcjRkWncshD7kIP1FjtTRdc\r\nfdrtPG+mjofRNTnr95ZbEyraBl/C+7DZMIJggzR8jEb11Y7unF/6SHo/lv9B\r\nwtiUjl3UOyynwAfgojsoR+yGqx3CARGgqKq+yApiJ+Qfv/Dy9tu8nuVzmRV0\r\nhwi7JvUKIVhxBVSQIz2z+qzrVsKxUEVBTAj2euoJ5VgOhUrcAdYAjfBVOEJc\r\nuESJDP9TZA0eMhK5VlXz3mB+qWEkWfpmqLwwmCP0Mlux3g6x5kd7QQ87PAn/\r\n75OEHLweqN9LhrDhkOFk7o0mf/ijL5NGwcudmfhyOo5OYd8pYHUd1SaFufM5\r\nKuhNZ0XdARCzBfF9Jigt39H9IwLUo0F4gUAetibSj0MPRZD7dP5MNP9WWdEh\r\nWmWrelyWqDJrBPWLq7F9g1rx0uHUGAuHkQvWolHtfTBzohDLSAZ3PJEKhWSQ\r\nh3SLYFYQY7E2rO80/Bl21z8Hcwr19f69KWeYIwOSxvZ4anh7Rk4W2SS7fZK6\r\nglP4saBsPfY1xhoJoEAOwvvABQJvx///Hqw=\r\n=a5eL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.5.1_1675896529788_0.5629001201116743"},"_hasShrinkwrap":false},"0.5.2":{"name":"@noreajs/oauth-v2-provider-me","version":"0.5.2","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie":"^0.5.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^0.21.1","cookie":"^0.5.0","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"^1.2.0","typescript":"^4.9.4","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^9.0.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":"^4.17.6","@types/express-session":"^1.17.0","axios":"^0.21.1","cookie":"^0.5.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","oauth-v2-client":">= 1.2.0","uuid":"^8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"ba4500d3faad0df74b984c8c148ce91c353292c9","_id":"@noreajs/oauth-v2-provider-me@0.5.2","_nodeVersion":"18.14.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-tjQjVNLo1H9Cw7zS8Ywlje06cwCfJXBbrgyFBoCjXDcXLHh9VttCItPi7l+wEhR+AuCNQSgOornZmod4lNHQgQ==","shasum":"22ba0af639ccef138f0c8c81cb7ffff2519d5045","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.5.2.tgz","fileCount":124,"unpackedSize":408889,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCLqOttkKXJftM5hbP5evjSVNnoqKP5o0J0Aru5MaEEQIgXHnjpRhyUcXED7hOuMNGwkSIgFTVWIGtygiez8YElAA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj8oE4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqKeRAAmL5426qwWoxg36QjzXOqktI+M3TLjfN+arER+naT0qtyrFB5\r\nKJiFVq6RUYRDfWrK1wwaq1N/q4IEDevicklb+myX9XvHAcmrw5A+o2IakCav\r\nP8Kh43Fnl7tmvi/Q5GFNXEjSl7v6lCvBGQNRzEaDb076+s7ypcaZf5dC6PHl\r\neIgT5jYXNTxFsZLWU0HHa24fJeXXg5Y2j+Yw1xfTPVnri/GrU+LIvIdgcpgA\r\nvzv429v1yxo4BuXdi519chIEGlt7ukFnBTDU3UW+c8qY2q7/h6hzCs9QdOgZ\r\nv0oQ7U4L45SoUHa7s7VAZ7kIEf+hm/ywCkBF0FFWtgIk//xt2mgj9en/3U7/\r\nAXk/G2Jb4bebfCpJvaqf10MUszsNw40HLqpH8RfBSNcDgWFoh/InmwLy0mjU\r\nPvcZKqfqOHBjEuZigkXt/P3kojc6jN1z3fYo1CbQrKEcdKRxbv9vXik/KNUA\r\n/PfvoAinkRlJ0COaAn4ru3uHSyg9MnKrCwK+EMSEJruFK7qho+gRgY0Zy/mv\r\nTmkhCJDjo8K2WfUqxx8vVz8X97cmP/9zAdoBbcKxvm75vDpBOWUCG5sjO3KA\r\nr2em6ozqbk9reJqMV5mohn+PrNlyBgwGm6D3O27cP18OZfWfTvWKxt5qGTpx\r\n8TZveh1c3FaNwrwOZ3Fl/RM53MmQhk5yAwA=\r\n=hCu+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.5.2_1676837175813_0.5018119056339558"},"_hasShrinkwrap":false},"0.5.3":{"name":"@noreajs/oauth-v2-provider-me","version":"0.5.3","description":"Oauth 2 Provider for Node.js using MongoDB and Express","main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"dist"},"scripts":{"start":"tsc && node dist/test-server/app.js","test":"echo \"No test specified\"","prestart":"npm run copy:assets","prepare":"tsc && npm run copy:assets","copy:assets":"copyfiles -a -u 2 lib/module/**/*.ejs dist/module"},"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"author":{"name":"Arnold L."},"license":"MIT","bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","devDependencies":{"@noreajs/common":"2.0.0","@noreajs/core":"^2.4.10","@noreajs/mongoose":"^0.2.9-0","@types/body-parser":"^1.19.0","@types/colors":"^1.2.1","@types/cookie":"^0.5.1","@types/cookie-parser":"^1.4.2","@types/csurf":"^1.9.36","@types/express":"^4.17.6","@types/express-session":"^1.17.0","@types/jsonwebtoken":"^8.5.0","@types/uuid":"^8.0.0","@types/validator":"^13.0.0","axios":"^1.4.0","cookie":"^0.5.0","copyfiles":"^2.4.0","express":"^4.17.1","express-session":"^1.17.1","moment":"^2.29.1","mongoose":"^6.1.6","oauth-v2-client":"^1.2.1","typescript":"^4.9.4","unixcrypt":"^1.0.10","uuid":"^8.3.2"},"dependencies":{"body-parser":"^1.19.0","colors":"1.4.0","cookie-parser":"^1.4.5","csurf":"^1.11.0","ejs":"^3.1.6","jsonwebtoken":"^9.0.0","rand-token":"^1.0.1","serialize-error":"^7.0.1","validator":"^13.0.0"},"peerDependencies":{"@noreajs/common":">= 2.0.0","@noreajs/mongoose":">= 0.2.9-0","@types/express":">= 4.17.6","@types/express-session":">= 1.17.0","axios":">= 1.0.0","cookie":">= 0.5.0","express":">= 4.17.1","express-session":">= 1.17.1","moment":">= 2.29.1","oauth-v2-client":">= 1.2.1","uuid":">= 8.3.2"},"peerDependenciesMeta":{"@types/express":{"optional":true},"@types/express-session":{"optional":true}},"gitHead":"505a968b5a55b1fe60ac2f11a9b82ae5367aa19e","_id":"@noreajs/oauth-v2-provider-me@0.5.3","_nodeVersion":"18.14.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-m9DWt/rLY3woYxW4cqwIvsyQ6SgDUJLad4XnyO/bBqu3iHhCUYi/7H7fKj+ZuULsaUBhnFPY/kQr0B1Lm5AzJA==","shasum":"d409ed88a534e4d70eb0165e791235ab6fa38e62","tarball":"https://registry.npmjs.org/@noreajs/oauth-v2-provider-me/-/oauth-v2-provider-me-0.5.3.tgz","fileCount":124,"unpackedSize":408903,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPj9ytKXC+1Wm8GmdB2/xRdGSGvhM33eM8TuSHsiOYVwIgRF08wCwRcYV2Iqgh1HT2g0vcyeUzd8FVrCQJYwMhD/I="}]},"_npmUser":{"name":"lambou","email":"lambouarnold@gmail.com"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/oauth-v2-provider-me_0.5.3_1690654435334_0.8130867124409757"},"_hasShrinkwrap":false}},"time":{"created":"2020-06-20T22:04:37.414Z","0.0.1":"2020-06-20T22:04:37.905Z","modified":"2023-07-29T18:13:55.658Z","0.0.2":"2020-06-20T23:10:35.860Z","0.0.3":"2020-06-21T00:47:56.132Z","0.0.4-0":"2020-06-26T14:56:20.908Z","0.0.4-1":"2020-06-27T05:03:37.640Z","0.0.4-2":"2020-06-28T01:12:59.062Z","0.0.4":"2020-10-02T11:46:52.393Z","0.0.5":"2020-10-14T07:17:02.517Z","0.0.6-0":"2020-10-18T07:33:40.107Z","0.0.6":"2020-10-27T13:03:31.464Z","0.0.7-0":"2020-10-27T13:38:56.042Z","0.0.7-1":"2020-10-27T14:58:46.010Z","0.0.7-2":"2020-10-27T15:08:43.759Z","0.0.7-3":"2020-10-27T15:18:29.386Z","0.0.7-4":"2020-10-27T15:29:48.395Z","0.0.7-5":"2020-10-28T06:09:17.866Z","0.0.7-6":"2020-10-28T06:27:36.232Z","0.0.7-7":"2020-10-28T06:46:13.131Z","0.0.7-8":"2020-10-28T06:52:29.598Z","0.0.7-9":"2020-10-28T07:03:02.359Z","0.0.7-10":"2020-10-28T07:13:54.452Z","0.0.8-0":"2020-11-04T11:17:47.893Z","0.0.8-1":"2020-11-04T13:28:41.239Z","0.0.8":"2020-11-22T15:16:33.657Z","0.0.9":"2020-11-30T09:29:31.089Z","0.1.0":"2020-11-30T10:31:50.701Z","0.1.1":"2020-12-07T11:15:49.902Z","0.1.2":"2020-12-07T13:23:03.136Z","0.1.3":"2020-12-07T14:04:07.538Z","0.1.4":"2020-12-07T14:19:52.659Z","0.1.5":"2020-12-07T14:47:50.729Z","0.1.6":"2020-12-07T15:09:28.033Z","0.1.7":"2020-12-07T15:15:27.708Z","0.1.8":"2020-12-07T16:09:17.126Z","0.1.9":"2020-12-07T16:31:05.063Z","0.2.0":"2020-12-07T16:56:03.217Z","0.2.1":"2020-12-07T17:48:04.022Z","0.2.2":"2020-12-07T18:08:32.902Z","0.2.3-0":"2021-01-19T15:24:14.466Z","0.2.3-1":"2021-01-19T15:32:27.132Z","0.2.3-2":"2021-01-19T16:05:59.458Z","0.2.3-3":"2021-01-19T16:35:33.434Z","0.2.3":"2021-02-14T17:17:53.062Z","0.2.4-0":"2021-10-30T19:20:55.034Z","0.2.4-1":"2021-10-30T20:12:49.755Z","0.2.4-2":"2021-10-30T21:12:28.293Z","0.2.4-3":"2021-10-30T21:49:28.626Z","0.2.4-4":"2021-11-12T03:05:23.094Z","0.2.4":"2021-11-12T03:23:24.079Z","0.2.5":"2022-01-13T16:49:25.363Z","0.2.6":"2022-01-14T06:32:34.148Z","0.2.7":"2022-01-24T22:01:06.683Z","0.2.8":"2022-01-26T19:19:32.665Z","0.3.0-0":"2022-05-07T15:26:44.804Z","0.3.0-1":"2022-05-07T16:31:00.902Z","0.3.0-2":"2022-05-07T17:17:16.013Z","0.3.0":"2022-05-26T12:18:19.813Z","0.4.0":"2022-06-08T06:19:50.738Z","0.4.1":"2022-06-08T07:23:28.094Z","0.4.2":"2023-01-29T23:07:49.577Z","0.5.0":"2023-02-05T19:05:25.552Z","0.5.1":"2023-02-08T22:48:49.937Z","0.5.2":"2023-02-19T20:06:15.996Z","0.5.3":"2023-07-29T18:13:55.534Z"},"maintainers":[{"name":"lambou","email":"lambouarnold@gmail.com"}],"description":"Oauth 2 Provider for Node.js using MongoDB and Express","homepage":"https://github.com/noreajs/oauth-v2-provider-me#readme","keywords":["oauth","oauth-v2","mongoose","oauth-provider","passport"],"repository":{"type":"git","url":"git+https://github.com/noreajs/oauth-v2-provider-me.git"},"author":{"name":"Arnold L."},"bugs":{"url":"https://github.com/noreajs/oauth-v2-provider-me/issues"},"license":"MIT","readme":"# Oauth v2 Provider ME (MongoDB + Express)\r\n\r\nWhen you develop your APIs, you need to secure the resources they will offer. The Oauth 2 framework offers a safe and secure way to achieve this.\r\n\r\nThis package is an OAuth 2.0 Authorization Server with [mongoose](<[https://mongoosejs.com/](https://mongoosejs.com/)>), [Express](<[https://expressjs.com/fr/](https://expressjs.com/fr/)>) and [EJS](<[https://ejs.co/](https://ejs.co/)>).\r\n\r\nWhile developing app using **MEAN** _(MongoDB + Express+ Angular + Node.js)_, **MERN** _(MongoDB + Express+ React.js + Node.js)_ or globally **ME\\*N** stack you can use this package to host a Oauth 2 server.\r\n\r\n**Table of Contents**\r\n\r\n[TOC]\r\n\r\n## Implemented specifications & Features\r\n\r\n- [RFC6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749) \r\n  - [x] Authorization (Authorization Code Flow, Implicit Flow)\r\n  - [x] Client Credentials Grant\r\n  - [x] Password Grant\r\n- [RFC7636 - Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636))\r\n  - [x] Authorization code with PKCE\r\n- [RFC 7009 - Oauth 2 Token Revocation](https://tools.ietf.org/html/rfc7009)\r\n  - [x] Token Revocation\r\n- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)\r\n  - [ ] ID Token `(soon)`\r\n\r\n\r\n\r\n## Installation\r\n\r\nInstallation command\r\n\r\n```typescript\r\nnpm  install @noreajs/oauth-v2-provider-me --save\r\n```\r\n\r\nThe package already content it's types definition.\r\n\r\n\r\n\r\n## Configuration\r\n\r\n\r\n\r\n### Initialization\r\n\r\nThe provider is initialize with a simple function.\r\n\r\nInitialization function definition\r\n\r\n```typescript\r\nOauth.init(app: Application, initContext: IOauthContext): void\r\n```\r\n\r\nThe **IOauthContext** is an object with some properties useful for the provider configuration.\r\n\r\n| Property                      | Type                                                         | Optional | Description                                                  |\r\n| ----------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |\r\n| providerName                  | string                                                       | false    | Oauth v2 provider name. This name is going to be used as cookie name. |\r\n| secretKey                     | string                                                       | false    | Oauth v2 provider secret key                                 |\r\n| jwtAlgorithm                  | \"HS256\", \"HS384\", \"HS512\", \"RS256\", \"RS384\", \"RS512\", \"ES256\", \"ES384\", \"ES512\" | true     | Jwt encrypt algorithm                                        |\r\n| authenticationLogic           | Function                                                     | false    | Function which take username and password as parameters and authenticate related user. Response can be an object of type `IEndUserAuthData` or `undefined` |\r\n| supportedOpenIdStandardClaims | Function                                                     | false    | Function that return claims to be included in id_token. Response can be an object of type `JwtTokenReservedClaimsType` or `undefined` |\r\n| subLookup                     | Function                                                     | true     | Lookup the token owner and make his data available in Express response within the `locals` property or **express Response** |\r\n| securityMiddlewares           | array                                                        | true     | Middlewares to be applied to Clients management routes and Scopes management routes |\r\n| tokenType                     | \"Bearer\"                                                     | true     | Token type will be always Bearer                             |\r\n| authorizationCodeLifeTime     | object                                                       | true     | Authorization code lifetime in seconds                       |\r\n| accessTokenExpiresIn          | object                                                       | true     | Access Token Expiration Times                                |\r\n| refreshTokenExpiresIn         | object                                                       | true     | Refresh Token Expiration Times                               |\r\n\r\nOauth context default values:\r\n\r\n* **jwtAlgorithm**: \"HS512\"\r\n* **securityMiddlewares**: []\r\n* **tokenType**: \"Bearer\"\r\n* **authorizationCodeLifeTime**: 60 * 5 // 5 minutes\r\n* **accessTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24, // 24h\r\n        external: 60 * 60 * 12, // 12h\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 2, // 2h\r\n        external: 60 * 60, // 1h\r\n    }\r\n}\r\n```\r\n\r\n* **refreshTokenExpiresIn**\r\n\r\n```typescript\r\n{\r\n    confidential: {\r\n        internal: 60 * 60 * 24 * 30 * 12, // 1 year\r\n        external: 60 * 60 * 24 * 30, // 30 days\r\n    },\r\n    public: {\r\n        internal: 60 * 60 * 24 * 30, // 30 days\r\n        external: 60 * 60 * 24 * 7, // 1 week\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\nInitialization with common Node.js + Express example\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth, IEndUserAuthData, JwtTokenReservedClaimsType } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    secretKey: \"66a5ddac054bfe9389e82de--your-secret-key--a7488756a00ca334a1468015da8\",\r\n    authenticationLogic: async function (username: string, password: string) {\r\n      // Your authentication logic here\r\n    },\r\n    supportedOpenIdStandardClaims: async function (userId: string) {\r\n      // Return supported Open ID standard claims\r\n    },\r\n    subLookup: async (sub: string) => {\r\n      // returns the user who has an identifier equal to sub\r\n    },\r\n    securityMiddlewares: [\r\n      // Oauth.authorize() - Add this middleware only on production mode\r\n    ],\r\n});\r\n\r\n// start the app\r\napp.listen(3000, function () {\r\n    console.log('Example Oauth 2 server listening on port 3000!')\r\n})\r\n```\r\n\r\n\r\n\r\n### Session\r\n\r\nThis package uses [Express session](https://github.com/expressjs/session#readme) for session management during authentication operations. You can initialize Express session session in two ways.\r\n\r\n**Before Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    resave: false,\r\n    saveUninitialized: true,\r\n    cookie: { secure: true }\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n**During Oauth initialization**\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\nconst app = express();\r\n\r\n// initialize Oauth v2 provider\r\nOauth.init(app, {\r\n    providerName: \"Your App Name\",\r\n    // ...some options\r\n}, {\r\n    sessionOptions: {\r\n        resave: false,\r\n        saveUninitialized: true,\r\n        cookie: { secure: true }\r\n\t}\r\n});\r\n```\r\n\r\n**Session Store Implementation**\r\n\r\n[Express-session](https://github.com/expressjs/session#readme) middleware stores session data on the server; it only saves the session ID in the cookie itself, but not the session data. By default, it uses memory storage and is not designed for a production environment. In production, you will need to configure a scalable session store.\r\n\r\nMongoDB session store example - [MongoDBStore](https://github.com/mongodb-js/connect-mongodb-session#readme)\r\n\r\n```typescript\r\nimport express from \"express\";\r\nimport session from \"express-session\";\r\nimport mongodbSession from \"connect-mongodb-session\";\r\n\r\nconst MongoDBStore = mongodbSession(session);\r\n\r\nconst app = express();\r\n\r\n// inject session\r\napp.use(session({\r\n    secret: 'keyboard cat',\r\n    // ... some options\r\n    // mongoDB store session initialization\r\n    store: new MongoDBStore({\r\n        uri: 'mongodb://localhost:27017/connect_mongodb_session_test',\r\n        collection: 'mySessions'\r\n    })\r\n}))\r\n\r\n// initialize oauth now\r\n```\r\n\r\n[See the list of other compatible session stores](https://github.com/expressjs/session#compatible-session-stores)\r\n\r\n\r\n\r\n## Manage scopes\r\n\r\nTo make your API more secure, Each route should be associated with one or more scopes.\r\n\r\nSome endpoints are already provided with the package to manage scopes:\r\n\r\n| HTTP Method | Route                | Description        |\r\n| ----------- | -------------------- | ------------------ |\r\n| GET         | /oauth/v2/scopes     | Get all scopes     |\r\n| GET         | /oauth/v2/scopes/:id | Get scope by ID    |\r\n| POST        | /oauth/v2/scopes     | Create a new scope |\r\n| PUT         | /oauth/v2/scopes/:id | Edit a scope       |\r\n| DELETE      | /oauth/v2/scopes/:id | Delete a scope     |\r\n\r\nScope properties\r\n\r\n| Property Name | Type     | Optional | Description                                           |\r\n| ------------- | -------- | -------- | ----------------------------------------------------- |\r\n| name          | string   | false    | Name of the scope. String without space.              |\r\n| description   | string   | true     | Description of the scope                              |\r\n| parent        | ObjectId | true     | To better organize the scopes, some can have parents. |\r\n\r\nScope creation's body request example\r\n\r\n```json\r\n{\r\n    \"name\": \"edit:user\",\r\n    \"description\": \"Edit a user account\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Manage clients\r\n\r\nDevelopers building applications that need to interact with your application's API will need to register their application with yours by creating a \"client\".\r\n\r\n### Client endpoints\r\n\r\nSome endpoints are already provided with the package to manage clients:\r\n\r\n| HTTP Method | Route                 | Description         |\r\n| ----------- | --------------------- | ------------------- |\r\n| GET         | /oauth/v2/clients     | Get all clients     |\r\n| GET         | /oauth/v2/clients/:id | Get client by ID    |\r\n| POST        | /oauth/v2/clients     | Create a new client |\r\n| PUT         | /oauth/v2/clients/:id | Edit a client       |\r\n| DELETE      | /oauth/v2/clients/:id | Delete a client     |\r\n\r\n### Client properties\r\n\r\nTo respect Oauth 2 specifications some properties are needed for the client.\r\n\r\n| Property Name       | Type                                                         | Optional                                            | Description                                                  |\r\n| ------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------ |\r\n| clientId            | string                                                       | Generated                                           | Client ID                                                    |\r\n| name                | string                                                       | false                                               | Name of the application                                      |\r\n| domaine             | string                                                       | true                                                | Domaine name of the application                              |\r\n| logo                | string                                                       | true                                                | Link of the application logo                                 |\r\n| description         | string                                                       | true                                                | Description of the application                               |\r\n| secretKey           | string                                                       | generated                                           | Secret key of the client. It is only generated when the **clientType** value is **confidential**. |\r\n| internal            | boolean                                                      | false                                               | Set internal value to true for [First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications) and false for [Third-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications) |\r\n| grants              | array of values in **implicit**, **client_credentials**, **password**, **authorization_code** and **refresh_token** | Automatically filled based on data provides         | Allowed grants depends on whether the client is confidential or public, internal or external. |\r\n| redirectURIs        | array of URI                                                 | false                                               | After a user successfully authorizes an application, the server will redirect the user back to the application with either an authorization code or access token in the URL |\r\n| clientProfile       | **web**, **user-agent-based** or **native**                  | false                                               | **web** for web application, **user-agent-based** for user-agent based application, and **native** for native desktop or mobile application. |\r\n| clientType          | **confidential** or **public**                               | Automatically filled based on *clientProfile* value | A **confidential** client is a client who guarantees the confidentiality of credentials (Web application with a secure backend). A **public** client cannot hold credentials securely (native desktop or mobile application, user-agent-based application such as a single page app). |\r\n| programmingLanguage | string                                                       | true                                                | Language used to develop the application                     |\r\n| scope               | string                                                       | false                                               | Scope requested by the application (i.e. *\"read:users list:users add:users\"*) |\r\n\r\nOther client properties:\r\n\r\n* **legalTermsAcceptedAt** *(OPTIONAL)*: if some legal terms need to be accepted before consuming your API.\r\n* **revokedAt** *(OPTIONAL)*: filled when the client is revoked\r\n\r\n#### Revoke a client\r\n\r\nTo revoke a client, use the edit endpoint and send data as follow:\r\n\r\n```typescript\r\n{\r\n    // ... other fields\r\n    revoke: true // you can also end false in other to cancel revokation\r\n}\r\n```\r\n\r\n\r\n\r\n### Client types detailed\r\n\r\nOAuth defines two client types, based on their ability to authenticate securely with the authorization server.\r\n\r\n- **confidential**\r\n  - **Web application**: Application were views are generated from a server. The following list is not exhaustive.\r\n    - JavaScript - [Node.js](https://nodejs.org/) (Express)\r\n    - C# – [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet)\r\n    - Java – [Spring MVC](https://spring.io/), [Apache Struts](https://struts.apache.org/), [Play Framework](https://en.wikipedia.org/wiki/Play_Framework)\r\n    - Groovy – [Grails Framework](https://en.wikipedia.org/wiki/Grails_(framework))\r\n    - Python – [Django](https://www.djangoproject.com/)\r\n    - Ruby – [Ruby on Rails](https://rubyonrails.org/)\r\n    - PHP – [Laravel](https://laravel.com/)\r\n\r\n- **public**\r\n  - **Browser-based application**: Most of [SPA](https://en.wikipedia.org/wiki/Single-page_application) application based on Web browser JavaScript frameworks and libraries such as:\r\n    - AngularJs\r\n    - Ember.Js\r\n    - ExtJS\r\n    - [Meteor.js](https://en.wikipedia.org/wiki/Meteor_(web_framework))\r\n    - [React](https://en.wikipedia.org/wiki/React_(JavaScript_library)).js\r\n    - [Vue.js](https://en.wikipedia.org/wiki/Vue.js)\r\n  - **Native application**: software program that is developed for use on a particular platform or device\r\n    - Mobile applications: *Android, IOS and Windows phone*\r\n    - Desktop application: *Linux, windows, Mac OS*\r\n\r\n### Client example\r\n\r\nClient creation's request body example\r\n\r\n```typescript\r\n{\r\n    name: \"Cake Shop\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.cakeshop.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"read:users read:cake add:cakes\" // \"*\" is allowed only for internal client\r\n}\r\n```\r\n\r\n\r\n\r\n## Authorization Grants\r\n\r\nDepending on the type of customers who want to access your API, there are appropriate types of authentication.\r\n\r\n### Authorization Code Grant\r\n\r\nThe authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user’s web browser) and receiving API authorization codes that are routed through the user-agent.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n* Public and confidential web frontend application - *web app or browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. \r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step. \r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\", \r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\", // required only for confidential client\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Authorization Code Grant with PKCE\r\n\r\nThe Authorization Code grant with \"Proof Key for Code Exchange\" (PKCE) is a secure way to authenticate public client. You use it when there is not guarantee that the client client can store secret key confidentially.\r\n\r\nThis grant is based on a *\"code verifier\"* and a *\"code challenge\"*.\r\n\r\n**Code Verifier & Code Challenge**\r\n\r\nAs this authorization grant does not provide a client secret, developers will need to generate a combination of a code verifier and a code challenge in order to request a token.\r\n\r\nThe code verifier should be a random string of between 43 and 128 characters containing letters, numbers and \"-\", \".\", \"\\*\", \"~\", as defined in the RFC 7636 specification.\r\n\r\nThe code challenge should be a BASE64URL-ENCODE encoded string with URL and filename-safe characters. The trailing '=' characters should be removed and no line breaks, whitespace, or other additional characters should be present.\r\n\r\n**Creating The Client**\r\n\r\nTargeted applications:\r\n\r\n- Public web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: false,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application.\r\n\r\n1. **Get authorization codes**\r\n\r\n* HTTP Method: **GET**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/authorize**\r\n\r\n* Query parameters:\r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"code\",\r\n\tcode_challenge: \"generated-code-challenge\", // REQUIRED.  Code challenge.\r\n    code_challenge_method: \"S256\", // OPTIONAL, defaults to \"plain\" if not present in the request.  Code verifier transformation method is \"S256\" or \"plain\".\r\n    scope: \"\", // OPTIONAL\r\n    state: \"\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\nAfter sending this request, the client will be redirect to an authentication page. Once the end-user authenticated, he will be redirected to the provided *redirect_uri* with the authorization code.\r\n\r\nThe given authorization code will be used to request access token in the next step.\r\n\r\n2. **Converting Authorization Codes To Access Tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"authorization_code\",\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    code_verifier: \"codeVerifier\",\r\n    code: \"code\" // code previously received\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Authorization Code (With PKCE)** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Password Grant\r\n\r\nThe password grant allows confidential application to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire authorization code redirect flow.\r\n\r\nTargeted clients:\r\n\r\nThis grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if first-party applications (e.g. : applications in your organization).\r\n\r\n**Creating A Password Grant Client**\r\n\r\nThis grant is recommended for internal ([First-party applications](https://auth0.com/docs/applications/concepts/app-types-first-third-party#first-party-applications)) applications:\r\n\r\n- Public or confidential web frontend application - *web app or browser-based app*\r\n- Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for password grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"native\",\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Requesting Tokens**\r\n\r\nOnce a client has been created, developers may use their client ID and secret to request an access token from your application.\r\n\r\nThe consuming application should send client ID, secret key, username and password to your application's /oauth/v2/token endpoint.\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    grant_type: \"password\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    username: \"john.conor@sky.net\",\r\n    password: \"my-password\",\r\n    scope: \"\" // OPTIONAL\r\n}\r\n```\r\n\r\n\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Password Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Implicit Grant\r\n\r\nThe implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can't be securely stored.\r\n\r\nThe implicit grant type is used for mobile apps and web applications (*i.e. applications that run in a web browser*), where the client secret confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user’s device.\r\n\r\n**Creating An Implicit Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Public web frontend application - *browser-based app*\r\n* Native frontend application - *mobile* or desktop app\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true,\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"user-agent-based\",\r\n    scope: \"read:users list:users edit:users\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request tokens**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body: \r\n\r\n```typescript\r\n{\r\n    client_id: \"client-id\",\r\n    redirect_uri: \"http://example.com/callback\",\r\n    response_type: \"token\",\r\n    scope: \"\", // OPTIONAL\r\n    state: \"state\" // OPTIONAL but highly recommended\r\n}\r\n```\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token** and fill the form with the client data\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Implicit** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n### Client Credentials Grant\r\n\r\nThe client credentials grant is suitable for machine-to-machine authentication. Use it if you need for example two or more servers of your organization to communicate together.\r\n\r\nThe client credentials grant type provides an application a way to access its own service. Server to server communication in the same organization.\r\n\r\n**Creating An Client Credentials Grant Client**\r\n\r\nTargeted applications:\r\n\r\n* Confidential web application - *frontend or backend*\r\n\r\nRequest body example:\r\n\r\n```typescript\r\n{\r\n    name: \"App Name\",\r\n    internal: true, // must be true for client credentials grant\r\n    redirectURIs: [\"https://www.app_name.com/auth/callback\"],\r\n    clientProfile: \"web\", // must be web for client credentials grant\r\n    scope: \"*\"\r\n}\r\n```\r\n\r\n\r\n\r\n**Request token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"client_credentials\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n>\r\n\r\n\r\n\r\n**Try with [Postman](http://postman.com/)**  *(You can also try with other rest API client)*\r\n\r\n* Configure a single request\r\n  * Create a new request\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n* Configure a folder\r\n  * Right click on the folder and Click on **Edit**\r\n  * Select **Authorization** tab\r\n  * Select **Oauth 2.0** within the Type\r\n  * Click on **Get New Access Token**\r\n  * Select **Client Credentials** as `Grant Type` value\r\n  *  Fill the rest of the form with the data of the client that you created before\r\n\r\n## Refreshing Tokens\r\n\r\nToken generated with some grants as Password Credentials Grant and Authorization Code Grant, come with a refresh token that the user can use to get a new token as follow.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/token**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    grant_type: \"refresh_token\",\r\n    refresh_token: \"the-refresh-token\",\r\n    client_id: \"client-id\",\r\n    client_secret: \"client-secret\",\r\n    scope: \"client-requested-scope\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Revoke Token\r\n\r\nRefresh token and Access token can be revoked, In case you would like to disconnect a user.\r\n\r\n**Refresh token**\r\n\r\n* HTTP Method: **POST**\r\n\r\n* Endpoint: **{YOUR_API_BASE_URL}/oauth/v2/revoke**\r\n\r\n* Query body:\r\n\r\n```typescript\r\n{\r\n    token_type_hint?: \"refresh_token\", // or \"access_token\";\r\n  \ttoken: \"the-token\",\r\n  \tclient_id: \"client-id\", // OPTIONAL\r\n  \tclient_secret: \"client-secret\" // OPTIONAL\r\n}\r\n```\r\n\r\n> **Note**: _client_id_ and _client_secret_ can be sent via Basic authorization header and not in the request body.\r\n>\r\n> _Authorization: Basic {BASE64URL-ENCODE(client_id:client_secret)}_\r\n\r\n\r\n\r\n## Purging Tokens and Authorization codes\r\n\r\nThis package provide some endpoints to purge revoked or expired tokens and authorization codes.\r\n\r\n| Target                       | HTTP Method | Endpoint              |\r\n| ---------------------------- | ----------- | --------------------- |\r\n| Tokens                       | DELETE      | /oauth/v2/purge/token |\r\n| Authorization Codes          | DELETE      | /oauth/v2/purge/code  |\r\n| Tokens & Authorization Codes | DELETE      | /oauth/v2/purge       |\r\n\r\nBy default, all *expired* or *revoked* tokens or codes are purged, but you may want to delete only revoked tokens or only expired tokens. To do this, you can pass the `type` parameter to your request, which can respectively take the values **revoked** or **expired**.\r\n\r\nExample:\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/token?type=revoked**\r\n\r\n  Delete all revoked tokens\r\n\r\n* **DELETE: {YOUR_API_BASE_URL}/oauth/v2/purge/code**\r\n\r\n  Delete both revoked and expired authorization codes\r\n\r\n\r\n\r\n## Protecting Routes\r\n\r\n### Via Middleware. \r\n\r\nYou can secure your routes by adding the middleware `Oauth.authorize()`. It is a static method of the `Oauth` class provided by the package.\r\n\r\nMethod definition:\r\n\r\n```typescript\r\nOauth.authorize(scope?: string | undefined): (req: Request, res: Response, next: NextFunction) => Promise<Response<any> | undefined>\r\n```\r\n\r\nImport `Oauth` \r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// app is an express application or express router\r\napp.route('/account/update').put([\r\n    // ... other middleware\r\n    Oauth.authorize(), // oauth middleware. It must always be before the protected resource\r\n    // ... other middleware\r\n    authController.update // protected resource\r\n]);\r\n```\r\n\r\n### Verify a token manually\r\n\r\nIn some use cases, you can recover the access token on your own. There is a method that allows you to verify a token: `Oauth.verifyToken`.\r\n\r\n**Example**\r\n\r\n```typescript\r\nimport { Oauth } from \"@noreajs/oauth-v2-provider-me\";\r\n\r\n// Token example\r\nconst accessToken = \"euiaoejsjflsdfhoiuezioueiz.ieaoufisdfosdfusdfksdlkfjdkfjs.skdjflksdfjls\";\r\n\r\nOauth.verifyToken(accessToken, (userId, lookupData) => {\r\n\t// userId : current user id\r\n    // lookupData: current user data if the lookup method has been defined while initializing Oauth. \r\n    // lookupData is undefined for client_credentials grant\r\n    next();\r\n}, (reason: string, authError: boolean) => {\r\n    // reason: is the description of the error\r\n    if (authError) {\r\n        // Authorization error\r\n    } else {\r\n        // internal error (e.g. Oauth 2 Server has not been initialized yet)\r\n    }\r\n}, scope)\r\n\r\n```\r\n\r\n**Method prototype** (Typescript)\r\n\r\n```typescript\r\nOauth.verifyToken(token: string, success: (userId: string, lookupData?: any) => Promise<void> | void, error: (reason: string, authError: boolean) => Promise<void> | void, scope?: string | undefined): Promise<void>\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### Secure Oauth 2 endpoints\r\n\r\nWhile initializing the provider, there is a property called `securityMiddlewares`. Once your app if fully functional and ready for production you can secure Oauth 2 endpoints *(Client management endpoints, purge endpoints)*.\r\n\r\n`securityMiddlewares` initialization example\r\n\r\n```typescript\r\n{\r\n    // ... other initialization properties\r\n    securityMiddlewares: [\r\n        // other middlewares\r\n        Oauth.authorize('create:clients list:clients purge:tokens purge:codes'),\r\n        // other middlewares\r\n    ],\r\n    // ... other initialization properties\r\n}\r\n```\r\n\r\n\r\n\r\n### Checking Scopes\r\n\r\nThe scope(s) required for a resource can be passed via the `Oauth.authorize` method as follow:\r\n\r\n```typescript\r\napp.route('/account/update').put([\r\n    Oauth.authorize('edit:profile'),\r\n    authController.update\r\n]);\r\n```\r\n\r\n**Note** : Many scopes can be transmitted by separating them with a space.\r\n\r\n\r\n\r\n## Mongoose Models\r\n\r\nThe Mongoose models used by the package are accessible. You can use them as you wish.\r\n\r\n| Model Name        | Collection Name      | Description                |\r\n| ----------------- | -------------------- | -------------------------- |\r\n| OauthAccessToken  | oauth_access_tokens  | Manage access tokens       |\r\n| OauthAuthCode     | oauth_auth_codes     | Manage authorization codes |\r\n| OauthClient       | oauth_clients        | Manage clients             |\r\n| OauthRefreshToken | oauth_refresh_tokens | Manage refresh tokens      |\r\n| OauthScope        | oauth_scopes         | Manage scopes              |\r\n\r\nYou can import these models as follows:\r\n\r\n``` typescript\r\nimport { /* model_name*/ } from \"@noreajs/oauth-v2-provider-me\"\r\n```\r\n\r\n\r\n\r\n## Consuming Your API With JavaScript ([axios](https://github.com/axios/axios))","readmeFilename":"README.md"}