Compare commits
	
		
			26 Commits
		
	
	
		
			master
			...
			playground
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8555d3673a | |||
| ff50c74a56 | |||
| 9760bcf6c1 | |||
| c90fd2a6f4 | |||
| f069314e76 | |||
| 0727c3a6c9 | |||
| 242c0e3abb | |||
| ece06b8463 | |||
| 980895992a | |||
| 9aaabeb908 | |||
| 4ab4ad0ac0 | |||
| 0ff3a2e3ce | |||
| 4b6a8f7316 | |||
| 998c652969 | |||
|  | 87820b3d24 | ||
| db261147c2 | |||
| 6eb5ea0f3d | |||
| 23318c01f0 | |||
| ed1c3374dd | |||
| 9dbc2b5664 | |||
| 84a8090d49 | |||
| 6105637cc5 | |||
| c5cc2be470 | |||
| a16fbdd764 | |||
| 23765a97ef | |||
| 2500711b8c | 
							
								
								
									
										1
									
								
								.well-known
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								.well-known
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | |||||||
|  | _apis | ||||||
							
								
								
									
										1
									
								
								_apis/oauth3
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								_apis/oauth3
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | |||||||
|  | oauth3.org | ||||||
							
								
								
									
										1
									
								
								_apis/org.oauth3
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								_apis/org.oauth3
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | |||||||
|  | oauth3.org | ||||||
							
								
								
									
										115
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								index.html
									
									
									
									
									
								
							| @ -8,7 +8,7 @@ | |||||||
|     <!-- <link rel="stylesheet" type="text/css" href="/css/style.css"> --> |     <!-- <link rel="stylesheet" type="text/css" href="/css/style.css"> --> | ||||||
|     <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Lato:300"> |     <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Lato:300"> | ||||||
|     <script src="https://use.fontawesome.com/3af0faae66.js"></script> |     <script src="https://use.fontawesome.com/3af0faae66.js"></script> | ||||||
|     <link rel="stylesheet" type="text/css" href="/css/daplie-installer-overrides.css"> |     <!-- link rel="stylesheet" type="text/css" href="/css/daplie-installer-overrides.css" --> | ||||||
|   </head> |   </head> | ||||||
| 
 | 
 | ||||||
|   <body> |   <body> | ||||||
| @ -24,8 +24,8 @@ | |||||||
|     <!-- Step 5: ask for permissions --> |     <!-- Step 5: ask for permissions --> | ||||||
| 
 | 
 | ||||||
|     <div class="dap-bordered js-userid-container"> |     <div class="dap-bordered js-userid-container"> | ||||||
|       <p class="org-title">daplie.me</p> |       <p class="org-title">OAuth3.org</p> | ||||||
|       <p class="dap-centered-text dap-normal-text welcome-text center-it">Welcome to a new way to login. daplie.me helps you create an Internet ID that allows you to choose what info is shared about you when you login into a site or app online.</p> |       <p class="dap-centered-text dap-normal-text welcome-text center-it">Welcome to a new way to login. OAuth3.org helps you create an Internet ID that allows you to choose what info is shared about you when you login into a site or app online.</p> | ||||||
|       <form method="post" action=""> |       <form method="post" action=""> | ||||||
|         <div class="form-group"> |         <div class="form-group"> | ||||||
|           <input type="email" class="form-control dap-input js-oauth3-email emailInput" placeholder="Enter an email address to start"></input> |           <input type="email" class="form-control dap-input js-oauth3-email emailInput" placeholder="Enter an email address to start"></input> | ||||||
| @ -46,7 +46,7 @@ | |||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <div class="dap-bordered js-authn"> |     <div class="dap-bordered js-authn"> | ||||||
|       <p class="org-title">daplie.me</p> |       <p class="org-title">OAuth3.org</p> | ||||||
|       <!-- <div class="dap-normal-text"> |       <!-- <div class="dap-normal-text"> | ||||||
|         <span class="fa fa-3x icon-centered-3x fa-purple fa-envelope"></span> |         <span class="fa fa-3x icon-centered-3x fa-purple fa-envelope"></span> | ||||||
|       </div> |       </div> | ||||||
| @ -69,7 +69,7 @@ | |||||||
|             <img src="./img/pressed-check.png" class="check js-remember-status"> |             <img src="./img/pressed-check.png" class="check js-remember-status"> | ||||||
|             <!-- <span class="fa fa-2x fa-purple fa-square-o dap-remember-margin js-remember-status"></span> --> |             <!-- <span class="fa fa-2x fa-purple fa-square-o dap-remember-margin js-remember-status"></span> --> | ||||||
|             <span class="dap-remember-me noselect">Remember this device.</span> |             <span class="dap-remember-me noselect">Remember this device.</span> | ||||||
|             <input class="js-remember-checkbox hidden" type="checkbox"></input> |             <input class="js-remember-checkbox hidden" type="checkbox" checked></input> | ||||||
|           </label> |           </label> | ||||||
|         </div> |         </div> | ||||||
|         <button type="submit" class="btn btn-primary submit-btn dap-full-button-green js-submit-code-btn" disabled>Submit</button> |         <button type="submit" class="btn btn-primary submit-btn dap-full-button-green js-submit-code-btn" disabled>Submit</button> | ||||||
| @ -86,7 +86,7 @@ | |||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <div class="dap-bordered dap-normal-text js-authz"> |     <div class="dap-bordered dap-normal-text js-authz"> | ||||||
|       <p class="org-title">daplie.me</p> |       <p class="org-title">OAuth3.org</p> | ||||||
|       <!-- <br> --> |       <!-- <br> --> | ||||||
|       <!-- <div class="dap-user-plus-app"> |       <!-- <div class="dap-user-plus-app"> | ||||||
|         <span class="fa fa-3x fa-purple fa-user-circle"></span> |         <span class="fa fa-3x fa-purple fa-user-circle"></span> | ||||||
| @ -142,58 +142,75 @@ | |||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| 
 | 
 | ||||||
|   <div class="fade mock-bare"> |   <div class="fade js-playground" ng-app="oauth3Playground" ng-strict> | ||||||
|     <div class="container"> |     <div class="container"> | ||||||
|       <div class="jumbotron"> |       <div class="jumbotron"> | ||||||
|         <h1>OAuth3 Playground</h1> |         <h1>OAuth3</h1> | ||||||
|  |         <p>A (mostly) client-side authentication and authorization framework for decentralized peer-to-peer and federated networks. | ||||||
|       </div> |       </div> | ||||||
|  |       <div class="row"> | ||||||
|  |         <div> | ||||||
|  |           <h2>OAuth3 Test Bed</h2> | ||||||
|  |           <!-- | ||||||
|  |           <a class="btn btn-primary" href="azp.html">Demo Authorized Party</a> | ||||||
|  |           <a class="btn btn-primary" href="issuer.html">Demo Issuer</a> | ||||||
|  |           --> | ||||||
|  |           <a class="btn btn-primary" href="playground.html">Demo Authorized Party</a> | ||||||
|  |           <a class="btn btn-primary" href="playground.html">Demo Issuer</a> | ||||||
|  |         </div> | ||||||
| 
 | 
 | ||||||
|       <div class="row"> |         <div> | ||||||
|         <div class="col-md-3"> |           <h2>Private, Peer-to-Peer, Anonymous: Pick any two... at a time</h2> | ||||||
|           Login Status: |           <ul> | ||||||
|         </div> |             <li>Privacy | ||||||
|         <div class="col-md-9"> |             <li>Peer-to-Peer | ||||||
|           ... |             <li>Anonymity | ||||||
|         </div> |           </ul> | ||||||
|       </div> |           <p>OAuth3's federated design allows it to work in all 3 modes of decentralization: | ||||||
|       <div class="row"> |           <ul> | ||||||
|         <div class="col-md-3"> |             <li>Private, Peer-to-Peer (Trusted model) | ||||||
|           Current Sessions: |               <!-- | ||||||
|         </div> |               (Public / Private Keypair model) | ||||||
|         <div class="col-md-9"> |               For trusted parties OAuth3 defines how to exchange public keys on the client-side to | ||||||
|           ... |               ensure that a resource owner's assets can be retrieved, without any involved. | ||||||
|         </div> |               --> | ||||||
|       </div> |  | ||||||
|       <div class="row"> |  | ||||||
|         <div class="col-md-3"> |  | ||||||
|           Approved Devices: |  | ||||||
|         </div> |  | ||||||
|         <div class="col-md-9"> |  | ||||||
|           ... |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="row"> |  | ||||||
|         <div class="col-md-3"> |  | ||||||
|           Approved Applications: |  | ||||||
|         </div> |  | ||||||
|         <div class="col-md-9"> |  | ||||||
|           ... |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
| 
 | 
 | ||||||
