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="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">
 | 
			
		||||
    <!-- link rel="stylesheet" type="text/css" href="/css/daplie-installer-overrides.css" -->
 | 
			
		||||
  </head>
 | 
			
		||||
 | 
			
		||||
  <body>
 | 
			
		||||
@ -24,8 +24,8 @@
 | 
			
		||||
    <!-- Step 5: ask for permissions -->
 | 
			
		||||
 | 
			
		||||
    <div class="dap-bordered js-userid-container">
 | 
			
		||||
      <p class="org-title">daplie.me</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="org-title">OAuth3.org</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="">
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
          <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 class="dap-bordered js-authn">
 | 
			
		||||
      <p class="org-title">daplie.me</p>
 | 
			
		||||
      <p class="org-title">OAuth3.org</p>
 | 
			
		||||
      <!-- <div class="dap-normal-text">
 | 
			
		||||
        <span class="fa fa-3x icon-centered-3x fa-purple fa-envelope"></span>
 | 
			
		||||
      </div>
 | 
			
		||||
@ -69,7 +69,7 @@
 | 
			
		||||
            <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="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>
 | 
			
		||||
        </div>
 | 
			
		||||
        <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 class="dap-bordered dap-normal-text js-authz">
 | 
			
		||||
      <p class="org-title">daplie.me</p>
 | 
			
		||||
      <p class="org-title">OAuth3.org</p>
 | 
			
		||||
      <!-- <br> -->
 | 
			
		||||
      <!-- <div class="dap-user-plus-app">
 | 
			
		||||
        <span class="fa fa-3x fa-purple fa-user-circle"></span>
 | 
			
		||||
@ -142,58 +142,75 @@
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="fade mock-bare">
 | 
			
		||||
  <div class="fade js-playground" ng-app="oauth3Playground" ng-strict>
 | 
			
		||||
    <div class="container">
 | 
			
		||||
      <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 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 class="col-md-3">
 | 
			
		||||
          Login Status:
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-md-9">
 | 
			
		||||
          ...
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col-md-3">
 | 
			
		||||
          Current Sessions:
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-md-9">
 | 
			
		||||
          ...
 | 
			
		||||
        </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>
 | 
			
		||||
        <div>
 | 
			
		||||
          <h2>Private, Peer-to-Peer, Anonymous: Pick any two... at a time</h2>
 | 
			
		||||
          <ul>
 | 
			
		||||
            <li>Privacy
 | 
			
		||||
            <li>Peer-to-Peer
 | 
			
		||||
            <li>Anonymity
 | 
			
		||||
          </ul>
 | 
			
		||||
          <p>OAuth3's federated design allows it to work in all 3 modes of decentralization:
 | 
			
		||||
          <ul>
 | 
			
		||||
            <li>Private, Peer-to-Peer (Trusted model)
 | 
			
		||||
              <!--
 | 
			
		||||
              (Public / Private Keypair model)
 | 
			
		||||
              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.
 | 
			
		||||
              -->
 | 
			
		||||
 | 
			
		||||
            <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>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <!--[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.mask.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.crypto.js"></script>
 | 
			
		||||
    <script src="/assets/oauth3.org/oauth3.issuer.js"></script>
 | 
			
		||||
    <script src="./js/issuer.js"></script>
 | 
			
		||||
    <script src="./js/script.js"></script>
 | 
			
		||||
  <!--[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.mask.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.crypto.js"></script>
 | 
			
		||||
  <script src="/assets/oauth3.org/oauth3.issuer.js"></script>
 | 
			
		||||
  <script src="./js/issuer.js"></script>
 | 
			
		||||
  <script src="./js/script.js"></script>
 | 
			
		||||
 | 
			
		||||
  </body>
 | 
			
		||||
</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 expiry calculation
 | 
			
		||||
    // 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
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -94,6 +94,9 @@ $(function () {
 | 
			
		||||
      // deprecated
 | 
			
		||||
      'oauth3_authn': "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"
 | 
			
		||||
    , 'bucket': "Access to file storage"
 | 
			
		||||
    , 'db': "Access to app data"
 | 
			
		||||
@ -118,7 +121,7 @@ $(function () {
 | 
			
		||||
    , '*': "FULL ACCOUNT ACCESS"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if ('oauth3_authn' === clientParams.scope) {
 | 
			
		||||
    if ('authn@oauth3.org' === (clientParams.scope||'').toString()) {
 | 
			
		||||
      // implicit ppid grant is automatic
 | 
			
		||||
      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
 | 
			
		||||
@ -362,7 +365,13 @@ $(function () {
 | 
			
		||||
  function handleAuthorizationDialog() {
 | 
			
		||||
    return getSession(CONFIG.host).then(function (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
 | 
			
		||||
      // providers=daplie.com,facebook.com,google.com // etc
 | 
			
		||||
      // TODO let the client specify switch_user
 | 
			
		||||
@ -403,7 +412,8 @@ $(function () {
 | 
			
		||||
      $('.mock-main').addClass('in');
 | 
			
		||||
    } else {
 | 
			
		||||
      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);
 | 
			
		||||
  if ($this.find('.js-remember-checkbox').is(':checked') === true) {
 | 
			
		||||
    $this.find('.js-remember-checkbox').prop( "checked", false );
 | 
			
		||||
    $this.find('.js-remember-status').attr("src", "./img/unpressed-check.png");
 | 
			
		||||
  } else {
 | 
			
		||||
    $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) {
 | 
			
		||||
  'use strict';
 | 
			
		||||
  ev.preventDefault();
 | 
			
		||||
  ev.stopPropagation();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  var $this = $(this);
 | 
			
		||||
  var $hiddenCheckbox = $this.find('.js-auth-checkbox');
 | 
			
		||||
  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