{"id":15013433,"url":"https://github.com/leaonline/oauth2-server","last_synced_at":"2025-04-12T04:44:22.026Z","repository":{"id":37720504,"uuid":"202368067","full_name":"leaonline/oauth2-server","owner":"leaonline","description":"OAuth 2 Server package for Meteor to create your own OAuth 2 authorization server. Zero config. Uses continuous updated @node-oauth/oauth2-server library","archived":false,"fork":false,"pushed_at":"2025-03-21T10:41:21.000Z","size":420,"stargazers_count":21,"open_issues_count":12,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-21T11:29:07.109Z","etag":null,"topics":["authorization-code-grant","authorization-server","hacktoberfest","meteor","meteorjs","nodejs","oauth2"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"RocketChat/rocketchat-oauth2-server","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leaonline.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-14T14:33:31.000Z","updated_at":"2025-03-21T10:41:28.000Z","dependencies_parsed_at":"2024-03-14T10:30:24.270Z","dependency_job_id":"7b5051d4-a49c-48cc-a96d-229c01409e51","html_url":"https://github.com/leaonline/oauth2-server","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leaonline%2Foauth2-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leaonline%2Foauth2-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leaonline%2Foauth2-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leaonline%2Foauth2-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leaonline","download_url":"https://codeload.github.com/leaonline/oauth2-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248519468,"owners_count":21117757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authorization-code-grant","authorization-server","hacktoberfest","meteor","meteorjs","nodejs","oauth2"],"created_at":"2024-09-24T19:44:16.350Z","updated_at":"2025-04-12T04:44:21.996Z","avatar_url":"https://github.com/leaonline.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Meteor OAuth2 Server\n\n[![Test suite](https://github.com/leaonline/oauth2-server/actions/workflows/tests.yml/badge.svg)](https://github.com/leaonline/oauth2-server/actions/workflows/tests.yml)\n[![CodeQL](https://github.com/leaonline/oauth2-server/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/leaonline/oauth2-server/actions/workflows/codeql-analysis.yml)\n[![built with Meteor](https://img.shields.io/badge/Meteor-package-green?logo=meteor\u0026logoColor=white)](https://atmospherejs.com/leaonline/oauth2-server)\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)\n![GitHub](https://img.shields.io/github/license/leaonline/oauth2-server)\n[![DOI](https://zenodo.org/badge/202368067.svg)](https://zenodo.org/doi/10.5281/zenodo.10817036)\n\n\nThis package is a implementation of the package\n[@node-oauth/oauth2-server](https://github.com/node-oauth/node-oauth2-server) \nfor Meteor.\nIt can run without `express` (we use Meteor's builtin `WebApp`) and implements \nthe `authorization_code` workflow and works like the Facebook's OAuth popup.\n\n## Changelog\n\nView the full changelog in the [history page](./HISTORY.md).\n\n## Install\n\nThis package is a full scale drop-in, so you just need to add it via\n\n```bash\n$ meteor add leaonline:oauth2-server\n```\n\n## Implementation\n\nThe package comes with a default config, so you can start immediately.\nHowever, we made it all configurable for you.\n\nYou can change various flags, routes and expiration times and collection names.\nThe following sections will show you how to setup the server with a full\nconfiguration.\n\n### Server implementation\n\nThe following example uses the full configuration.\nThe used values represent the current default values.\n\n`server/oauth2server.js`\n```javascript\nimport { Meteor } from \"meteor/meteor\"\nimport { OAuth2Server } from 'meteor/leaonline:oauth2-server'\n\nconst oauth2server = new OAuth2Server({\n  serverOptions: {\n    addAcceptedScopesHeader: true,\n    addAuthorizedScopesHeader: true,\n    allowBearerTokensInQueryString: false,\n    allowEmptyState: false,\n    authorizationCodeLifetime: 300,\n    accessTokenLifetime: 3600,\n    refreshTokenLifetime: 1209600,\n    allowExtendedTokenAttributes: false,\n    requireClientAuthentication: true\n  },\n  model: {\n    accessTokensCollectionName: 'oauth_access_tokens',\n    refreshTokensCollectionName: 'oauth_refresh_tokens',\n    clientsCollectionName: 'oauth_clients',\n    authCodesCollectionName: 'oauth_auth_codes',\n    debug: true\n  },\n  routes: {\n    accessTokenUrl: '/oauth/token',\n    authorizeUrl: '/oauth/authorize',\n    errorUrl: '/oauth/error',\n    fallbackUrl: '/oauth/*'\n  }\n})\n\n// this is a \"secret\" route that is only accessed with\n// a valid token, which has been generated \n// by the authorization_code grant flow\n// You will have to implement it to allow your remote apps\n// to retrieve the user credentials after successful\n// authentication.\noauth2server.authenticatedRoute().get('/oauth/ident', function (req, res, next) {\n  const user = Meteor.users.findOne(req.data.user.id)\n\n  res.writeHead(200, {\n    'Content-Type': 'application/json',\n  })\n  const body = JSON.stringify({\n    id: user._id,\n    login: user.username,\n    email: user.emails[0].address,\n    firstName: user.firstName,\n    lastName: user.lastName,\n    name: `${user.firstName} ${user.lastName}`\n  })\n  res.end(body)\n})\n\n// create some fallback for all undefined routes\noauth2server.app.use('*', function (req, res, next) {\n  res.writeHead(404)\n  res.end('route not found')\n})\n```\n\n### Additional validation\n\nOften, you want to restrict who of your users can access which client / service.\nIn order to decide to give permission or not, you can register a handler that\nreceives the authenticated user and the client she aims to access:\n\n```javascript\noauth2server.validateUser(function({ user, client }) {\n  // the following example uses alanning:roles to check, whether a user\n  // has been assigned a role that indicates she can access the client.\n  // It is up to you how you implement this logic. If all users can access\n  // all registered clients, you can simply omit this call at all.\n  const { clientId } = client\n  const { _id } = user\n  \n  return Roles.userIsInRoles(_id, 'manage-app', clientId)\n})\n```\n\n\n\n### Client/Popup implementation\n\nYou should install a router to handle client side routing independently \nfrom the WebApp routes. You can for example use:\n\n```bash\n$ meteor add ostrio:flow-router-extra\n```\n\nand then define a client route for your popup dialog (we use Blaze in this example\nbut it will work with any of your preferred and loved frontends):\n\n`client/main.html`\n```javascript\n\u003chead\u003e\n    \u003ctitle\u003eauthserver\u003c/title\u003e\n\u003c/head\u003e\n\n\u003ctemplate name=\"layout\"\u003e\n    {{\u003e yield}}\n\u003c/template\u003e\n```\n\n`client/main.js`\n```javascript\nimport { FlowRouter } from 'meteor/ostrio:flow-router-extra'\nimport './authorize.html'\nimport './authorize'\nimport './main.html'\n\n// Define the route to render the popup view\nFlowRouter.route('/dialog/oauth', {\n  action: function (params, queryParams) {\n    this.render('layout', 'authorize', queryParams)\n  }\n})\n```\n\n`client/authorize.js`\n```javascript\n// Subscribe the list of already authorized clients\n// to auto accept\nTemplate.authorize.onCreated(function() {\n  this.subscribe('authorizedOAuth');\n});\n\n// Get the login token to pass to oauth\n// This is the best way to identify the logged user\nTemplate.authorize.helpers({\n  getToken: function() {\n    return localStorage.getItem('Meteor.loginToken');\n  }\n});\n\n// Auto click the submit/accept button if user already\n// accepted this client\nTemplate.authorize.onRendered(function() {\n  var data = this.data;\n  this.autorun(function(c) {\n    var user = Meteor.user();\n    if (user \u0026\u0026 user.oauth \u0026\u0026 user.oauth.authorizedClients \u0026\u0026 user.oauth.authorizedClients.indexOf(data.client_id()) \u003e -1) {\n      c.stop();\n      $('button').click();\n    }\n  });\n});\n```\n\n`client/authorize.html`\n```html\n\u003ctemplate name=\"authorize\"\u003e\n  {{#if currentUser}}\n    \u003cform method=\"post\" action=\"{{redirect_uri}}\" role=\"form\" class=\"{{#unless Template.subscriptionsReady}}hidden{{/unless}}\"\u003e\n      \u003ch2\u003eAuthorise\u003c/h2\u003e\n      \u003cinput type=\"hidden\" name=\"allow\" value=\"yes\"\u003e\n      \u003cinput type=\"hidden\" name=\"token\" value=\"{{getToken}}\"\u003e\n      \u003cinput type=\"hidden\" name=\"client_id\" value=\"{{client_id}}\"\u003e\n      \u003cinput type=\"hidden\" name=\"redirect_uri\" value=\"{{redirect_uri}}\"\u003e\n      \u003cinput type=\"hidden\" name=\"response_type\" value=\"code\"\u003e\n      \u003cbutton type=\"submit\"\u003eAuthorise\u003c/button\u003e\n    \u003c/form\u003e\n    {{#unless Template.subscriptionsReady}}\n      loading...\n    {{/unless}}\n  {{else}}\n    {{\u003e loginButtons}}\n  {{/if}}\n\u003c/template\u003e\n```\n\n`client/style.css`\n```css\n.hidden {\n  display: none;\n}\n```\n\n## API and Documentation\n\nWe also have an [API documentation](./API.md) with further info on the \npackage internals.\n\nFurthermore we suggest you to consult the RFC docs on OAuth2:\n\n- [RFC 6749 -  The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749.html)\n- [RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://datatracker.ietf.org/doc/html/rfc6750.html)\n\n## Testing\n\nWe use mocha with `meteortesting:mocha` to run the tests. \nWe have now a full scale test project inside this one and you can use it \nextensively to lint and test this project.\n\n### Setup\n\nThe setup is already prepared, so you just need to run a few commands:\n\n```bash\n$ cd test-proxy\n$ meteor npm install # install npm dependencies\n$ meteor npm run setup # link with package\n```\n\n### Run the linter\n\nAfter the setup from the previous section you can run the linter via\n\n```bash\n$ meteor npm run lint\n```\n\nor auto-fix code via\n\n```bash\n$ meteor npm run lint:fix\n```\n\nNote, that we use `standardx`, which is `standard` code style with a few extra\ntweaks. We also use `eslint-plugin-security`, which can sometimes create lots\nof false-positives. If you need assistance, feel free to create an issue.\n\n### Run the tests\n\nAfter the setup from the previous section you can run the tests via\n\n```bash\n$ meteor npm run test\n```\n\nor in watch mode via\n\n```bash\n$ meteor npm run test:watch\n```\n\nor with coverage report (+ watch mode) via\n\n```bash\n$ meteor npm run test:coverage\n```\n\n### Build the docs\n\nWe use jsDoc and jsdoc2md to create a markdown file. To build the docs use\n\n```bash\n$ meteor npm run build:docs\n```\n\n## License\n\nMIT, see [license file](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleaonline%2Foauth2-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleaonline%2Foauth2-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleaonline%2Foauth2-server/lists"}