|  |             <li>Private, Anonymous (Escrow / Broker model) | ||||||
|  |               <!-- | ||||||
|  |               (Escrow / Broker model) | ||||||
|  |               When you want transactions to be both private and anonymous there | ||||||
|  |               must be a mutual trusted authority to broker the transaction to ensure privacy without | ||||||
|  |               disclosing identity. In the same way that a private escrow service can ensure a valid | ||||||
|  |               between two untrusted participants, <em>any</em> OAuth3 Issuer can broker identity and | ||||||
|  |               privilege transactions between two parties. | ||||||
|  |               --> | ||||||
|  | 
 | ||||||
|  |             <li>Peer-to-Peer, Anonymous (Public Ledger model) | ||||||
|  |               <!-- | ||||||
|  |               --> | ||||||
|  |           </ul> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <h2>Authentication, simplified</h2> | ||||||
|  |         <ul> | ||||||
|  |           <li>A single implementation | ||||||
|  |           <li>No developer keys (uses tls authentication) | ||||||
|  |           <li>Smart scope discovery | ||||||
|  |         </ul> | ||||||
|  |       </div> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     <!--[if IE]><script src="bower_components/rsvp.js/rsvp.js"></script><![endif]--> |   <!--[if IE]><script src="bower_components/rsvp.js/rsvp.js"></script><![endif]--> | ||||||
|     <script src="./js/jquery-2.2.0.min.js"></script> |   <script src="./js/jquery-2.2.0.min.js"></script> | ||||||
|     <script src="./js/jquery.mask.min.js"></script> |   <script src="./js/jquery.mask.min.js"></script> | ||||||
|     <script src="./js/bootstrap.min.js"></script> |   <script src="./js/bootstrap.min.js"></script> | ||||||
|     <script src="/assets/oauth3.org/oauth3.core.js"></script> |   <script src="/assets/oauth3.org/oauth3.core.js"></script> | ||||||
|     <script src="/assets/oauth3.org/oauth3.crypto.js"></script> |   <script src="/assets/oauth3.org/oauth3.crypto.js"></script> | ||||||
|     <script src="/assets/oauth3.org/oauth3.issuer.js"></script> |   <script src="/assets/oauth3.org/oauth3.issuer.js"></script> | ||||||
|     <script src="./js/issuer.js"></script> |   <script src="./js/issuer.js"></script> | ||||||
|     <script src="./js/script.js"></script> |   <script src="./js/script.js"></script> | ||||||
| 
 | 
 | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|  | |||||||
							
								
								
									
										33889
									
								
								js/angular-1.6.6.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33889
									
								
								js/angular-1.6.6.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10075
									
								
								js/angular-ui-router-1.0.10.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10075
									
								
								js/angular-ui-router-1.0.10.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										18
									
								
								js/issuer.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								js/issuer.js
									
									
									
									
									
								
							| @ -68,7 +68,7 @@ $(function () { | |||||||
|     // TODO casing
 |     // TODO casing
 | ||||||
|     // TODO expiry calculation
 |     // TODO expiry calculation
 | ||||||
|     // TODO leave this up to OAUTH3
 |     // TODO leave this up to OAUTH3
 | ||||||
|     session.provider_uri = session.provider_rui || CONFIG.host; |     session.provider_uri = session.provider_uri || CONFIG.host; | ||||||
|     session.client_uri = session.client_uri || CONFIG.host; // same as provider in this case
 |     session.client_uri = session.client_uri || CONFIG.host; // same as provider in this case
 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -94,6 +94,9 @@ $(function () { | |||||||
|       // deprecated
 |       // deprecated
 | ||||||
|       'oauth3_authn': "Basic secure authentication" |       'oauth3_authn': "Basic secure authentication" | ||||||
|     , 'auth@oauth3.org': "Basic secure authentication" |     , 'auth@oauth3.org': "Basic secure authentication" | ||||||
|  |     , 'profile@oauth3.org': "Basic profile information" | ||||||
|  |     , 'profile.email@oauth3.org': "Email address" | ||||||
|  |     , 'profile.phone@oauth3.org': "Phone number" | ||||||
|     , 'wallet': "Access to payments and subscriptions" |     , 'wallet': "Access to payments and subscriptions" | ||||||
|     , 'bucket': "Access to file storage" |     , 'bucket': "Access to file storage" | ||||||
|     , 'db': "Access to app data" |     , 'db': "Access to app data" | ||||||
| @ -118,7 +121,7 @@ $(function () { | |||||||
|     , '*': "FULL ACCOUNT ACCESS" |     , '*': "FULL ACCOUNT ACCESS" | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if ('oauth3_authn' === clientParams.scope) { |     if ('authn@oauth3.org' === (clientParams.scope||'').toString()) { | ||||||
|       // implicit ppid grant is automatic
 |       // implicit ppid grant is automatic
 | ||||||
|       console.warn('[security] fix scope checking on backend so that we can do automatic grants'); |       console.warn('[security] fix scope checking on backend so that we can do automatic grants'); | ||||||
|       // TODO check user preference if implicit ppid grant is allowed
 |       // TODO check user preference if implicit ppid grant is allowed
 | ||||||
| @ -362,7 +365,13 @@ $(function () { | |||||||
|   function handleAuthorizationDialog() { |   function handleAuthorizationDialog() { | ||||||
|     return getSession(CONFIG.host).then(function (session) { |     return getSession(CONFIG.host).then(function (session) { | ||||||
|       return getGrants(session); |       return getGrants(session); | ||||||
|     }).catch(function () { |     }).catch(function (e) { | ||||||
|  |       if(e) { | ||||||
|  |         console.error( | ||||||
|  |             "Error authing current session. Requiring re-login. Message: " | ||||||
|  |             , e.message | ||||||
|  |         ); | ||||||
|  |       } | ||||||
|       // TODO select the providers the client wants to show
 |       // TODO select the providers the client wants to show
 | ||||||
|       // providers=daplie.com,facebook.com,google.com // etc
 |       // providers=daplie.com,facebook.com,google.com // etc
 | ||||||
|       // TODO let the client specify switch_user
 |       // TODO let the client specify switch_user
 | ||||||
| @ -403,7 +412,8 @@ $(function () { | |||||||
|       $('.mock-main').addClass('in'); |       $('.mock-main').addClass('in'); | ||||||
|     } else { |     } else { | ||||||
|       console.log('[DEBUG] not an auth window'); |       console.log('[DEBUG] not an auth window'); | ||||||
|       $('.mock-bare').addClass('in'); |       $('.js-playground').addClass('in'); | ||||||
|  |       //window.PLAYGROUND();
 | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										538
									
								
								js/playground.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										538
									
								
								js/playground.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,538 @@ | |||||||
|  | (function () { | ||||||
|  |   'use strict'; | ||||||
|  | 
 | ||||||
|  |   window.ngOauth3App = angular.module('oauth3Playground', [ 'oauth3.org' ]) | ||||||
|  |   //window.ngOauth3App = angular.module('oauth3Playground', [ 'ui.router' ])
 | ||||||
|  | /* | ||||||
|  |   ngOauth3App.config(function($stateProvider) { | ||||||
|  |     var helloState = { | ||||||
|  |       name: 'hello', | ||||||
|  |       url: '/hello', | ||||||
|  |       template: '<h3>hello world!</h3>' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     var aboutState = { | ||||||
|  |       name: 'about', | ||||||
|  |       url: '/about', | ||||||
|  |       template: '<h3>Its the UI-Router hello world app!</h3>' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     $stateProvider.state(helloState); | ||||||
|  |     $stateProvider.state(aboutState); | ||||||
|  |   }); | ||||||
|  | */ | ||||||
|  |   .controller('PlaygroundCtrl', [ '$timeout', 'azp@oauth3.org', function ($timeout, OAUTH3) { | ||||||
|  |     // NOTE: This OAUTH3 is the same as window.OAUTH3, but with angular's promise injected
 | ||||||
|  |     // TODO: how to load more than one version of oauth3 on the page (i.e. a vanilla version without angular entaglement)
 | ||||||
|  |     var vm = this; | ||||||
|  | 
 | ||||||
|  |     vm.framework = 'none'; | ||||||
|  |     vm.clientUri = OAUTH3.clientUri({ host: window.location.host }); | ||||||
|  |     vm.conf = { debug: undefined, client_id: vm.clientUri, client_uri: vm.clientUri, provider_uri: vm.clientUri }; | ||||||
|  |     vm.providerUri = vm.conf.client_uri; | ||||||
|  |     // map of things being debounced presently
 | ||||||
|  |     vm.debouncing = {}; | ||||||
|  |     vm.defaults = { provider: vm.conf.provider_uri, directives: null }; | ||||||
|  |     vm.defaults.scopes = [ | ||||||
|  |       { name: 'profile@oauth3.org', desc: "Basic profile information", checked: true } | ||||||
|  |     , { name: 'authn@oauth3.org', desc: "Basic secure authentication", checked: true } | ||||||
|  |       //{ name: 'authn@oauth3.org', desc: "Basic secure authentication" }
 | ||||||
|  |     , { name: 'photos@daplie.com', desc: "Access to photos" } | ||||||
|  |     , { name: 'profile@oauth3.org', desc: "Access to basic profile info such as username, display_name, etc" } | ||||||
|  |     , { name: 'dns', desc: "DNS records (A/AAAA, TXT, SRV, MX, etc)" } | ||||||
|  |     , { name: '*', desc: "FULL ACCOUNT ACCESS" } | ||||||
|  |     //, 'auth@oauth3.org': "Basic secure authentication"
 | ||||||
|  |     //, 'profile.email@oauth3.org': "Email address"
 | ||||||
|  |     //, 'profile.phone@oauth3.org': "Phone number"
 | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     vm.form = {}; | ||||||
|  |     vm.form.id = 'coolaj86@gmail.com'; | ||||||
|  |     vm.form.subject = ''; | ||||||
|  |     vm.form.userProvider = ''; | ||||||
|  |     vm.form.provider = 'sso.hellabit.com'; | ||||||
|  |     vm.form.scopes = ''; | ||||||
|  | 
 | ||||||
|  |     vm.locks = {}; | ||||||
|  |     vm.validated = {}; | ||||||
|  |     vm.responses = {}; | ||||||
|  | 
 | ||||||
|  |     //
 | ||||||
|  |     // Convenience for our app
 | ||||||
|  |     //
 | ||||||
|  |     vm.fn = {}; | ||||||
|  |     vm.fn.updateUrls = function () { | ||||||
|  |       Object.keys(vm.api.urls).forEach(function (key) { | ||||||
|  |         var fn = vm.api.urls[key]; | ||||||
|  |         fn(); | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  |     vm.fn._debounce = {}; | ||||||
|  |     vm.fn.debounceUi = function () { | ||||||
|  |       if (vm.debouncing.user || vm.debouncing.provider) { | ||||||
|  |         vm.locks['login'] = true; | ||||||
|  |       } else { | ||||||
|  |         vm.locks['login'] = false; | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     vm.fn.debounce = function (name, time) { | ||||||
|  |       vm.debouncing[name] = true; | ||||||
|  |       vm.fn.debounceUi(); | ||||||
|  |       $timeout.cancel(vm.fn._debounce[name]); | ||||||
|  |       vm.fn._debounce[name] = $timeout(function () { | ||||||
|  |         vm.debouncing[name] = false; | ||||||
|  |         vm.fn.debounceUi(); | ||||||
|  |         // do nothing, just use promise
 | ||||||
|  |         return; | ||||||
|  |       }, time || 250); | ||||||
|  |       return vm.fn._debounce[name]; | ||||||
|  |     } | ||||||
|  |     vm.fn.changeUser = function () { | ||||||
|  |       var parts = vm.form.id.split('@'); | ||||||
|  |       var user; | ||||||
|  |       var provider; | ||||||
|  | 
 | ||||||
|  |       if (/@/.test(vm.form.id)) { | ||||||
|  |         // The username may have a single @, the provider may not
 | ||||||
|  |         // user@thing.com@whatever.com -> user@thing.com, whatever.com
 | ||||||
|  |         provider = parts.pop(); | ||||||
|  |         user = parts.join(''); | ||||||
|  |       } else { | ||||||
|  |         //vm.form.hasUser = false;
 | ||||||
|  |         user = ''; | ||||||
|  |         provider = parts.join(''); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       vm.form.subject = vm.form.id; | ||||||
|  | 
 | ||||||
|  |       return vm.fn.debounce('provider', 250).then(function () { | ||||||
|  |         var parts = vm.form.provider.split('.'); | ||||||
|  |         if (!vm.form.providerIndependent) { | ||||||
|  |           vm.form.provider = provider; | ||||||
|  |         } | ||||||
|  |         vm.form.userProvider = provider; | ||||||
|  |         // Careful: don't use state within a debounce function
 | ||||||
|  |         // uses vm.form.provider for lookup
 | ||||||
|  |         if (parts.length >= 2 && parts[parts.length - 1].length >= 2 && parts.every(function (p) {return p.length})) { | ||||||
|  |           return vm.api.discover().then(function () { | ||||||
|  |             console.log('[changeUser] vm.directives:'); | ||||||
|  |             console.log(vm.directives); | ||||||
|  |             console.log(provider); | ||||||
|  |             console.log(OAUTH3.uri.normalize(vm.directives.issuer)); | ||||||
|  |             if (vm.directives && provider === OAUTH3.uri.normalize(vm.directives.issuer)) { | ||||||
|  |               vm.form.subject = user; | ||||||
|  |             } else { | ||||||
|  |               vm.form.subject = vm.form.id; | ||||||
|  |             } | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  |     vm.fn.changeProvider = function () { | ||||||
|  |       vm.form.providerIndependent = true; | ||||||
|  | 
 | ||||||
|  |       var parts = vm.form.provider.split('.'); | ||||||
|  |       vm.fn.debounce('provider', 250).then(function () { | ||||||
|  |         // Careful: don't use state within a debounce function
 | ||||||
|  |         if (parts.length >= 2 && parts[parts.length - 1].length >= 2 && parts.every(function (p) {return p.length})) { | ||||||
|  |           return vm.api.discover(); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  |     vm.fn.toggleAdvanced = function () { | ||||||
|  |       vm.advanced = !vm.advanced; | ||||||
|  |       vm.form.provider = vm.form.userProvider; | ||||||
|  |       if (!vm.advanced) { | ||||||
|  |         vm.form.providerIndependent = false; | ||||||
|  |         vm.fn.changeUser(); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     vm.fn.updateDebug = function () { | ||||||
|  |       if (!vm.conf.debug) { | ||||||
|  |         vm.conf.debug = undefined; | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     vm.fn.updateScopes = function () { | ||||||
|  |       var scopes = {}; | ||||||
|  | 
 | ||||||
|  |       (vm.scopes && vm.scopes.split(',') || []).forEach(function (name) { | ||||||
|  |         scopes[name] = true; | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       vm.defaults.scopes.forEach(function (scope) { | ||||||
|  |         if (scope.checked) { | ||||||
|  |           scopes[scope.name] = true; | ||||||
|  |         } else { | ||||||
|  |           scopes[scope.name] = false; | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       vm.form.scopes = Object.keys(scopes).filter(function (key) { | ||||||
|  |         return scopes[key]; | ||||||
|  |       }).map(function (key) { | ||||||
|  |         return key; | ||||||
|  |       }).join(','); | ||||||
|  | 
 | ||||||
|  |       vm.fn.updateUrls(); // vm.api.urls.implicitGrant();
 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     vm.fn.lock = function () { | ||||||
|  |       vm._working = true; | ||||||
|  |     }; | ||||||
|  |     vm.fn.unlock = function () { | ||||||
|  |       vm._working = false; | ||||||
|  |     }; | ||||||
|  |     vm.fn.clearError = function () { | ||||||
|  |       vm.error = null; | ||||||
|  |     }; | ||||||
|  |     vm.fn.clearDirectives = function () { | ||||||
|  |       vm.directives = null; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // A place for all the generated urls
 | ||||||
|  |     vm.urls = {}; | ||||||
|  | 
 | ||||||
|  |     //
 | ||||||
|  |     // Wrap around the OAUTH3 APIs
 | ||||||
|  |     //
 | ||||||
|  |     vm.api = {}; | ||||||
|  |     vm.api.urls = {}; | ||||||
|  |     vm.api.authn = {}; | ||||||
|  |     vm.api.jwt = {}; | ||||||
|  |     vm.api.urls.credentialMeta = function () { | ||||||
|  |       if (!vm.directives ||!vm.directives.credential_meta || !vm.form.id) { return; } | ||||||
|  |       vm.urls.credentialMeta = OAUTH3.urls.credentialMeta(vm.directives, { email: vm.form.id }); | ||||||
|  |     }; | ||||||
|  |     vm.api.urls.otp = function () { | ||||||
|  |       if (!vm.directives || !vm.form.id) { return; } | ||||||
|  |       vm.urls.otp = OAUTH3.urls.otp(vm.directives, { email: vm.form.id }); | ||||||
|  |     }; | ||||||
|  |     vm.api.authn.otp = function () { | ||||||
|  |       vm.fn.updateUrls(); // vm.api.urls.otp();
 | ||||||
|  |       OAUTH3.authn.otp(vm.directives, { email: vm.form.id }).then(function (resp) { | ||||||
|  |         vm.responses.otp = resp; | ||||||
|  |         vm.form.otpUuid = resp.data.code_id; | ||||||
|  |         console.log('vm.responses.otp: (' + typeof resp + ')'); | ||||||
|  |         console.log(vm.responses.otp); | ||||||
|  | 
 | ||||||
|  |         console.log('vm.form.otpUuid:'); | ||||||
|  |         console.log(vm.form.otpUuid); | ||||||
|  | 
 | ||||||
|  |         vm.fn.updateUrls(); // vm.api.urls.resourceOwnerPassword();
 | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  |     vm.api.authn.credentialMeta = function () { | ||||||
|  |       vm.fn.updateUrls(); // vm.api.urls.credentialMeta();
 | ||||||
|  |       OAUTH3.authn.loginMeta(vm.directives, { email: vm.form.id }).then(function () { | ||||||
|  |         vm.fn.updateUrls(); // vm.api.urls.credentialMeta();
 | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     vm.api.authn._ropOpts = function () { | ||||||
|  |       //var opts = { email: vm.form.id, uuid: vm.form.otpUuid, code: vm.form.otpCode };
 | ||||||
|  |       return vm.api.authn._ropOpts_ = { | ||||||
|  |         client_id: vm.conf.client_uid || undefined | ||||||
|  |       , client_uri: vm.conf.client_uri || undefined | ||||||
|  |       , grant_type: 'password' | ||||||
|  |       , username: vm.form.id || undefined | ||||||
|  |       , password: vm.form.otpCode || undefined | ||||||
|  |       , totp: vm.form.totpToken || undefined | ||||||
|  |       , otp: vm.form.otpCode || "{{otp-code}}" | ||||||
|  |       , password_type: vm.form.otpCode && 'otp' || undefined | ||||||
|  |       , otp_code: vm.form.otpCode || undefined | ||||||
|  |       , otp_id: vm.form.otpUuid || undefined | ||||||
|  |       , otp_uuid: vm.form.otpUuid || undefined | ||||||
|  |       , user_agent: navigator.userAgent || undefined // "AJ's Macbook" for a specific device?
 | ||||||
|  |       , jwk: vm.form.rememberDevice && opts.jwk || undefined | ||||||
|  |       //, "public_key": opts.rememberDevice && opts.publicKey || undefined
 | ||||||
|  |       //, "public_key_type":  opts.rememberDevice && opts.publicKeyType || undefined // RSA/ECDSA
 | ||||||
|  |       //, "jwt": opts.jwt // TODO sign a proof with a previously loaded public_key
 | ||||||
|  |       , debug: vm.form.debug || undefined | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |     vm.api.urls.resourceOwnerPassword = function () { | ||||||
|  |       if (!vm.directives || !vm.form.otpUuid) { return; } | ||||||
|  |       vm.urls.resourceOwnerPassword = OAUTH3.urls.resourceOwnerPassword(vm.directives, vm.api.authn._ropOpts()); | ||||||
|  |     }; | ||||||
|  |     vm.api.authn.resourceOwnerPassword = function () { | ||||||
|  |       vm.fn.updateUrls(); // vm.api.urls.resourceOwnerPassword();
 | ||||||
|  |       OAUTH3.authn.resourceOwnerPassword(vm.directives, vm.api.authn._ropOpts()).then(function (resp) { | ||||||
|  |         vm.responses.resourceOwnerPassword = { status: 0, data: resp }; | ||||||
|  |         vm.form.accessToken = vm.accessToken = resp.access_token; | ||||||
|  |         vm.form.refreshToken = vm.refreshToken = resp.refresh_token; | ||||||
|  |         vm.ropSession = resp; | ||||||
|  |         vm.ropToken = resp.token; | ||||||
|  | 
 | ||||||
|  |         vm.fn.updateUrls(); // vm.api.urls.resourceOwnerPassword(); also grants
 | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     vm.api.jwt.decode = function () { | ||||||
|  |       vm.ropToken = OAUTH3.jwt.decode(vm.form.accessToken || vm.accessToken); | ||||||
|  |     }; | ||||||
|  |     vm.api.jwt.decodeRefresh = function () { | ||||||
|  |       vm.ropToken = OAUTH3.jwt.decode(vm.form.refreshToken || vm.refreshToken); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     vm.api.providerUri = function () { | ||||||
|  |       console.log('[DEBUG] providerUri:', vm.providerUri); | ||||||
|  |       try { | ||||||
|  |         vm.providerUri = OAUTH3.uri.normalize(vm.providerUri); | ||||||
|  |         vm.conf.provider_uri = vm.providerUri; | ||||||
|  |       } catch(e) { | ||||||
|  |         vm.error = e; | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     vm.api.clientUri = function () { | ||||||
|  |       console.log('[DEBUG] clientUri:', vm.clientUri); | ||||||
|  |       try { | ||||||
|  |         vm.clientUri = OAUTH3.clientUri({ host: vm.clientUri }); | ||||||
|  |         if (vm.clientUri) { | ||||||
|  |       console.log('[DEBUG] clientUri:', vm.clientUri); | ||||||
|  |           vm.conf.client_uri = vm.clientUri; | ||||||
|  |           vm.conf.client_id = vm.clientUri; | ||||||
|  |         } | ||||||
|  |       } catch(e) { | ||||||
|  |         vm.error = e; | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     vm.api._discoverCount = 0; | ||||||
|  |     vm.api.urls.implicitGrant = function (provider) { | ||||||
|  |       if (!vm.directives) { | ||||||
|  |         console.log('[DEBUG] skipping implicit grant due to missing directives'); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       var opts = { | ||||||
|  |         client_uri: vm.conf.client_uri | ||||||
|  |       , subject: vm.form.subject || undefined | ||||||
|  |       , debug: vm.conf.debug || undefined | ||||||
|  |       , scope: vm.form.scopes || undefined | ||||||
|  |       }; | ||||||
|  |       var implicitGrantObj = OAUTH3.urls.implicitGrant(vm.directives, opts); | ||||||
|  |       vm.urls.implicitGrant = vm.implicitGrantUrl = (OAUTH3.url.normalize(provider || vm.form.provider) + '/' + implicitGrantObj.url).replace(implicitGrantObj.state, '{{random}}'); | ||||||
|  |     } | ||||||
|  |     vm.api.discover = function () { | ||||||
|  |       vm.directives = null; | ||||||
|  |       vm.validated.provider = ''; | ||||||
|  |       vm.api._discoverCount += 1; | ||||||
|  |       var latest = vm.api._discoverCount; | ||||||
|  |       var provider = vm.form.provider; // shouldn't be mutable during this time but...
 | ||||||
|  | 
 | ||||||
|  |       vm.fn.lock(); | ||||||
|  | 
 | ||||||
|  |       vm.discoveryObj = OAUTH3.urls.discover(provider, vm.conf); | ||||||
|  |       vm.urls.directives = vm.directivesUrl = OAUTH3.url.normalize(provider) + '/' + vm.discoveryObj.query._pathname; | ||||||
|  |       vm.urls.discovery = vm.discoveryUrl = vm.discoveryObj.method + ' ' + vm.discoveryObj.url; | ||||||
|  | 
 | ||||||
|  |       console.log('about to discover'); | ||||||
|  | 
 | ||||||
|  |       return OAUTH3.discover(provider, vm.conf).then(function (dir) { | ||||||
|  |         if (latest !== vm.api._discoverCount) { | ||||||
|  |           console.log('[DEBUG] ignoring stale discover response for', provider); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         console.log('[DEBUG] directives:'); | ||||||
|  |         console.log(dir); | ||||||
|  |         vm.validated.provider = provider; | ||||||
|  |         vm.directives = dir; | ||||||
|  | 
 | ||||||
|  |         vm.api.urls.implicitGrant(provider); | ||||||
|  |         //JSON.stringify(dir, null, 2);
 | ||||||
|  |       }, function (err) { | ||||||
|  |         vm.form.provider = vm.defaults.provider; | ||||||
|  |         vm.validated.provider = vm.defaults.provider; | ||||||
|  |         vm.directives = vm.defaults.directives; | ||||||
|  |         if (latest !== vm.api._discoverCount) { | ||||||
|  |           console.warn('[DEBUG] ignoring stale discover error for', provider); | ||||||
|  |           console.warn(err); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         console.log('error on discover'); | ||||||
|  |         vm.error = err; | ||||||
|  |       }).then(function () { | ||||||
|  |         vm.fn.unlock(); | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  |     vm.api.urls.scope = function () { | ||||||
|  |       // TODO do something like this in the oauth3 library
 | ||||||
|  |       vm.urls.scope = 'https://:host/.well-known/oauth3/scopes/:scope.json\nhttps://example.com/.well-known/oauth3/scopes/example@oauth3.org.json\n\n' | ||||||
|  |         + 'GET https://example.com/.well-known/oauth3/#/?action=scope&state={{random}}&redirect_uri=https%3A%2F%2Fsso.hellabit.com%2F.well-known%2Foauth3%2Fcallback.html%23%2F&response_type=rpc&_method=GET&_pathname=.well-known%2Foauth3%2Fscopes%2Fexample@oauth3.org.json'; | ||||||
|  |     }; | ||||||
|  |     vm.api.discoverScopes = function () { | ||||||
|  |       var scopes = vm.form.scopes && vm.form.scopes.split(',') || []; | ||||||
|  |       vm.scopesObj = []; | ||||||
|  | 
 | ||||||
|  |       function nextScope() { | ||||||
|  |         var scopename = scopes.shift(); | ||||||
|  |         if (!scopename) { | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // something like https://example.com/.well-known/oauth3.org/scopes/:scopename.json
 | ||||||
|  |         var scopeUrlObj = OAUTH3.urls.discoverScope(vm.form.provider, { | ||||||
|  |           client_uri: vm.conf.client_uri | ||||||
|  |         , scope: scopename | ||||||
|  |         , debug: vm.conf.debug || undefined | ||||||
|  |         }); | ||||||
|  |         vm.urls.scope = vm.scopeUrl = OAUTH3.url.normalize(provider) + '/' + scopeUrlObj.query._pathname; | ||||||
|  | 
 | ||||||
|  |         // something like the discovery url that loads in an iframe
 | ||||||
|  |         var discoverScopeObj = OAUTH3.urls.discoverScope(vm.form.provider, { | ||||||
|  |           client_uri: vm.conf.client_uri | ||||||
|  |         , scope: scopename | ||||||
|  |         , debug: vm.conf.debug || undefined | ||||||
|  |         }); | ||||||
|  |         vm.urls.discoverScope = vm.discoverScopeUrl = OAUTH3.url.normalize(provider) + '/' + discoverScopeObj.url; | ||||||
|  | 
 | ||||||
|  |         // Go and fetch!
 | ||||||
|  |         return OAUTH3.discoverScopes(vm.form.provider, { | ||||||
|  |           client_uri: vm.conf.client_uri | ||||||
|  |         , scope: scopename | ||||||
|  |         , debug: vm.conf.debug || undefined | ||||||
|  |         }).then(function (scope) { | ||||||
|  |           var allScopes = {}; | ||||||
|  |           vm.scopesObj.push(scope); | ||||||
|  |           vm.defaults.scopes.push(scope); | ||||||
|  |           vm.defaults.scopes = vm.defaults.scopes.filter(function (scope) { | ||||||
|  |             if (allScopes[scope.name]) { | ||||||
|  |               return false; | ||||||
|  |             } | ||||||
|  |             allScopes[scope.name] = true; | ||||||
|  |             return true; | ||||||
|  |           }); | ||||||
|  |         }, function (err) { | ||||||
|  |           console.error("Error in discover scope:"); | ||||||
|  |           console.error(err); | ||||||
|  |           vm.scopesObj.push({ name: scopename, desc: "Error, not found" }); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return nextScope(); | ||||||
|  |     }; | ||||||
|  |     vm.api.implicitGrant = function () { | ||||||
|  |       var provider = vm.validated.provider; | ||||||
|  |       var opts = { | ||||||
|  |         client_uri: vm.conf.client_uri | ||||||
|  |       , subject: vm.form.subject || undefined | ||||||
|  |       , debug: vm.conf.debug || undefined | ||||||
|  |       , scope: vm.form.scopes || undefined | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       console.log('[DEBUG] vm.directives'); | ||||||
|  |       console.log(vm.directives); | ||||||
|  |       vm.implicitGrantObj = OAUTH3.urls.implicitGrant(vm.directives, opts); | ||||||
|  |       console.log('[DEBUG] vm.implicitGrantObj'); | ||||||
|  |       console.log(vm.implicitGrantObj); | ||||||
|  |       vm.urls.implicitGrant = vm.implicitGrantUrl = (OAUTH3.url.normalize(provider) + '/' + vm.implicitGrantObj.url); | ||||||
|  |       return OAUTH3.implicitGrant(vm.directives, opts).then(function (session) { | ||||||
|  |         vm.session = session; | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     vm.urls.profile = {}; | ||||||
|  |     vm.api.urls.profile_get = function () { | ||||||
|  |       if (!vm.directives || !vm.accessToken) { return; } | ||||||
|  |       vm.urls.profile_get = OAUTH3.urls.accounts.get(vm.directives, vm.ropSession); | ||||||
|  |     }; | ||||||
|  |     vm.api.profile = {}; | ||||||
|  |     vm.api.profile_get = function () { | ||||||
|  |       console.log('you tickled me!', vm.ropSession); | ||||||
|  |       vm.api.urls.profile_get(); | ||||||
|  |       return OAUTH3.requests.accounts.get(vm.directives, vm.ropSession).then(function (resp) { | ||||||
|  |         console.log('you tickled me twice!'); | ||||||
|  |         if (!resp.data) { | ||||||
|  |           resp = { status: 0, data: resp }; | ||||||
|  |         } | ||||||
|  |         vm.responses.profile_get = resp; | ||||||
|  |       }, function (err) { | ||||||
|  |         console.error('Could not get profile:'); | ||||||
|  |         console.error(err); | ||||||
|  |         vm.error = err; | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  |     vm.api.profile_set = function () { | ||||||
|  |       console.log('you tickled me!', vm.ropSession); | ||||||
|  |       vm.api.urls.profile_set(); | ||||||
|  |       return OAUTH3.requests.accounts.set(vm.directives, vm.ropSession).then(function (resp) { | ||||||
|  |         console.log('you tickled me twice!'); | ||||||
|  |         if (!resp.data) { | ||||||
|  |           resp = { status: 0, data: resp }; | ||||||
|  |         } | ||||||
|  |         vm.responses.profile_set = resp; | ||||||
|  |       }, function (err) { | ||||||
|  |         console.error('Could not set profile:'); | ||||||
|  |         console.error(err); | ||||||
|  |         vm.error = err; | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     vm.api.authz = {}; | ||||||
|  |     vm.api.authz._grantsOpts = function () { | ||||||
|  |       return vm.api.authz._grantsOpts_ = { | ||||||
|  |         method: 'GET' | ||||||
|  |       , client_id: vm.conf.client_id | ||||||
|  |       , client_uri: vm.conf.client_uri | ||||||
|  |       , session: vm.ropSession | ||||||
|  |       , debug: vm.conf.debug | ||||||
|  |       , all: true | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |     vm.api.urls.grants = function () { | ||||||
|  |       if (!vm.directives || !vm.ropSession || !vm.form.id) { return; } | ||||||
|  |       vm.urls.grants = OAUTH3.urls.grants(vm.directives, vm.api.authz._grantsOpts()); | ||||||
|  |     }; | ||||||
|  |     vm.api.authz.grants = function () { | ||||||
|  |       vm.fn.updateUrls(); // vm.api.urls.grants();
 | ||||||
|  |       return OAUTH3.authz.grants(vm.form.provider, vm.api.authz._grantsOpts()).then(function (resp) { | ||||||
|  |         vm.responses.grants = { status: 0, data: resp }; | ||||||
|  |         vm.fn.updateUrls(); // vm.api.urls.grants();
 | ||||||
|  |       }, function (err) { | ||||||
|  |         console.error('[error] authz.grants:'); | ||||||
|  |         console.error(err); | ||||||
|  |         vm.error = err; | ||||||
|  |       }); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     vm.form.provider = vm.defaults.provider; | ||||||
|  |     vm.validated.provider = vm.defaults.provider; | ||||||
|  |     vm.api.discover().then(function () { | ||||||
|  |       vm.defaults.directives = vm.directives; | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     vm.fn.updateScopes(); | ||||||
|  | 
 | ||||||
|  |     vm.apistr = ''; | ||||||
|  |     Object.keys(OAUTH3).forEach(function (key) { | ||||||
|  |       var thingy = OAUTH3[key]; | ||||||
|  | 
 | ||||||
|  |       if ('_' === key[0] || -1 !== [ 'create', '_browser', '_defaultStorage', 'hooks', '_hooks', '_digest' ].indexOf(key)) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ('function' === typeof thingy) { | ||||||
|  |         vm.apistr += thingy.toString().split(/\n/)[0].replace('function ', 'OAUTH3.' + key).replace(/\s+{\s*/, '') + '\n'; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ('object' === typeof thingy) { | ||||||
|  |         Object.keys(thingy).forEach(function (key2) { | ||||||
|  |           var thingy2 = thingy[key2]; | ||||||
|  |           if ('function' === typeof thingy2) { | ||||||
|  |             vm.apistr += thingy2.toString().split(/\n/)[0].replace('function ', 'OAUTH3.' + key + '.' + key2).replace(/\s+{\s*/, '') + '\n'; | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           if ('object' === typeof thingy2) { | ||||||
|  |             Object.keys(thingy2).forEach(function (key3) { | ||||||
|  |               var thingy3 = thingy2[key3]; | ||||||
|  |               if ('function' === typeof thingy3) { | ||||||
|  |                 vm.apistr += thingy3.toString().split(/\n/)[0].replace('function ', 'OAUTH3.' + key + '.' + key2 + '.' + key3).replace(/\s+{\s*/, '') + '\n'; | ||||||
|  |               } | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } ] ); | ||||||
|  | }()); | ||||||
| @ -40,21 +40,18 @@ $('body').on('click', '.js-remember-label', function (ev) { | |||||||
|   var $this = $(this); |   var $this = $(this); | ||||||
|   if ($this.find('.js-remember-checkbox').is(':checked') === true) { |   if ($this.find('.js-remember-checkbox').is(':checked') === true) { | ||||||
|     $this.find('.js-remember-checkbox').prop( "checked", false ); |     $this.find('.js-remember-checkbox').prop( "checked", false ); | ||||||
|  |     $this.find('.js-remember-status').attr("src", "./img/unpressed-check.png"); | ||||||
|   } else { |   } else { | ||||||
|     $this.find('.js-remember-checkbox').prop( "checked", true ); |     $this.find('.js-remember-checkbox').prop( "checked", true ); | ||||||
|  |     $this.find('.js-remember-status').attr("src", "./img/pressed-check.png"); | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| $('body').on('click', '.check', function () { |  | ||||||
|   'use strict'; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| $('body').on('click', '.js-auth-li-enabled', function (ev) { | $('body').on('click', '.js-auth-li-enabled', function (ev) { | ||||||
|   'use strict'; |   'use strict'; | ||||||
|   ev.preventDefault(); |   ev.preventDefault(); | ||||||
|   ev.stopPropagation(); |   ev.stopPropagation(); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|   var $this = $(this); |   var $this = $(this); | ||||||
|   var $hiddenCheckbox = $this.find('.js-auth-checkbox'); |   var $hiddenCheckbox = $this.find('.js-auth-checkbox'); | ||||||
|   var $img = $this.find('.check'); |   var $img = $this.find('.check'); | ||||||
|  | |||||||
							
								
								
									
										616
									
								
								playground.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										616
									
								
								playground.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,616 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |   <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|  |     <title>Login Facilitator: OAuth3.org</title> | ||||||
|  |     <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css"> | ||||||
|  |     <!-- <link rel="stylesheet" type="text/css" href="/css/style.css"> --> | ||||||
|  |     <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Lato:300"> | ||||||
|  |     <script src="https://use.fontawesome.com/3af0faae66.js"></script> | ||||||
|  |     <!-- link rel="stylesheet" type="text/css" href="/css/daplie-installer-overrides.css" --> | ||||||
|  |   </head> | ||||||
|  | 
 | ||||||
|  |   <body> | ||||||
|  | 
 | ||||||
|  |   <div class="fade in js-playground" ng-app="oauth3Playground" ng-strict> | ||||||
|  |     <div ng-controller="PlaygroundCtrl as vm"> | ||||||
|  |       <div class="container"> | ||||||
|  |         <div class="jumbotron"> | ||||||
|  |           <h1>OAuth3 Playground</h1> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <h2>Go ahead, test our login</h2> | ||||||
|  | 
 | ||||||
|  |             <div ng-if="vm.error" class="alert alert-warning"><span ng-bind="vm.error.message"></span><button class="btn btn-danger pull-right" type="button" ng-click="vm.error = null">X</button></div> | ||||||
|  |             <div ng-if="vm._working" class="alert alert-info"> | ||||||
|  |               <marquee>taking my sweet time to do something in the background...</marquee> | ||||||
|  |             </div> | ||||||
|  |             <div ng-if="vm.validated.provider" class="alert alert-success"><span ng-bind="vm.validated.provider"></span> will be used as the login issuer</div> | ||||||
|  | 
 | ||||||
|  |             <label>Address:</label> | ||||||
|  |             <input type="text" placeholder="ex: john@example.com (optional)" class="form-control" ng-model="vm.form.id" ng-change="vm.fn.changeUser()"> | ||||||
|  |             <label ng-if="vm.advanced">Identity Issuer:</label> | ||||||
|  |             <input ng-if="vm.advanced" type="text" class="form-control" ng-model="vm.form.provider" placeholder="ex: sso.example.com (required)" ng-change="vm.fn.changeProvider()"> | ||||||
|  |             <button class="btn btn-link" ng-if="!vm.advanced" ng-click="vm.fn.toggleAdvanced()">open advanced</button> | ||||||
|  |             <button class="btn btn-link" ng-if="vm.advanced" ng-click="vm.fn.toggleAdvanced()">close advanced</button> | ||||||
|  |             <button class="btn btn-primary" ng-click="vm.api.implicitGrant()" ng-disabled="!vm.validated.provider">Login</button> | ||||||
|  |             <label><input type="checkbox" ng-model="vm.conf.debug" ng-change="vm.fn.updateDebug()"/> Debug OAuth3 Flow?</label> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <br/> | ||||||
|  |             <br/> | ||||||
|  |             <br/> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <h2>Debug & Status Info:</h2> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <h3>JavaScript Framework</h3> | ||||||
|  |             <small>(yes, real runs-in-a-web-browser - and even on Android - ES5.1)</small> | ||||||
|  |             <br> | ||||||
|  |             <label><input name="framework" type="radio" ng-model="vm.framework" ng-value="'none'"/> ES5.1</label> (no framework) | ||||||
|  |             <label><input name="framework" type="radio" ng-model="vm.framework" ng-value="'jquery'"/> jQuery</label> | ||||||
|  |             <label><input name="framework" type="radio" ng-model="vm.framework" ng-value="'angularjs'"/> AngularJS</label> | ||||||
|  |             <label><input name="framework" type="radio" ng-model="vm.framework" ng-value="'nodejs'"/> node.js</label> | ||||||
|  |             <br> | ||||||
|  | 
 | ||||||
|  |             <label><input name="framework" type="checkbox" checked="checked" disabled="disabled"/> azp<small>@oauth3.org</small></label> | ||||||
|  |             <label><input name="framework" type="checkbox" ng-model="vm.components.issuer"/> issuer<small>@oauth3.org</small></label> | ||||||
|  |             <br> | ||||||
|  | 
 | ||||||
|  |             <pre ng-if="'nodejs' === vm.framework"><code>var OAUTH3 = require('oauth3.org');</code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre ng-if="'nodejs' !== vm.framework"><code><script src="/assets/oauth3.org/oauth3.core.js"></script><span ng-if="vm.components.issuer"> | ||||||
|  | <script src="/assets/oauth3.org/oauth3.crypto.js"></script> | ||||||
|  | <script src="/assets/oauth3.org/oauth3.issuer.js"></script></span><span | ||||||
|  | ng-if="'none' === vm.framework || 'jquery' === vm.framework"></span><span ng-if="'angularjs' === vm.framework"> | ||||||
|  | <script src="/assets/oauth3.org/oauth3.ng.js"></script></span> | ||||||
|  | </code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Client URI</strong>: <span ng-bind="vm.conf.client_uri"></span> | ||||||
|  |             <br> | ||||||
|  |             (this is the URL of the application as per window.location.href) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <input class="form-input" type="text" ng-model="vm.clientUri"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.clientUri()">Set</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.clientUri({ host: "<span ng-bind="vm.clientUri"></span>", port: null, pathname: '/' });</code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Subject</strong>: <span ng-bind="vm.form.subject"></span> | ||||||
|  |             <br> | ||||||
|  |             (this is either the subject portion or whole address of subject@issuer) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <input class="form-input" type="text" ng-model="vm.form.id"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.fn.changeUser()">Set</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>address: <span ng-bind="vm.form.id"></span></code></pre> | ||||||
|  |             <pre><code>subject: <span ng-bind="vm.form.subject"></span></code></pre> | ||||||
|  |             <pre><code>issuer: <span ng-bind="vm.form.userProvider"></span></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Issuer URI</strong>: <span ng-bind="vm.validated.provider"></span> | ||||||
|  |             <br> | ||||||
|  |             (this is the URL part of subject@issuer) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <input class="form-input" type="text" ng-model="vm.form.provider"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.fn.changeProvider()">Set</button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Directives Discovery</strong>: | ||||||
|  |             <br> | ||||||
|  |             (this is how we learn if a server support oauth3 and to what extent) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.fn.changeProvider()">Discover Directives</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.discover("<span ng-bind="vm.form.provider"></span>", opts);</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.directives"><code><span ng-bind="vm.urls.directives"></span></code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.discover("<span ng-bind="vm.form.provider"></span>", opts);</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.discovery"><code><span ng-bind="vm.urls.discovery"></span></code></pre> | ||||||
|  | 
 | ||||||
|  |             <div ng-if="vm.directives"> | ||||||
|  |               <button ng-if="vm.state.hideDirectives" class="btn btn-link" ng-click="vm.state.hideDirectives = !vm.state.hideDirectives">show directives</button> | ||||||
|  |               <button ng-if="!vm.state.hideDirectives" class="btn btn-link" ng-click="vm.state.hideDirectives = !vm.state.hideDirectives">hide directives</button> | ||||||
|  |               <pre ng-if="!vm.state.hideDirectives"><code><span ng-bind="vm.directives | json"></span></code></pre> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Scopes</strong>: <span ng-bind="vm.form.scopes"></span> | ||||||
|  |             <br> | ||||||
|  |             (these are used to lookup the descriptions of grant permissions) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <input class="form-input" type="text" ng-model="vm.form.scopes" placeholder="ex: authn@oauth3.org,photos@example.com,dns@domains.org"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.discoverScopes()" ng-disabled="!vm.form.scopes">Discover Scopes</button> | ||||||
|  | 
 | ||||||
|  |             <ul> | ||||||
|  |               <li ng-repeat="scope in vm.defaults.scopes"> | ||||||
|  |                 <label> | ||||||
|  |                   <input type="checkbox" ng-model="scope.checked" ng-change="vm.fn.updateScopes()"/> | ||||||
|  |                   <strong ng-bind="scope.name">name</strong> | ||||||
|  |                 </label> | ||||||
|  |                 <span ng-bind="scope.desc">desc</span> | ||||||
|  |               </li> | ||||||
|  |             </ul> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.scope(directives, opts);</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.scope"><code><span ng-bind="vm.urls.scope"></span></code></pre> | ||||||
|  |             <pre ng-if="vm.urls.discoverScope"><code><span ng-bind="vm.urls.discoverScope"></span></code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.discoverScopes(directives, opts);</code></pre> | ||||||
|  | 
 | ||||||
|  |             <button ng-if="vm.scopesObj" class="btn btn-default" ng-click="vm.fn.clearScopes()">[X]</button> | ||||||
|  |             <pre ng-if="vm.scopesObj"><code><span ng-bind="vm.scopesObj | json"></span></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Authorization Dialog URL</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is what opens the login dialog box with the checkboxes and such) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.implicitGrant()" ng-disabled="!vm.directives || !vm.validated.provider">Open Authorization Dialog</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.implicitGrant(directives, opts);</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.implicitGrant"><code><span ng-bind="vm.urls.implicitGrant"></span></code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.implicitGrant(directives, opts);</code></pre> | ||||||
|  | 
 | ||||||
|  |             <button ng-if="vm.session" class="btn btn-default" ng-click="vm.fn.clearSession()">[X]</button> | ||||||
|  |             <pre ng-if="vm.session"><code><span ng-bind="vm.session | json"></span></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Refresh Token URL</strong> | ||||||
|  |             <br> | ||||||
|  |             (This is the URL of the iFrame that completes token refreshes. And it occurs over iFrame rather than API so that no server is required.) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.refreshToken()" ng-disabled="!vm.directives || !vm.validated.provider">Refresh Token</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.refreshToken(directives, opts);</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.refreshToken"><code><span ng-bind="vm.urls.refreshToken"></span></code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.refreshToken(directives, opts);</code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Logout Dialog URL</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is what opens the logout dialog) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.logout()" ng-disabled="!vm.directives || !vm.validated.provider">Open Logout Dialog</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.logout(directives, opts);</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.logout"><code><span ng-bind="vm.urls.logout"></span></code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.logout(directives, opts);</code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <h2>1st Party and App Login</h2> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Credential Meta URL</strong> | ||||||
|  |             <br> | ||||||
|  |             <strong>(Not implemented... anymore)</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the endpoint that reports if the user exists and what their proof-strategy is) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.authn.credentialMeta()" ng-disabled="true || !vm.directives || !vm.form.id">Check user details</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.authn.loginMeta(directives, { email: "<span ng-bind="vm.form.id"></span>" });</code></pre> | ||||||
|  |             <pre ng-if="vm.urls.credentialMeta"><code><span ng-bind="vm.urls.credentialMeta"></span></code></pre> | ||||||
|  |             <pre ng-if="vm.responses.credentialMeta"><code><span ng-bind="vm.responses.credentialMeta"></span></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Credential OTP URL</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the URL that sends your one-time password via email) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.authn.otp()" ng-disabled="!vm.directives || !vm.form.id">Send OTP to user</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.authn.otp(directives, { email: "<span ng-bind="vm.form.id"></span>" });</code></pre> | ||||||
|  |             <div ng-if="vm.urls.otp"> | ||||||
|  |               <pre><code><span ng-bind="vm.urls.otp.method"></span> <span ng-bind="vm.urls.otp.url"></span> | ||||||
|  | <span ng-if="vm.urls.otp.headers" ng-bind="vm.urls.otp.headers | json"></span> | ||||||
|  | <span ng-bind="vm.urls.otp.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |               <pre ng-if="vm.responses.otp"><code><span ng-bind="vm.responses.otp.status"></span> | ||||||
|  | <span ng-if="vm.responses.otp.headers" ng-bind="vm.responses.otp.headers | json"></span> | ||||||
|  | <span ng-bind="vm.responses.otp.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Resource Owner Password URL</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the URL that native apps and APIs use to login) | ||||||
|  |             <br> | ||||||
|  |             (it's also a bit of a misnomer, it should be *proof* rather than password) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <input class="form-input" type="text" ng-model="vm.form.otpCode" ng-change="vm.api.urls.resourceOwnerPassword()" placeholder="ex: XXXX-XXXX-XXXX"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.authn.resourceOwnerPassword()" ng-disabled="!vm.form.otpUuid || !vm.form.otpCode">Exchange Proof for Session</button> | ||||||
|  | 
 | ||||||
|  |             <br> | ||||||
|  |             <input class="form-input disabled" type="text" ng-model="vm.form.otpUuid" disabled> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.resourceOwnerPassword(directives, opts);</code></pre> | ||||||
|  |             <div ng-if="vm.urls.resourceOwnerPassword"> | ||||||
|  |               <pre><code><span ng-bind="vm.urls.resourceOwnerPassword.method"></span> <span ng-bind="vm.urls.resourceOwnerPassword.url"></span> | ||||||
|  | <span ng-if="vm.urls.resourceOwnerPassword.headers" ng-bind="vm.urls.resourceOwnerPassword.headers | json"></span> | ||||||
|  | <span ng-bind="vm.urls.resourceOwnerPassword.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.authn.resourceOwnerPassword(directives, <span ng-bind="vm.api.authn._ropOpts_ || 'opts'"></span>);</code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Session</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the object that contains meta data about the session, including the access token itself) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  | 
 | ||||||
|  |             <pre ng-if="vm.responses.resourceOwnerPassword"><code><span ng-bind="vm.responses.resourceOwnerPassword.status"></span> | ||||||
|  | <span ng-if="vm.responses.resourceOwnerPassword.headers" ng-bind="vm.responses.resourceOwnerPassword.headers | json"></span> | ||||||
|  | <span ng-bind="vm.responses.resourceOwnerPassword.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  | 
 | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Profile</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the profile object) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  | 
 | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.profile_get()" ng-disabled="!vm.accessToken">Get Profile</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code><span ng-bind="vm.urls.profile_get.method"></span> <span ng-bind="vm.urls.profile_get.url"></span> | ||||||
|  | <span ng-if="vm.urls.profile_get.headers" ng-bind="vm.urls.profile_get.headers | json"></span> | ||||||
|  | <span ng-bind="vm.urls.profile_get.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre ng-if="!vm.responses.profile_get"><code> ... | ||||||
|  | </code></pre> | ||||||
|  | 
 | ||||||
|  |             <pre ng-if="vm.responses.profile_get"><code><span ng-bind="vm.responses.profile_get.status"></span> | ||||||
|  | <span ng-if="vm.responses.profile_get.headers" ng-bind="vm.responses.profile_get.headers | json"></span> | ||||||
|  | <span ng-bind="vm.responses.profile_get.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  | 
 | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Access Token</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the access token) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <pre><code>OAUTH3.jwt.decode(token);</code></pre> | ||||||
|  | 
 | ||||||
|  |             <textarea class="form-control" ng-model="vm.accessToken" ng-change="vm.api.jwt.decode()"></textarea> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.jwt.decode()" ng-disabled="!vm.accessToken">Decode Access Token</button> | ||||||
|  | 
 | ||||||
|  |             <textarea ng-if="vm.refreshToken" class="form-control" ng-model="vm.refreshToken" ng-change="vm.api.jwt.decodeRefresh()"></textarea> | ||||||
|  |             <button ng-if="vm.refreshToken" class="btn btn-default" ng-click="vm.api.jwt.decodeRefresh()" ng-disabled="!vm.refreshToken">Decode Refresh Token</button> | ||||||
|  | 
 | ||||||
|  |             <pre ng-if="vm.ropToken"><code ng-bind="vm.ropToken | json"></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Token Issuer's Public Key</strong> | ||||||
|  |             <br> | ||||||
|  |             <strong>(not implemented)</strong> | ||||||
|  |             <br> | ||||||
|  |             (this is the URL that inspects and verifies the token) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.authn.jwk()" ng-disabled="!vm.directives">Fetch Token Issuer's Public Key</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.authn.jwk(directives, token);</code></pre> | ||||||
|  | 
 | ||||||
|  |             <div ng-if="vm.urls.jwk"> | ||||||
|  |               <pre><code><span ng-bind="vm.urls.jwk.method"></span> <span ng-bind="vm.urls.jwk.url"></span> | ||||||
|  | <span ng-if="vm.urls.jwk.headers" ng-bind="vm.urls.jwk.headers | json"></span> | ||||||
|  | <span ng-bind="vm.urls.jwk.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |               <pre ng-if="vm.responses.jwk"><code><span ng-bind="vm.responses.jwk.status"></span> | ||||||
|  | <span ng-if="vm.responses.jwk.headers" ng-bind="vm.responses.jwk.headers | json"></span> | ||||||
|  | <span ng-bind="vm.responses.jwk.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  | 
 | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Verify JWT</strong> | ||||||
|  |             <br> | ||||||
|  |             <strong>(not implemented)</strong> | ||||||
|  |             <br> | ||||||
|  |             (ppids can be verified via the public key of the issuer) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <label>JWK</label> | ||||||
|  |             <textarea class="form-control" ng-model="vm.responses.jwk.data"></textarea> | ||||||
|  |             <br> | ||||||
|  |             <label>Access Token</label> | ||||||
|  |             <textarea class="form-control" ng-model="vm.accessToken"></textarea> | ||||||
|  |             <br> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.jwt.verify()" ng-disabled="!vm.accessToken || !vm.responses.jwk.data">Verify JWT</button> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.jwt.verify(token, jwk);</code></pre> | ||||||
|  |             <pre><code><span ng-bind="vm.responses.verify"></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row" ng-if="vm.validated.provider"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Exchange Opaque Token</strong> | ||||||
|  |             <br> | ||||||
|  |             <strong>(not implemented)</strong> | ||||||
|  |             <br> | ||||||
|  |             (Opaque tokens are issued serverside - like a traditional OAuth2 token - and do not contain a subject and, therefore, cannot identify a user directly. | ||||||
|  |             They may be used by multiple audiences client-side, but must be exchanged by authorized parties for a ppid access token to verify identity serverside. | ||||||
|  |             They can be refreshed without changing the JTI.) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <textarea class="form-control" ng-model="vm.form.opaqueToken"></textarea> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.authz.exchange()" ng-disabled="!vm.directives || !vm.responses.jwk.data">Exchange Opaque Token</button> | ||||||
|  |             <textarea ng-if="vm.refreshToken" class="form-control" ng-model="vm.refreshToken"></textarea> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.authz.exchange(directives, token);</code></pre> | ||||||
|  |             <div ng-if="vm.urls.exchange"> | ||||||
|  |               <pre><code><span ng-bind="vm.urls.exchange.method"></span> <span ng-bind="vm.urls.exchange.url"></span> | ||||||
|  | <span ng-if="vm.urls.exchange.headers" ng-bind="vm.urls.exchange.headers | json"></span> | ||||||
|  | <span ng-bind="vm.urls.exchange.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |               <pre ng-if="vm.responses.exchange"><code><span ng-bind="vm.responses.exchange.status"></span> | ||||||
|  | <span ng-if="vm.responses.exchange.headers" ng-bind="vm.responses.exchange.headers | json"></span> | ||||||
|  | <span ng-bind="vm.responses.exchange.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <br> | ||||||
|  |           <br> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             <strong>Approved Apps</strong> | ||||||
|  |             <br> | ||||||
|  |             (these are the public keys generated on remember-me devices and the opaque tokens issued to remember-me-not devices) | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             <button class="btn btn-default" ng-click="vm.api.authz.grants()" ng-disabled="!vm.form.accessToken">List App Grants</button> | ||||||
|  |             <br> | ||||||
|  | 
 | ||||||
|  |             <pre><code>OAUTH3.urls.grants(directives, opts);</code></pre> | ||||||
|  |             <pre><code>OAUTH3.authz.grants(directives, <span ng-bind="vm.api.authz._grantsOpts_"></span>);</code></pre> | ||||||
|  | 
 | ||||||
|  |             <div ng-if="vm.urls.grants"> | ||||||
|  |               <pre><code><span ng-bind="vm.urls.grants.method"></span> <span ng-bind="vm.urls.grants.url"></span> | ||||||
|  | <span ng-if="vm.urls.grants.headers" ng-bind="vm.urls.grants.headers | json"></span> | ||||||
|  | <span ng-bind="vm.urls.grants.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |               <pre ng-if="vm.responses.grants"><code><span ng-bind="vm.responses.grants.status"></span> | ||||||
|  | <span ng-if="vm.responses.grants.headers" ng-bind="vm.responses.grants.headers | json"></span> | ||||||
|  | <span ng-bind="vm.responses.grants.data | json"></span> | ||||||
|  | </code></pre> | ||||||
|  |             </div> | ||||||
|  |             ... | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-3"> | ||||||
|  |             Approved Applications: | ||||||
|  |           </div> | ||||||
|  |           <div class="col-md-9"> | ||||||
|  |             ... | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <br/> | ||||||
|  |             <br/> | ||||||
|  |             <br/> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <h2>Live API</h2> | ||||||
|  |             <small>these are what's actually on the object</small> | ||||||
|  | 
 | ||||||
|  |             <pre><code ng-bind="vm.apistr"></code></pre> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="row"> | ||||||
|  |           <div class="col-md-12"> | ||||||
|  |             <h2>Docs</h2> | ||||||
|  | 
 | ||||||
|  |             <p>0. Include the Library | ||||||
|  |             <pre><code># Browsers | ||||||
|  |   <script src="oauth3.core.js"></script> | ||||||
|  |   var OAUTH3 = window.OAUTH3; | ||||||
|  | 
 | ||||||
|  |   # Node.js | ||||||
|  |   var OAUTH3 = require('oauth3.js').OAUTH3; | ||||||
|  |   </code></pre> | ||||||
|  | 
 | ||||||
|  |             <p>1. Establish the Client ID by its URI | ||||||
|  |             <pre><code># Browsers | ||||||
|  |   var clientUri = OAUTH3.clientUri(window.location); // example.com | ||||||
|  | 
 | ||||||
|  |   # Node.js | ||||||
|  |   var clientUri = OAUTH3.clientUri("https://example.com"); // example.com | ||||||
|  |   </code></pre> | ||||||
|  | 
 | ||||||
|  |             <p>2. Provide promisable storage hooks for saving sessions and caching directives | ||||||
|  |             <pre><code>OAUTH3._hooks = { | ||||||
|  |     directives: { | ||||||
|  |       get: function (providerUri) { ... } | ||||||
|  |     , set: function (providerUri, directives) { ... } | ||||||
|  |     , all: function () { ... } | ||||||
|  |     , clear: function () { ... } | ||||||
|  |   , sessions: { | ||||||
|  |       get: function (providerUri, id) { ... } | ||||||
|  |     , set: function (providerUri, newSession, id) { ... } | ||||||
|  |     , all: function (providerUri) { ... } | ||||||
|  |     , clear: function (providerUri) { ... } | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |   </code></pre> | ||||||
|  |             SECURITY: The default storage engine is window.sessionStorage. Session storage | ||||||
|  |             should be used for app:// urls and localhost urls and other applications | ||||||
|  |             in which the identity of the app is ephemeral, arbitrary, or not distinct. | ||||||
|  | 
 | ||||||
|  |             <p><h4>3. Check to see if the user already has a session</h4> | ||||||
|  |             <pre><code>OAUTH3.hooks.session.get(providerUri).then(function (session) { | ||||||
|  |     console.log('[DEBUG] session:'); | ||||||
|  |     console.log(session); | ||||||
|  |   }); | ||||||
|  |   OAUTH3.hooks.session.all().then(function (sessions) { | ||||||
|  |     console.log('[DEBUG] all sessions:'); | ||||||
|  |     console.log(sessions); | ||||||
|  |   }); | ||||||
|  |   </code></pre> | ||||||
|  |             Note: expired sessions should not be returned and stale sessions should be refreshed | ||||||
|  | 
 | ||||||
|  |             <p>4. Prompt the user for their address and perform the lookup to see if it | ||||||
|  |             has a provider. | ||||||
|  |             <pre><code>var providerUri = address.split('@')[1] || address; | ||||||
|  |   var opts = { client_uri: clientUri }; | ||||||
|  |   OAUTH3.discover(providerUri, opts).then(function (dir) { | ||||||
|  |     console.log('[DEBUG] directives:'); | ||||||
|  |     console.log(dir); | ||||||
|  |   }); | ||||||
|  |   </code></pre> | ||||||
|  | 
 | ||||||
|  |             <p>4. | ||||||
|  |             <pre><code> | ||||||
|  |   </code></pre> | ||||||
|  | 
 | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   <!--[if IE]><script src="bower_components/rsvp.js/rsvp.js"></script><![endif]--> | ||||||
|  |   <script src="./js/jquery-2.2.0.min.js"></script> | ||||||
|  |   <script src="/assets/oauth3.org/oauth3.core.js"></script> | ||||||
|  |   <script src="/assets/oauth3.org/oauth3.crypto.js"></script> | ||||||
|  |   <script src="/assets/oauth3.org/oauth3.issuer.js"></script> | ||||||
|  | 
 | ||||||
|  |   <script src="./js/angular-1.6.6.js"></script> | ||||||
|  |   <script src="./js/angular-ui-router-1.0.10.js"></script> | ||||||
|  |   <script src="/assets/oauth3.org/oauth3.ng.js"></script> | ||||||
|  |   <script src="./js/playground.js"></script> | ||||||
|  | 
 | ||||||
|  |   </body> | ||||||
|  | </html> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user