├── .gitignore
├── examples
├── clientApplication
│ ├── .gitignore
│ ├── .meteor
│ │ ├── .gitignore
│ │ ├── release
│ │ ├── platforms
│ │ ├── .id
│ │ ├── .finished-upgraders
│ │ ├── packages
│ │ └── versions
│ ├── packages
│ │ └── meteor-oauth2-client
│ ├── client
│ │ ├── index.css
│ │ ├── configFormFixes.js
│ │ ├── index.js
│ │ └── index.html
│ ├── README.md
│ ├── LICENSE.txt
│ └── server
│ │ └── index.js
├── resourceServer
│ ├── .gitignore
│ ├── .meteor
│ │ ├── .gitignore
│ │ ├── release
│ │ ├── platforms
│ │ ├── .id
│ │ ├── .finished-upgraders
│ │ ├── packages
│ │ └── versions
│ ├── packages
│ │ └── meteor-oauth2-server
│ ├── client
│ │ ├── index.css
│ │ ├── index.js
│ │ └── index.html
│ ├── README.md
│ ├── server
│ │ ├── methods.js
│ │ └── rest.js
│ └── LICENSE.txt
└── README.md
├── packages
├── meteor-oauth2-server
│ ├── .gitignore
│ ├── .versions
│ ├── package.js
│ ├── client.js
│ ├── LICENSE.txt
│ ├── common.js
│ ├── README.md
│ ├── server.js
│ └── meteor-model.js
└── meteor-oauth2-client
│ ├── meteor_configure.js
│ ├── meteor_common.js
│ ├── meteor_configure.html
│ ├── LICENSE
│ ├── package.js
│ ├── .versions
│ ├── meteor_client.js
│ ├── README.md
│ └── meteor_server.js
├── documentation
├── OAuthWebSequence.png
└── OAuthWebSequenceWithConfig.png
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .npm
2 |
--------------------------------------------------------------------------------
/examples/clientApplication/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
--------------------------------------------------------------------------------
/examples/resourceServer/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.2.1
2 |
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.2.1
2 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-server/.gitignore:
--------------------------------------------------------------------------------
1 | .npm
2 | .idea
3 |
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/platforms:
--------------------------------------------------------------------------------
1 | server
2 | browser
3 |
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/platforms:
--------------------------------------------------------------------------------
1 | server
2 | browser
3 |
--------------------------------------------------------------------------------
/examples/resourceServer/packages/meteor-oauth2-server:
--------------------------------------------------------------------------------
1 | ../../../packages/meteor-oauth2-server
--------------------------------------------------------------------------------
/examples/clientApplication/packages/meteor-oauth2-client:
--------------------------------------------------------------------------------
1 | ../../../packages/meteor-oauth2-client/
--------------------------------------------------------------------------------
/examples/resourceServer/client/index.css:
--------------------------------------------------------------------------------
1 | .section {
2 | padding-left: 2em;
3 | padding-right: 2em;
4 | }
--------------------------------------------------------------------------------
/examples/clientApplication/client/index.css:
--------------------------------------------------------------------------------
1 | .section {
2 | padding-left: 2em;
3 | padding-right: 2em;
4 | }
--------------------------------------------------------------------------------
/documentation/OAuthWebSequence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prime-8-consulting/meteor-oauth2/HEAD/documentation/OAuthWebSequence.png
--------------------------------------------------------------------------------
/documentation/OAuthWebSequenceWithConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prime-8-consulting/meteor-oauth2/HEAD/documentation/OAuthWebSequenceWithConfig.png
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | ba5i7g1ib6dam3006bh
8 |
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | okjv8s177qxaw1qvqjsj
8 |
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 | 1.2.0-standard-minifiers-package
10 | 1.2.0-meteor-platform-split
11 | 1.2.0-cordova-changes
12 | 1.2.0-breaking-changes
13 |
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 | 1.2.0-standard-minifiers-package
10 | 1.2.0-meteor-platform-split
11 | 1.2.0-cordova-changes
12 | 1.2.0-breaking-changes
13 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-client/meteor_configure.js:
--------------------------------------------------------------------------------
1 | Template.configureLoginServiceDialogForMeteorOAuth2Server.base_url = function () {
2 | return Meteor.absoluteUrl();
3 | };
4 |
5 | Template.configureLoginServiceDialogForMeteorOAuth2Server.fields = function () {
6 | return [
7 | { property: 'clientId', label: 'API Key (Client ID)' },
8 | { property: 'secret', label: 'Secret Key' },
9 | { property: 'baseUrl', label: 'Target Base URL' },
10 | { property: 'loginUrl', label: 'Target Login URL' }
11 | ];
12 | };
13 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | This is our directory of examples.
2 |
3 | ## resourceServer
4 | This is an example of using the meteor-oauth2-server package. If you want to make your meteor
5 | application provide oauth services to other site, this should be your reference porint. This
6 | application is also used as a test application to ensure the meteor-oauth2-server package is
7 | functioning properly.
8 |
9 | ## clientApplication
10 | This is an example of using the meteor-oauth2-client package. If you want users to authenticate from
11 | a meteor application that is running the meteor-oauth2-server package, this should be your reference
12 | point. This application assumes you will have the resourceServer application running.
13 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-server/.versions:
--------------------------------------------------------------------------------
1 | babel-compiler@5.8.24_1
2 | babel-runtime@0.1.4
3 | base64@1.0.4
4 | blaze@2.1.3
5 | blaze-tools@1.0.4
6 | boilerplate-generator@1.0.4
7 | check@1.1.0
8 | deps@1.0.9
9 | diff-sequence@1.0.1
10 | ecmascript@0.1.6
11 | ecmascript-runtime@0.2.6
12 | ejson@1.0.7
13 | html-tools@1.0.5
14 | htmljs@1.0.5
15 | id-map@1.0.4
16 | jquery@1.11.4
17 | local-test:prime8consulting:meteor-oauth2-server@0.0.3
18 | logging@1.0.8
19 | meteor@1.1.10
20 | meteorhacks:async@1.0.0
21 | mongo-id@1.0.1
22 | observe-sequence@1.0.7
23 | prime8consulting:meteor-oauth2-server@0.0.3
24 | promise@0.5.1
25 | random@1.0.5
26 | reactive-var@1.0.6
27 | routepolicy@1.0.6
28 | simple:json-routes@2.1.0
29 | spacebars@1.0.7
30 | spacebars-compiler@1.0.7
31 | tracker@1.0.9
32 | ui@1.0.8
33 | underscore@1.0.4
34 | webapp@1.2.3
35 | webapp-hashing@1.0.5
36 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-client/meteor_common.js:
--------------------------------------------------------------------------------
1 | if (_.isUndefined(MeteorOAuth2)) {
2 | MeteorOAuth2 = {
3 | serviceName: 'MeteorOAuth2Server'
4 | };
5 | }
6 |
7 | Accounts.oauth.registerService(MeteorOAuth2.serviceName);
8 |
9 | if (Meteor.isClient) {
10 | Meteor['loginWith'+ MeteorOAuth2.serviceName] = function(options, callback) {
11 | if (! callback && typeof options === "function") {
12 | callback = options;
13 | options = null;
14 | }
15 |
16 | var credentialRequestCompleteCallback = Accounts.oauth.credentialRequestCompleteHandler(callback);
17 | MeteorOAuth2.requestCredential(options, credentialRequestCompleteCallback);
18 | };
19 | } else {
20 | Accounts.addAutopublishFields({
21 | forLoggedInUser: ['services.'+ MeteorOAuth2.serviceName],
22 | forOtherUsers: []
23 | });
24 | }
--------------------------------------------------------------------------------
/examples/clientApplication/README.md:
--------------------------------------------------------------------------------
1 | ## Client Application
2 |
3 | This example is used to test and demonstrate the meteor-oauth2-client package
4 | and it's interaction with a meteor service running the
5 | meteor-oauth2-server package. This example expects that the resourceServer
6 | application is also running. Check the example directory for details.
7 |
8 | =========================================
9 | #### Installation
10 |
11 | Starting:
12 | ``` sh
13 | meteor --port 3200
14 | ```
15 | After it is started, goto http://localhost:3200 and walk through the steps.
16 |
17 | The reason we are using a specific port here is to:
18 | 1. Not interfere with your running instance of meteor.
19 | 2. Work well with the resourceServer example as it assumes this application
20 | will be hosted at localhost:3200
21 |
22 | =========================================
23 | #### Licensing
24 |
25 | 
26 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-client/meteor_configure.html:
--------------------------------------------------------------------------------
1 |
2 |
8 | If you operate the AuthenticationServer, you can add a client by directly editing it's database. In a production environment, this entry would be generated by an admin console or a client API Key Request Page. If you do not operate the resource owner, then you must contact the service in some way to get the keys.
9 |
13 | Configure the ClientApplication by entering the ClientID in this form. Each meteor site operates differently, so there is not unified API website to goto. The AuthenticationServer will need the following a Redirect URI:
14 | Configure the ClientApplication
3 |
4 |
5 |
6 | Step C1
7 | Step C2
12 |
17 |
19 |
20 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-server/package.js:
--------------------------------------------------------------------------------
1 | Package.describe({
2 | name: 'prime8consulting:meteor-oauth2-server',
3 | version: '0.0.3',
4 | summary: 'Add oauth2 server support to your application.',
5 | git: 'https://github.com/prime-8-consulting/meteor-oauth2/packages/meteor-oauth2-server'
6 | });
7 |
8 | Package.onUse(function(api) {
9 | api.versionsFrom('1.0');
10 |
11 | api.use('webapp', 'server');
12 | api.use('check', 'server');
13 | api.use('meteorhacks:async@1.0.0', 'server');
14 | api.use('simple:json-routes@2.1.0', 'server');
15 |
16 | api.addFiles('common.js', ['client', 'server']);
17 | api.addFiles('meteor-model.js', 'server');
18 | api.addFiles('server.js', 'server');
19 | api.addFiles('client.js', 'client');
20 |
21 | api.export('oAuth2Server', ['client', 'server']);
22 | });
23 |
24 | Npm.depends({
25 | "express": "4.13.4",
26 | "body-parser": "1.14.2",
27 | "oauth2-server": "2.4.1"
28 | });
29 |
30 | Package.onTest(function(api) {
31 |
32 | });
33 |
--------------------------------------------------------------------------------
/examples/resourceServer/README.md:
--------------------------------------------------------------------------------
1 | ## ResourceServer
2 |
3 | This example is used to test the meteor-oauth2-server package.
4 | It can also be used as a demonstration of how to integrate oauth2
5 | into your own application. The code is well documented, so it should
6 | be fairly easy to follow and implement your own solution. Pay
7 | particular attention to server/rest.js and client/index.js for how
8 | to create authorization codes and use access tokens in a rest service.
9 |
10 | =========================================
11 | #### Installation
12 |
13 | Starting:
14 |
15 | ``` sh
16 | meteor --port 3100
17 | ```
18 | After it is started, goto http://localhost:3100 and walk through the steps.
19 |
20 | The reason we are using a specific port here is to:
21 | 1. Not interfere with your running instance of meteor.
22 | 2. Work well with the clientApplication example as it assumes the resourceServer
23 | will be hosted at localhost:3100
24 |
25 | =========================================
26 | #### Licensing
27 |
28 | 
29 |
--------------------------------------------------------------------------------
/examples/resourceServer/server/methods.js:
--------------------------------------------------------------------------------
1 | Meteor.methods({
2 | /**
3 | * OAUTH FLOW - Step C1.1
4 | * While you are not required to implement client addition in the same way, clients will have
5 | * to be available for the oauth2 process to work properly. That may mean running code on
6 | * Meteor.startup() to populate the db.
7 | * @param client
8 | */
9 | 'addClient': function (client){
10 | console.log('addClient', client);
11 | oAuth2Server.collections.client.upsert(
12 | {
13 | clientId: client.clientId
14 | },
15 | {
16 | $set: client
17 | }
18 | );
19 | },
20 |
21 | /**
22 | * Exists purely for testing purposes.
23 | * @returns {any}
24 | */
25 | 'clientCount': function() {
26 | return oAuth2Server.collections.client.find({}).count();
27 | },
28 |
29 | /**
30 | * Exists purely for testing purposes.
31 | */
32 | 'deleteAllClients': function() {
33 | oAuth2Server.collections.client.remove({});
34 | }
35 | });
36 |
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | # Check this file (and the other files in this directory) into your repository.
3 | #
4 | # 'meteor add' and 'meteor remove' will edit this file for you,
5 | # but you can also edit it by hand.
6 |
7 | meteor-base # Packages every Meteor app needs to have
8 | mobile-experience # Packages for a great mobile UX
9 | mongo # The database Meteor supports right now
10 | blaze-html-templates # Compile .html files into Meteor Blaze views
11 | session # Client-side reactive dictionary for your app
12 | jquery # Helpful client-side library
13 | tracker # Meteor's client-side reactive programming library
14 |
15 | standard-minifiers # JS/CSS minifiers run for production mode
16 | es5-shim # ECMAScript 5 compatibility for older browsers.
17 | ecmascript # Enable ECMAScript2015+ syntax in app code
18 |
19 | accounts-ui
20 | accounts-password
21 | reactive-var
22 | prime8consulting:meteor-oauth2-server
23 | http
24 | simple:json-routes
--------------------------------------------------------------------------------
/packages/meteor-oauth2-server/client.js:
--------------------------------------------------------------------------------
1 | oAuth2Server.subscribeTo = {
2 | authCode: function() {
3 | return Meteor.subscribe(oAuth2Server.pubSubNames.authCodes);
4 | },
5 | refreshTokens: function() {
6 | return Meteor.subscribe(oAuth2Server.pubSubNames.refreshTokens);
7 | }
8 | };
9 |
10 | oAuth2Server.callMethod = {
11 | /**
12 | *
13 | * @param client_id : string - The client id.
14 | * @param redirect_uri : string - The Uri to goto after processing.
15 | * @param response_type : string - Oauth response type.
16 | * @param scope : string[] - An array of scopes.
17 | * @param state : string - A state variable provided by the client. It will be added onto the redirectToUri.
18 | * @param callback
19 | */
20 | authCodeGrant: function(client_id, redirect_uri, response_type, scope, state, callback) {
21 | Meteor.call(
22 | oAuth2Server.methodNames.authCodeGrant,
23 | client_id,
24 | redirect_uri,
25 | response_type,
26 | scope,
27 | state,
28 | callback
29 | );
30 | }
31 | };
32 |
33 |
--------------------------------------------------------------------------------
/examples/clientApplication/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Prime 8 Consulting
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/examples/resourceServer/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Prime 8 Consulting
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/packages/meteor-oauth2-client/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Prime 8 Consulting
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/packages/meteor-oauth2-server/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Prime 8 Consulting
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/packages/meteor-oauth2-client/package.js:
--------------------------------------------------------------------------------
1 | Package.describe({
2 | name: 'prime8consulting:meteor-oauth2-client',
3 | version: '0.0.2',
4 | summary: 'Add support for logging into a meteor site running the meteor-oauth2-server package.',
5 | git: 'https://github.com/prime-8-consulting/meteor-oauth2/packages/meteor-oauth2-client'
6 | });
7 |
8 | Package.onUse(function(api) {
9 | api.versionsFrom('1.0');
10 |
11 | api.use('accounts-base', ['client', 'server']);
12 | api.use('accounts-oauth', ['client', 'server']);
13 | api.use('oauth', ['client', 'server']);
14 | api.use('oauth2', ['client', 'server']);
15 | api.use('http', ['client', 'server']);
16 | api.use('service-configuration', ['client', 'server']);
17 | api.use('underscore', ['client', 'server']);
18 | api.use(['random', 'templating@1.0.11'], 'client');
19 |
20 | api.addFiles([
21 | 'meteor_configure.html',
22 | 'meteor_configure.js'
23 | ], 'client');
24 |
25 | api.addFiles('meteor_common.js', ['client', 'server']);
26 | api.addFiles('meteor_server.js', 'server');
27 | api.addFiles('meteor_client.js', 'client');
28 |
29 | api.export('MeteorOAuth2');
30 | });
31 |
32 | Package.onTest(function(api) {
33 |
34 | });
35 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-server/common.js:
--------------------------------------------------------------------------------
1 | refreshTokensCollection = new Meteor.Collection('OAuth2RefreshTokens');
2 | refreshTokensCollection.allow({
3 | insert: function(userId, doc) {
4 | return Meteor.isServer && userId && userId === doc.userId;
5 | },
6 | update: function(userId, doc, fieldNames, modifier) {
7 | return false;
8 | },
9 | remove: function(userId, doc) {
10 | return userId && userId === doc.userId;
11 | }
12 | });
13 |
14 | authCodesCollection = new Meteor.Collection('OAuth2AuthCodes');
15 | authCodesCollection.allow({
16 | insert: function(userId, doc) {
17 | return Meteor.isServer && userId && userId === doc.userId;
18 | },
19 | update: function(userId, doc, fieldNames, modifier) {
20 | return false;
21 | },
22 | remove: function(userId, doc) {
23 | return userId && userId === doc.userId;
24 | }
25 | });
26 |
27 | oAuth2Server = {
28 | pubSubNames: {
29 | authCodes: 'oauth2/authCodes',
30 | refreshTokens: 'oauth2/refreshTokens'
31 | },
32 | methodNames: {
33 | authCodeGrant: 'oauth2/authCodeGrant'
34 | },
35 | collections: {
36 | refreshToken: refreshTokensCollection,
37 | authCode: authCodesCollection
38 | }
39 | };
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | # Check this file (and the other files in this directory) into your repository.
3 | #
4 | # 'meteor add' and 'meteor remove' will edit this file for you,
5 | # but you can also edit it by hand.
6 |
7 | meteor-base # Packages every Meteor app needs to have
8 | mobile-experience # Packages for a great mobile UX
9 | mongo # The database Meteor supports right now
10 | blaze-html-templates # Compile .html files into Meteor Blaze views
11 | session # Client-side reactive dictionary for your app
12 | jquery # Helpful client-side library
13 | tracker # Meteor's client-side reactive programming library
14 |
15 | standard-minifiers # JS/CSS minifiers run for production mode
16 | es5-shim # ECMAScript 5 compatibility for older browsers.
17 | ecmascript # Enable ECMAScript2015+ syntax in app code
18 |
19 | autopublish # Publish all data to the clients (for prototyping)
20 | insecure # Allow all DB writes from clients (for prototyping)
21 | prime8consulting:meteor-oauth2-client
22 | service-configuration
23 | accounts-ui
24 | oauth
25 | reactive-var
26 | http
27 | webapp
28 |
--------------------------------------------------------------------------------
/examples/clientApplication/server/index.js:
--------------------------------------------------------------------------------
1 | Meteor.methods({
2 | /**
3 | * Convenience method for clearing out the service configuration. This should never exist in production.
4 | */
5 | resetServiceConfiguration: function() {
6 | ServiceConfiguration.configurations.remove({
7 | service: MeteorOAuth2.serviceName // using the constant provided by the package, easy for refactoring.
8 | });
9 | },
10 |
11 | /**
12 | * AUTH FLOW - Step A7.
13 | * We have an access token. Get the user from the REST service.
14 | * This will perform a server-to-server request for the identification of the user. This method
15 | * is not one you will need to implement as the oauth2 client package does this for you. We are
16 | * doing it here to demonstrate each step of the oauth2 process.
17 | */
18 | getUserId: function() {
19 | var user = Meteor.user();
20 | var serviceConfig = ServiceConfiguration.configurations.findOne({
21 | service: MeteorOAuth2.serviceName
22 | });
23 |
24 |
25 | return HTTP.get(
26 | serviceConfig.baseUrl + '/api/getUserId',
27 | {
28 | params: {
29 | access_token: user.services.MeteorOAuth2Server.accessToken
30 | }
31 | }
32 | );
33 | }
34 | });
35 |
--------------------------------------------------------------------------------
/packages/meteor-oauth2-client/.versions:
--------------------------------------------------------------------------------
1 | accounts-base@1.2.2
2 | accounts-oauth@1.1.8
3 | babel-compiler@5.8.24_1
4 | babel-runtime@0.1.4
5 | base64@1.0.4
6 | binary-heap@1.0.4
7 | blaze@2.1.3
8 | blaze-tools@1.0.4
9 | boilerplate-generator@1.0.4
10 | caching-compiler@1.0.0
11 | caching-html-compiler@1.0.2
12 | callback-hook@1.0.4
13 | check@1.1.0
14 | ddp@1.2.2
15 | ddp-client@1.2.1
16 | ddp-common@1.2.2
17 | ddp-rate-limiter@1.0.0
18 | ddp-server@1.2.2
19 | deps@1.0.9
20 | diff-sequence@1.0.1
21 | ecmascript@0.1.6
22 | ecmascript-runtime@0.2.6
23 | ejson@1.0.7
24 | geojson-utils@1.0.4
25 | html-tools@1.0.5
26 | htmljs@1.0.5
27 | http@1.1.1
28 | id-map@1.0.4
29 | jquery@1.11.4
30 | local-test:prime8consulting:meteor-oauth2-client@0.0.2
31 | localstorage@1.0.5
32 | logging@1.0.8
33 | meteor@1.1.10
34 | minifiers@1.1.7
35 | minimongo@1.0.10
36 | mongo@1.1.3
37 | mongo-id@1.0.1
38 | npm-mongo@1.4.39_1
39 | oauth@1.1.6
40 | oauth2@1.1.5
41 | observe-sequence@1.0.7
42 | ordered-dict@1.0.4
43 | prime8consulting:meteor-oauth2-client@0.0.2
44 | promise@0.5.1
45 | random@1.0.5
46 | rate-limit@1.0.0
47 | reactive-var@1.0.6
48 | reload@1.1.4
49 | retry@1.0.4
50 | routepolicy@1.0.6
51 | service-configuration@1.0.5
52 | spacebars@1.0.7
53 | spacebars-compiler@1.0.7
54 | templating@1.1.5
55 | templating-tools@1.0.0
56 | tracker@1.0.9
57 | ui@1.0.8
58 | underscore@1.0.4
59 | url@1.0.5
60 | webapp@1.2.3
61 | webapp-hashing@1.0.5
62 |
--------------------------------------------------------------------------------
/examples/resourceServer/server/rest.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This is an example where we use the oAuth2 server to allow/deny access to our REST service.
3 | * In this example, we will use JsonRoutes.
4 | */
5 |
6 | /**
7 | * First we define the middle-ware to use. This ensures the oauth2 server validation code
8 | * is ran whenever /api/* is accessed from our server. Doing this let's your rest service
9 | * take full advantage of oauth2 without all the boiler plate.
10 | * It is expected whenever a /api url is called, a "access_token" is present in the
11 | * query or the body.
12 | */
13 | JsonRoutes.Middleware.use(
14 | '/api/*',
15 | oAuth2Server.oauthserver.authorise() // OAUTH FLOW - A7.1
16 | );
17 |
18 | /**
19 | * OAUTH FLOW - A7.2
20 | *
21 | * Here is an example of querying for and returning data. At this point, the api path
22 | * has been validated by the oAuth2 server package. So the code can execute
23 | * un-encumbered.
24 | * Note: this is a REST service and it can be called from any server any where. That
25 | * being said, this server has no concept if your user is authenticated or not. This
26 | * is the point of the "access_token". To get the userId, you will have to look it up
27 | * in the access token collection.
28 | */
29 | JsonRoutes.add('get', '/api/getUserId', function(req, res, next) {
30 | console.log('GET /api/getUserId');
31 |
32 | var accessTokenStr = (req.params && req.params.access_token) || (req.query && req.query.access_token);
33 | var accessToken = oAuth2Server.collections.accessToken.findOne({accessToken: accessTokenStr});
34 |
35 | JsonRoutes.sendResult(res, {
36 | data: accessToken.userId
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/examples/clientApplication/client/configFormFixes.js:
--------------------------------------------------------------------------------
1 | /*
2 | This file just contains convenient methods for auto-filling the oauth2 login form configuration. None
3 | of the code here is important for implementing oauth2 on your site.
4 | */
5 |
6 | $(document).ready(function() {
7 | // update the fields when the dialog is dynamically added.
8 | $(document).on('DOMNodeInserted', '#configure-login-service-dialog', function(e) {
9 | populateServiceValues(e.target);
10 | });
11 |
12 | // update the fields on page load.
13 | populateServiceValues($('#configure-login-service-dialog'));
14 | });
15 |
16 | function populateServiceValues(target) {
17 | var setCount = 0;
18 | setCount += prePopulateValues(target, 'configure-login-service-dialog-clientId', 'clientApplication');
19 | setCount += prePopulateValues(target, 'configure-login-service-dialog-secret', '12345');
20 | setCount += prePopulateValues(target, 'configure-login-service-dialog-baseUrl', 'http://localhost:3100');
21 | setCount += prePopulateValues(target, 'configure-login-service-dialog-loginUrl', 'http://localhost:3100');
22 |
23 | // a hacky way to make the meteor configure interface make the save button
24 | // enabled. it only enables if it detects key up events in the input fields.
25 | if (setCount) {
26 | $('#configure-login-service-dialog-clientId').trigger('keyup', 17);
27 | }
28 | }
29 |
30 | function prePopulateValues(target, id, value) {
31 | var el = $(target).find('#' + id);
32 | if (!el.length) {
33 | return false;
34 | }
35 |
36 | if (!el.val()) {
37 | el.val(value);
38 | return true;
39 | }
40 |
41 | return false;
42 | }
43 |
--------------------------------------------------------------------------------
/examples/clientApplication/.meteor/versions:
--------------------------------------------------------------------------------
1 | accounts-base@1.2.2
2 | accounts-oauth@1.1.8
3 | accounts-ui@1.1.6
4 | accounts-ui-unstyled@1.1.8
5 | autopublish@1.0.4
6 | autoupdate@1.2.4
7 | babel-compiler@5.8.24_1
8 | babel-runtime@0.1.4
9 | base64@1.0.4
10 | binary-heap@1.0.4
11 | blaze@2.1.3
12 | blaze-html-templates@1.0.1
13 | blaze-tools@1.0.4
14 | boilerplate-generator@1.0.4
15 | caching-compiler@1.0.0
16 | caching-html-compiler@1.0.2
17 | callback-hook@1.0.4
18 | check@1.1.0
19 | ddp@1.2.2
20 | ddp-client@1.2.1
21 | ddp-common@1.2.2
22 | ddp-rate-limiter@1.0.0
23 | ddp-server@1.2.2
24 | deps@1.0.9
25 | diff-sequence@1.0.1
26 | ecmascript@0.1.6
27 | ecmascript-runtime@0.2.6
28 | ejson@1.0.7
29 | es5-shim@4.1.14
30 | fastclick@1.0.7
31 | geojson-utils@1.0.4
32 | hot-code-push@1.0.0
33 | html-tools@1.0.5
34 | htmljs@1.0.5
35 | http@1.1.1
36 | id-map@1.0.4
37 | insecure@1.0.4
38 | jquery@1.11.4
39 | launch-screen@1.0.4
40 | less@2.5.1
41 | livedata@1.0.15
42 | localstorage@1.0.5
43 | logging@1.0.8
44 | meteor@1.1.10
45 | meteor-base@1.0.1
46 | minifiers@1.1.7
47 | minimongo@1.0.10
48 | mobile-experience@1.0.1
49 | mobile-status-bar@1.0.6
50 | mongo@1.1.3
51 | mongo-id@1.0.1
52 | npm-mongo@1.4.39_1
53 | oauth@1.1.6
54 | oauth2@1.1.5
55 | observe-sequence@1.0.7
56 | ordered-dict@1.0.4
57 | prime8consulting:meteor-oauth2-client@0.0.2
58 | promise@0.5.1
59 | random@1.0.5
60 | rate-limit@1.0.0
61 | reactive-dict@1.1.3
62 | reactive-var@1.0.6
63 | reload@1.1.4
64 | retry@1.0.4
65 | routepolicy@1.0.6
66 | service-configuration@1.0.5
67 | session@1.1.1
68 | spacebars@1.0.7
69 | spacebars-compiler@1.0.7
70 | standard-minifiers@1.0.2
71 | templating@1.1.5
72 | templating-tools@1.0.0
73 | tracker@1.0.9
74 | ui@1.0.8
75 | underscore@1.0.4
76 | url@1.0.5
77 | webapp@1.2.3
78 | webapp-hashing@1.0.5
79 |
--------------------------------------------------------------------------------
/examples/resourceServer/.meteor/versions:
--------------------------------------------------------------------------------
1 | accounts-base@1.2.2
2 | accounts-password@1.1.4
3 | accounts-ui@1.1.6
4 | accounts-ui-unstyled@1.1.8
5 | autoupdate@1.2.4
6 | babel-compiler@5.8.24_1
7 | babel-runtime@0.1.4
8 | base64@1.0.4
9 | binary-heap@1.0.4
10 | blaze@2.1.3
11 | blaze-html-templates@1.0.1
12 | blaze-tools@1.0.4
13 | boilerplate-generator@1.0.4
14 | caching-compiler@1.0.0
15 | caching-html-compiler@1.0.2
16 | callback-hook@1.0.4
17 | check@1.1.0
18 | ddp@1.2.2
19 | ddp-client@1.2.1
20 | ddp-common@1.2.2
21 | ddp-rate-limiter@1.0.0
22 | ddp-server@1.2.2
23 | deps@1.0.9
24 | diff-sequence@1.0.1
25 | ecmascript@0.1.6
26 | ecmascript-runtime@0.2.6
27 | ejson@1.0.7
28 | email@1.0.8
29 | es5-shim@4.1.14
30 | fastclick@1.0.7
31 | geojson-utils@1.0.4
32 | hot-code-push@1.0.0
33 | html-tools@1.0.5
34 | htmljs@1.0.5
35 | http@1.1.1
36 | id-map@1.0.4
37 | jquery@1.11.4
38 | launch-screen@1.0.4
39 | less@2.5.1
40 | livedata@1.0.15
41 | localstorage@1.0.5
42 | logging@1.0.8
43 | meteor@1.1.10
44 | meteor-base@1.0.1
45 | meteorhacks:async@1.0.0
46 | minifiers@1.1.7
47 | minimongo@1.0.10
48 | mobile-experience@1.0.1
49 | mobile-status-bar@1.0.6
50 | mongo@1.1.3
51 | mongo-id@1.0.1
52 | npm-bcrypt@0.7.8_2
53 | npm-mongo@1.4.39_1
54 | observe-sequence@1.0.7
55 | ordered-dict@1.0.4
56 | prime8consulting:meteor-oauth2-server@0.0.3
57 | promise@0.5.1
58 | random@1.0.5
59 | rate-limit@1.0.0
60 | reactive-dict@1.1.3
61 | reactive-var@1.0.6
62 | reload@1.1.4
63 | retry@1.0.4
64 | routepolicy@1.0.6
65 | service-configuration@1.0.5
66 | session@1.1.1
67 | sha@1.0.4
68 | simple:json-routes@2.1.0
69 | spacebars@1.0.7
70 | spacebars-compiler@1.0.7
71 | srp@1.0.4
72 | standard-minifiers@1.0.2
73 | templating@1.1.5
74 | templating-tools@1.0.0
75 | tracker@1.0.9
76 | ui@1.0.8
77 | underscore@1.0.4
78 | url@1.0.5
79 | webapp@1.2.3
80 | webapp-hashing@1.0.5
81 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Meteor OAuth2
2 |
3 | This is the root repository of several meteor packages that give your application the ability to act as an OAuth2 server or login to a OAuth2 Meteor application.
4 |
5 | Checkout the packages for the package source. The examples will be very helpful in understanding what you can do with these packages.
6 |
7 | =========================================
8 | #### OAuth Flow - Diagram
9 |
10 | 
11 |
12 | =========================================
13 | #### OAuth Flow - Step By Step
14 |
15 | ```bash
16 | C1 Request Client ID
17 | C1.1 Generate Client ID # Meteor.call('oauth/addclient', newClient)
18 | C1.2 Return Client ID
19 | C2 Configure Client ID
20 |
21 | A1 Start App # Meteor.startup()
22 | A1.1 Launch Browser
23 | A1.1.1. Request Login
24 | A1.1.1.1 Create Login Page
25 | A1.1.1.2 Return to Login Page
26 | A2 Enter Login Details
27 | A2.1 Submit Login Details
28 | A2.1.1 Authenticate User
29 | A2.1.2 Redirect to Application
30 | A3 Intercept Redirect
31 | A4 Extract Auth Code
32 | A5 Get Access Token # HTTP.post('/oauth/token')
33 | A5.1 Generate Access Token # oAuth2Server.callMethod.authCodeGrant()
34 | A5.2 Return Access/Refresh Token # HTTP.post('/oauth/token')
35 | A6 Save Refresh Token # tokenResult.set(result.data)
36 | A7 Request Data # HTTP.get('/api/getUserId')
37 | A7.1 Check Access Token # oAuth2Server.oauthserver.authorise()
38 | A7.2 Return Data # JsonRoutes.add
39 | A8 Rest of Business Logic
40 | ```
41 |
42 |
43 | =========================================
44 | #### Licensing
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/examples/clientApplication/client/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | All the code here is to demonstrate the two-way communication between the resource server and
3 | this client application. None of the code here is important when implementing the client on
4 | you site.
5 | */
6 |
7 | var getUserIdResult = new ReactiveVar(null);
8 |
9 | Template.main.helpers({
10 | getUserAccessToken: function() {
11 | return getUserAccessToken();
12 | },
13 |
14 | getUserIdResult: function() {
15 | return getUserIdResult.get();
16 | },
17 |
18 | getUserOAuth2Id: function() {
19 | var user = Meteor.user();
20 |
21 | if (!isOAuth2User(user)) {
22 | return;
23 | }
24 |
25 | return user.services.MeteorOAuth2Server.id;
26 | }
27 | });
28 |
29 | Template.main.events({
30 | /**
31 | * Wipe out all the configured services.
32 | */
33 | 'click button.resetServiceConfiguration': function() {
34 | Meteor.call('resetServiceConfiguration');
35 | },
36 |
37 | /**
38 | * Perform a server-to-server request to get the user id on the resource server. This action exists
39 | * just to demonstrate the steps in the oauth2 process. The oauth2 client package does this for you
40 | * when logging in.
41 | */
42 | 'click button.testLocalTokens': function() {
43 | if (getUserAccessToken()) {
44 | Meteor.call('getUserId', function(err, result) {
45 | console.log(result);
46 | // set the userId.
47 | getUserIdResult.set(result.data);
48 | });
49 | } // if
50 | } // function
51 | });
52 |
53 | /**
54 | * Determine if a user originates from an oauth2 login.
55 | * @param user
56 | * @returns {*}
57 | */
58 | function isOAuth2User(user) {
59 | return user
60 | && user.services
61 | && user.services.MeteorOAuth2Server
62 | ;
63 | }
64 |
65 | /**
66 | * Get the user access token if it exists.
67 | * @returns {*}
68 | */
69 | function getUserAccessToken() {
70 | var user = Meteor.user();
71 |
72 | if (!isOAuth2User(user)) {
73 | return;
74 | }
75 |
76 | return user.services.MeteorOAuth2Server.accessToken;
77 | }
78 |
--------------------------------------------------------------------------------
/examples/clientApplication/client/index.html:
--------------------------------------------------------------------------------
1 |
19 | Good news! Your user was authenticated with OAuth2. While the authentication is indication that data 20 | is being transferred from the resource service using tokens. You can view the results here. 21 |
22 | 23 |accessToken: {{ getUserAccessToken }}
25 | 26 | 27 | 28 | {{#if getUserIdResult}} 29 |31 | This step is also performed server-to-server by the client application and is 32 | only done here for testing purposes. Here we are using the newly acquired 33 | access token, we retrieve the userId associated with the access token. These two 34 | should match. 35 |
36 || expected id | 39 |{{ getUserOAuth2Id }} | 40 |This was given to us by the oauth2 service during login. | 41 |
| actual id | 44 |{{ getUserIdResult }} | 45 |This was retrieved via REST using the access token. | 46 |
56 | For the sake of convenience while you experiment, you can reset configuration for the ClientApplication. 57 | This will make the login button you see above goto it's unconfigured state. 58 |
59 | 60 |
15 | This meteor-oauth2-server package currently provides functionality for both the
16 | AuthenticationServer and the ResourceServer. This functionality may be split into separate packages
17 | and/or examples in the future; however, for the time being, AuthenticationServer and ResourceServer
18 | are the same application.
19 |
21 | The following steps represent the steps that are necessary to properly negotiate an oauth2 token 22 | (Described here). 23 | While these steps work on this site, this site is for testing and demo purposes only. Do not use 24 | this configuration in production. You'll know if everything is working if you can get to Step A7 25 | and the user ids match. 26 |
27 | 28 |32 | The AuthenticationServer & ResourceServer need to know about the ClientApplication that's going 33 | to authenticate to it. So the first step in configuring the ResourceServer is to register a 34 | Client ID and Client Secret. The following form illustrates what might be provided to a customer 35 | who is self-configuring a client application via an API Key Generation page. 36 |
37 | 38 | {{#if clientCount}} 39 |Client created.
40 |41 | For the sake of testing, you can remove all the created clients. 42 | 43 |
44 | {{/if}} 45 | 46 | {{#unless clientCount }} 47 | 77 | 78 |79 | However the record is created, the server is going to look for a client that exists, is active, 80 | and it's redirectUri must match the redirect_uri provided in the URL. If not, the creation 81 | of the authorization code in step 4 will fail. 82 |
83 | {{/unless}} 84 | 85 |A login page needs to be created. This is done by visiting the site with the proper url parameters.
90 | {{#unless isUrlParamsValid }} 91 |The URL params are not set in order to authorize an oauth2 token.
92 |The following link will simulate arriving to this page from another site that wishes to authenticate with oauth2.
93 | Simulate proper link. 94 | {{/unless}} 95 | 96 | {{#if isUrlParamsValid}} 97 |Here are the url params this site received.
98 || clint_id | 101 |{{ urlParams.client_id }} | 102 |
| redirect_uri | 105 |{{ urlParams.redirect_uri }} | 106 |
| response_type | 109 |{{ urlParams.response_type }} | 110 |
The user must be authenticated to authorize an oauth2 request.
118 | {{> loginButtons}} 119 | {{/unless}} 120 | 121 | {{#if currentUser}} 122 |User is authenticated.
123 | {{> loginButtons}} 124 | 125 |This is the button a user would click to allow {{ urlParams.client_id }} access to your email address.. etc.
128 | 129 | 130 | {{#if grantResult}} 131 |Grant was run with the given params. Normally, the user would be redirected to the redirect URI.
133 || Success | 136 |{{ grantResult.success }} | 137 |
| Error | 140 |{{ grantResult.error }} | 141 |
| Authorization Code | 144 |{{ grantResult.authorizationCode }} | 145 |
| RedirectUri | 148 |{{ grantResult.redirectToUri}} | 149 |
This is where the user's interaction generally stops. For testing purposes, now that you have an authorization code, you can test service by retrieving an access token.
154 | 155 | 156 | {{#if tokenResult}} 157 |160 | Using the authorizationCode, the client applicationg would post back to this server 161 | to request a token. This is the token you'd use to run REST calls and alike. 162 | This is server to server communication. This example is only for testing purposes to 163 | ensure we did everything properly. 164 |
165 || access_token | 168 |{{ tokenResult.access_token }} | 169 |
| expires_in | 172 |{{ tokenResult.expires_in }} | 173 |
| token_type | 176 |{{ tokenResult.token_type }} | 177 |
183 | This step is also performed server-to-server by the client application and is 184 | only done here for testing purposes. Here we are using the newly acquired 185 | access token, we retrieve the userId associated with the access token. 186 |
187 || expected id | 190 |{{ currentUser._id }} | 191 |This was given to us by Meteor. | 192 |
| actual id | 195 |{{ getUserIdResult }} | 196 |This was retrieved via REST using the access token. | 197 |
This shows a list of all the existing auth codes.
213 |This shows a list of all the existing refresh tokens.
222 |