add intro page, split playground
This commit is contained in:
parent
9aaabeb908
commit
980895992a
584
index.html
584
index.html
|
@ -143,543 +143,52 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fade js-playground" ng-app="oauth3Playground" ng-strict>
|
<div class="fade js-playground" ng-app="oauth3Playground" ng-strict>
|
||||||
<div ng-controller="PlaygroundCtrl as vm">
|
<div class="container">
|
||||||
<div class="container">
|
<div class="jumbotron">
|
||||||
<div class="jumbotron">
|
<h1>OAuth3</h1>
|
||||||
<h1>OAuth3 Playground</h1>
|
<p>A (mostly) client-side authentication and authorization framework for decentralized peer-to-peer and federated networks.
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
<div class="row">
|
<a class="btn btn-primary" href="playground.html">Enter the OAuth3 Playground</a>
|
||||||
<div class="col-md-12">
|
|
||||||
<h2>Go ahead, test our login</h2>
|
<div>
|
||||||
|
<h2>Private, Peer-to-Peer, Anonymous: Pick any two... at a time</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>
|
<ul>
|
||||||
<div ng-if="vm._working" class="alert alert-info">
|
<li>Privacy
|
||||||
<marquee>taking my sweet time to do something in the background...</marquee>
|
<li>Peer-to-Peer
|
||||||
</div>
|
<li>Anonymity
|
||||||
<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>
|
</ul>
|
||||||
|
<p>OAuth3's federated design allows it to work in all 3 modes of decentralization:
|
||||||
<label>Address:</label>
|
<ul>
|
||||||
<input type="text" placeholder="ex: john@example.com (optional)" class="form-control" ng-model="vm.form.id" ng-change="vm.fn.changeUser()">
|
<li>Private, Peer-to-Peer (Trusted model)
|
||||||
<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()">
|
(Public / Private Keypair model)
|
||||||
<button class="btn btn-link" ng-if="!vm.advanced" ng-click="vm.fn.toggleAdvanced()">open advanced</button>
|
For trusted parties OAuth3 defines how to exchange public keys on the client-side to
|
||||||
<button class="btn btn-link" ng-if="vm.advanced" ng-click="vm.fn.toggleAdvanced()">close advanced</button>
|
ensure that a resource owner's assets can be retrieved, without any involved.
|
||||||
<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>
|
<li>Private, Anonymous (Escrow / Broker model)
|
||||||
</div>
|
<!--
|
||||||
|
(Escrow / Broker model)
|
||||||
<div class="row">
|
When you want transactions to be both private and anonymous there
|
||||||
<div class="col-md-12">
|
must be a mutual trusted authority to broker the transaction to ensure privacy without
|
||||||
<br/>
|
disclosing identity. In the same way that a private escrow service can ensure a valid
|
||||||
<br/>
|
between two untrusted participants, <em>any</em> OAuth3 Issuer can broker identity and
|
||||||
<br/>
|
privilege transactions between two parties.
|
||||||
</div>
|
-->
|
||||||
</div>
|
|
||||||
|
<li>Peer-to-Peer, Anonymous (Public Ledger model)
|
||||||
<div class="row">
|
<!--
|
||||||
<div class="col-md-12">
|
-->
|
||||||
|
</ul>
|
||||||
<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>
|
|
||||||
|
|
||||||
<button ng-if="vm.directives" class="btn btn-default" ng-click="vm.fn.clearDirectives()">[X]</button>
|
|
||||||
<pre ng-if="vm.directives"><code><span ng-bind="vm.directives | json"></span></code></pre>
|
|
||||||
</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>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.authn.resourceOwnerPassword(directives, <span ng-bind="vm.api.authn._ropOpts_ || 'opts'"></span>);</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>
|
|
||||||
</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>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.refreshToken">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.directives || !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>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</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>
|
||||||
|
|
||||||
|
<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>
|
</div>
|
||||||
|
@ -695,10 +204,5 @@
|
||||||
<script src="./js/issuer.js"></script>
|
<script src="./js/issuer.js"></script>
|
||||||
<script src="./js/script.js"></script>
|
<script src="./js/script.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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
vm.framework = 'none';
|
vm.framework = 'none';
|
||||||
vm.clientUri = OAUTH3.clientUri(window.location);
|
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.conf = { debug: undefined, client_id: vm.clientUri, client_uri: vm.clientUri, provider_uri: vm.clientUri };
|
||||||
vm.providerUri = vm.conf.client_uri;
|
vm.providerUri = vm.conf.client_uri;
|
||||||
// map of things being debounced presently
|
// map of things being debounced presently
|
||||||
|
|
|
@ -0,0 +1,585 @@
|
||||||
|
<!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>
|
||||||
|
|
||||||
|
<button ng-if="vm.directives" class="btn btn-default" ng-click="vm.fn.clearDirectives()">[X]</button>
|
||||||
|
<pre ng-if="vm.directives"><code><span ng-bind="vm.directives | json"></span></code></pre>
|
||||||
|
</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">Open Logout Dialog</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>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.refreshToken">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…
Reference in New Issue