Compare commits

..

No commits in common. "master" and "pre-issuer-rewrite" have entirely different histories.

12 changed files with 216 additions and 292 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
*.*sw* *.*sw*
bower_components/ bower_components/
assets/ assets/
.DS_Store

View File

@ -1,5 +0,0 @@
v1.2.1 - Authorization Dialog for ID Issuer
* Resource Owner Password token exchange
* Public / Private Keypair generation
* Public key (remember device) syncing
* BUG: Remember me is not operational

41
LICENSE
View File

@ -1,41 +0,0 @@
Copyright 2017 Daplie, Inc
This is open source software; you can redistribute it and/or modify it under the
terms of either:
a) the "MIT License"
b) the "Apache-2.0 License"
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Apache-2.0 License Summary
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,30 +1,20 @@
issuer.html This is a WALNUT module representing the html package for oauth3.org.
===========
| [oauth3.js](https://git.oauth3.org/OAuth3/oauth3.js) It must be installed to `/srv/walnut/packages/pages/issuer@oauth3.org`
| *issuer.html*
| [issuer.rest.walnut.js](https://git.oauth3.org/OAuth3/issuer.rest.walnut.js)
| [issuer.srv](https://git.oauth3.org/OAuth3/issuer.srv)
| Sponsored by [ppl](https://ppl.family)
This is a browser application which implements the issuer side of the *authorization_dialog* flow for OAuth3.
It may be used client-side only (public key or granted scope syncing will be disabled),
or will the *issuer.rest.walnut.js* APIs on the backend for full functionality.
For use with walnut it must be installed to `/opt/walnut/packages/pages/issuer@oauth3.org`
```bash ```bash
git clone git@git.oauth3.org:OAuth3/org.oauth3.git /opt/walnut/packages/pages/issuer@oauth3.org git clone git@git.daplie.com:OAuth3/issuer_oauth3.org.git /srv/walnut/packages/pages/issuer@oauth3.org
pushd /opt/walnut/packages/pages/issuer@oauth3.org ln -s issuer@oauth3.org /srv/walnut/packages/pages/org.oauth3
pushd /srv/walnut/packages/pages/issuer@oauth3.org
bash ./install.sh bash ./install.sh
popd popd
``` ```
```bash ```bash
echo "issuer@oauth3.org" >> /opt/walnut/var/sites/EXAMPLE.COM echo "issuer@oauth3.org" >> /srv/walnut/packages/sites/EXAMPLE.COM
echo "org.oauth3" >> /srv/walnut/packages/sites/EXAMPLE.COM
``` ```
This uses the OAuth3 JavaScript SDK `oauth3.js` as a subpackage in This uses the OAuth3 JavaScript SDK `oauth3.js` as a subpackage in `/srv/walnut/packages/pages/issuer@oauth3.org/assets/oauth3.org`.
`/opt/walnut/packages/pages/issuer@oauth3.org/assets/oauth3.org`.
The 'login popup' is hosted on our tardigrade proxy VM.

View File

@ -12,6 +12,10 @@ html, body {
background-color: #282828; background-color: #282828;
color: #FFFFFF; color: #FFFFFF;
} }
/*override bootstrap fade*/
.fade {
opacity: 1;
}
input.emailInput::placeholder { input.emailInput::placeholder {
font-family : Brown Regular; font-family : Brown Regular;
font-size : 14px; font-size : 14px;
@ -441,6 +445,3 @@ span.dap-small-text.js-scope-desc.noselect {
color : #808080; color : #808080;
color : rgb(128, 128, 128); color : rgb(128, 128, 128);
} }
.error-msg {
color: #FDA748;
}

BIN
img/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -11,8 +11,7 @@
<link rel="stylesheet" type="text/css" href="/css/daplie-installer-overrides.css"> <link rel="stylesheet" type="text/css" href="/css/daplie-installer-overrides.css">
</head> </head>
<body> <body class="fade mock-main">
<div class="fade mock-main">
<!-- STEP 1: ask the user where they want to log in --> <!-- STEP 1: ask the user where they want to log in -->
<!-- STEP 2: ask the user for their email --> <!-- STEP 2: ask the user for their email -->
@ -24,8 +23,8 @@
<!-- Step 5: ask for permissions --> <!-- Step 5: ask for permissions -->
<div class="dap-bordered js-userid-container"> <div class="dap-bordered js-userid-container">
<p class="org-title">daplie.me</p> <p class="org-title">Safelogin.org</p>
<p class="dap-centered-text dap-normal-text welcome-text center-it">Welcome to a new way to login. daplie.me helps you create an Internet ID that allows you to choose what info is shared about you when you login into a site or app online.</p> <p class="dap-centered-text dap-normal-text welcome-text center-it">Welcome to a new way to login. Safelogin.org helps you create an Internet ID that allows you to choose what info is shared about you when you login into a site or app online.</p>
<form method="post" action=""> <form method="post" action="">
<div class="form-group"> <div class="form-group">
<input type="email" class="form-control dap-input js-oauth3-email emailInput" placeholder="Enter an email address to start"></input> <input type="email" class="form-control dap-input js-oauth3-email emailInput" placeholder="Enter an email address to start"></input>
@ -46,7 +45,7 @@
</div> </div>
<div class="dap-bordered js-authn"> <div class="dap-bordered js-authn">
<p class="org-title">daplie.me</p> <p class="org-title">Safelogin.org</p>
<!-- <div class="dap-normal-text"> <!-- <div class="dap-normal-text">
<span class="fa fa-3x icon-centered-3x fa-purple fa-envelope"></span> <span class="fa fa-3x icon-centered-3x fa-purple fa-envelope"></span>
</div> </div>
@ -62,7 +61,6 @@
<p class="code-lasts-text">Code lasts for 15 minutes.</p> <p class="code-lasts-text">Code lasts for 15 minutes.</p>
<input type="hidden" class="js-authn-otp-uuid"> <input type="hidden" class="js-authn-otp-uuid">
<input class="dap-input js-authn-otp-code form-control" placeholder="XXXX-XXXX-XXXX" maxlength="14"></input> <input class="dap-input js-authn-otp-code form-control" placeholder="XXXX-XXXX-XXXX" maxlength="14"></input>
<p class="error-msg"></p>
</div> </div>
<div class="dap-centered-div dap-space-on-top form-group"> <div class="dap-centered-div dap-space-on-top form-group">
<label class="js-remember-label dap-normal-text"> <label class="js-remember-label dap-normal-text">
@ -72,7 +70,8 @@
<input class="js-remember-checkbox hidden" type="checkbox"></input> <input class="js-remember-checkbox hidden" type="checkbox"></input>
</label> </label>
</div> </div>
<button type="submit" class="btn btn-primary submit-btn dap-full-button-green js-submit-code-btn" disabled>Submit</button> <!-- <button class="dap-full-button-green js-remember-btn js-authz-remember-me">SIGN IN ONCE</button> -->
<button type="submit" class="btn btn-primary submit-btn dap-full-button-green js-remember-btn js-authz-remember-me">Submit</button>
<!-- <a href="./authnocode.html" target="_blank" class="btn btn-primary">Send Code Again</a> --> <!-- <a href="./authnocode.html" target="_blank" class="btn btn-primary">Send Code Again</a> -->
<button class="btn btn-primary js-edit-email-button" type="button">Edit My Email</button> <button class="btn btn-primary js-edit-email-button" type="button">Edit My Email</button>
</form> </form>
@ -86,14 +85,14 @@
</div> </div>
<div class="dap-bordered dap-normal-text js-authz"> <div class="dap-bordered dap-normal-text js-authz">
<p class="org-title">daplie.me</p> <p class="org-title">Safelogin.org</p>
<!-- <br> --> <!-- <br> -->
<!-- <div class="dap-user-plus-app"> <!-- <div class="dap-user-plus-app">
<span class="fa fa-3x fa-purple fa-user-circle"></span> <span class="fa fa-3x fa-purple fa-user-circle"></span>
<span class="fa fa-2x fa-gray fa-plus"></span> <span class="fa fa-2x fa-gray fa-plus"></span>
<img class="dap-lab-logo" src="./img/Daplie-Badge-Purple.png" alt="Daplie Labs Logo"> <img class="dap-lab-logo" src="./img/Daplie-Badge-Purple.png" alt="Daplie Labs Logo">
</div> --> </div> -->
<p class="dap-centered-text dap-normal-text almost-done-text">Almost done. Now it's time to set your preferences.</p> <p class="dap-centered-text dap-normal-text almost-done-text">Almost done. Now its time to set your preferences.</p>
<br> <br>
<form class="js-authorization-decision" action="#"> <form class="js-authorization-decision" action="#">
@ -140,60 +139,17 @@
<button type="button" class="dap-full-button-green js-logout btn btn-primary">Sign Out</button> <button type="button" class="dap-full-button-green js-logout btn btn-primary">Sign Out</button>
<img src="./img/sponsored-by.png" class="sponsored-by-logo"> <img src="./img/sponsored-by.png" class="sponsored-by-logo">
</div> </div>
</div>
<div class="fade mock-bare">
<div class="container">
<div class="jumbotron">
<h1>OAuth3 Playground</h1>
</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>
</div>
<!--[if IE]><script src="bower_components/rsvp.js/rsvp.js"></script><![endif]--> <!--[if IE]><script src="bower_components/rsvp.js/rsvp.js"></script><![endif]-->
<script src="./js/jquery-2.2.0.min.js"></script> <script src="./js/jquery-2.2.0.min.js"></script>
<script src="./js/jquery.mask.min.js"></script> <script src="./js/jquery.mask.min.js"></script>
<script src="./js/bootstrap.min.js"></script> <script src="./js/bootstrap.min.js"></script>
<script src="/assets/oauth3.org/oauth3.core.js"></script>
<script src="/assets/oauth3.org/oauth3.crypto.js"></script>
<script src="/assets/oauth3.org/oauth3.issuer.js"></script>
<script src="./js/issuer.js"></script> <script src="./js/issuer.js"></script>
<script src="./js/script.js"></script> <script src="./js/script.js"></script>
<script src="/assets/oauth3.org/oauth3.core.js"></script>
<script src="/assets/oauth3.org/oauth3.issuer.js"></script>
<!--script src="/assets/oauth3.org/oauth3.mock.js"></script-->
</body> </body>
</html> </html>

View File

@ -2,15 +2,14 @@
set -e set -e
set -u set -u
# git clone https://git.oauth3.org/OAuth3/issuer.html.git /srv/walnut/packages/pages/issuer@oauth3.org # git clone https://git.daplie.com/OAuth3/issuer_oauth3.org.git /srv/walnut/packages/pages/issuer@oauth3.org
# git clone https://git.oauth3.org/OAuth3/azp.html.git /srv/walnut/packages/pages/azp@oauth3.org
mkdir -p assets mkdir -p assets
if ! [ -d ./assets/oauth3.org ]; then if ! [ -d ./assets/oauth3.org ]; then
git clone https://git.oauth3.org/OAuth3/oauth3.js.git ./assets/oauth3.org git clone https://git.daplie.com/OAuth3/oauth3.js.git ./assets/oauth3.org
fi fi
pushd ./assets/oauth3.org pushd ./assets/oauth3.org
git checkout v1.2 git checkout v1
git pull git pull
popd popd

View File

@ -10,7 +10,7 @@ $(function () {
var auth = OAUTH3.create(); var auth = OAUTH3.create();
auth.init().then(function () { auth.init().then(function () {
$('.mock-main').addClass('in'); $('body').addClass('in');
}); });
auth.setProvider(providerUri).then(function () { auth.setProvider(providerUri).then(function () {

View File

@ -9,7 +9,7 @@ $(function () {
var OAUTH3 = window.OAUTH3; var OAUTH3 = window.OAUTH3;
var CONFIG = { var CONFIG = {
host: OAUTH3.clientUri(window.location) host: OAUTH3.utils.clientUri(window.location)
, directives: null // will be populated before the login button appears , directives: null // will be populated before the login button appears
}; };
var loc = window.location; var loc = window.location;
@ -20,8 +20,22 @@ $(function () {
}; };
$('.js-scopes-container').html(''); $('.js-scopes-container').html('');
/*
OAUTH3._hooks.sessions.all = function (providerUri) {
};
*/
OAUTH3._hooks = { sessions: {} };
OAUTH3._hooks.sessions.get = function (providerUri, id) {
return JSON.parse(window.localStorage.getItem('session-' + providerUri + (id || '')) || 'null');
};
OAUTH3._hooks.sessions.set = function (providerUri, newSession, id) {
window.localStorage.setItem('session-' + providerUri, JSON.stringify(newSession));
window.localStorage.setItem('session-' + providerUri + (id || newSession.id || newSession.token.id || ''), JSON.stringify(newSession));
return newSession;
};
// TODO let query.parse do location.hash || location.search || location // TODO let query.parse do location.hash || location.search || location
var clientParams = OAUTH3.query.parse(loc.hash || loc.search); var clientParams = OAUTH3.query.parse(window.location.hash || window.location.search);
if (/authorization_dialog/.test(window.location.href)) { if (/authorization_dialog/.test(window.location.href)) {
// OAUTH3.lintClientParams(params, window) // OAUTH3.lintClientParams(params, window)
// OAUTH3.normalizeClientParams(params, window) // OAUTH3.normalizeClientParams(params, window)
@ -44,12 +58,12 @@ $(function () {
+ "'" + OAUTH3.url.normalize(window.document.referrer) + "'" + "'" + OAUTH3.url.normalize(window.document.referrer) + "'"
); );
} }
if (clientParams.client_uri && clientParams.client_uri !== clientParams.client_id) { if (clientParams.client_uri) {
console.warn("'client_id' should be used instead of 'client_uri'"); console.warn("'client_id' should be used instead of 'client_uri'");
} }
if (!(clientParams.client_id || clientParams.client_uri)) { if (!(clientParams.client_id || clientParams.client_uri)) {
window.alert("'client_id' must exist as the uri identifying the client"); window.alert("'response_type' must exist and be either 'token' (implicit flow) or 'code' (authorization flow)");
console.error("'client_id' must exist as the uri identifying the client"); console.error("'response_type' must exist and be either 'token' (implicit flow) or 'code' (authorization flow)");
clientParams.client_id = clientParams.client_uri = OAUTH3.url.normalize(window.document.referrer); clientParams.client_id = clientParams.client_uri = OAUTH3.url.normalize(window.document.referrer);
} }
if (!clientParams.redirect_uri) { if (!clientParams.redirect_uri) {
@ -85,36 +99,21 @@ $(function () {
} }
function getGrants(session) { function getGrants(session) {
var clientLogo = OAUTH3.url.normalize(clientParams.client_uri) // optional relative logo ? var clientObj = OAUTH3.query.parse(loc.hash || loc.search);
var clientLogo = OAUTH3.url.normalize(clientObj.client_uri) // optional relative logo ?
+ '/.well-known/oauth3/logo-128x128.png' + '/.well-known/oauth3/logo-128x128.png'
; ;
var callbackUrl;
// TODO put in directives.json or similar // TODO put in directives.json or similar
var grantDescriptions = { var grantDescriptions = {
// deprecated
'oauth3_authn': "Basic secure authentication" 'oauth3_authn': "Basic secure authentication"
, 'auth@oauth3.org': "Basic secure authentication"
, 'wallet': "Access to payments and subscriptions" , 'wallet': "Access to payments and subscriptions"
, 'bucket': "Access to file storage" , 'bucket': "Access to file storage"
, 'db': "Access to app data" , 'db': "Access to app data"
, 'domains': "Domain registration (and Glue and NS records)" // TODO make an alias , 'domains': "Domain registration (and Glue and NS records)" // TODO make an alias
, 'domains@oauth3.org': "Domain registration (and Glue and NS records)" // TODO make an alias
, 'domains:glue': "Glue Record management (for vanity nameservers)" , 'domains:glue': "Glue Record management (for vanity nameservers)"
, 'domains:ns': "Name Server management" , 'domains:ns': "Name Server management"
, 'dns': "DNS records (A/AAAA, TXT, SRV, MX, etc)" , 'dns': "DNS records (A/AAAA, TXT, SRV, MX, etc)"
// new
, 'hello@example.com': "Hello World Example Access"
, 'authn@oauth3.org': "Basic secure authentication"
, 'wallet@oauth3.org': "Access to payments and subscriptions"
, 'bucket@oauth3.org': "Access to file storage"
, 'db@oauth3.org': "Access to app data"
, 'domains@oauth3.org': "Domain registration (and Glue and NS records)" // TODO make an alias
, 'domains:glue@oauth3.org': "Glue Record management (for vanity nameservers)"
, 'domains:ns@oauth3.org': "Name Server management"
, 'dns@oauth3.org': "DNS records (A/AAAA, TXT, SRV, MX, etc)"
, 'www@daplie.com': "Websites and webapps"
, '*': "FULL ACCOUNT ACCESS" , '*': "FULL ACCOUNT ACCESS"
}; };
@ -128,10 +127,10 @@ $(function () {
$('.js-client-logo').attr('src', clientLogo); $('.js-client-logo').attr('src', clientLogo);
//$('.js-user-avatar').attr('src', userAvatar); //$('.js-user-avatar').attr('src', userAvatar);
return OAUTH3.authz.scopes(CONFIG.host, session, clientParams).then(function (scopes) { return OAUTH3.authz.scopes(CONFIG.host, session, clientObj).then(function (scopes) {
if (!scopes.pending.length) { if (!scopes.pending.length) {
// looks like we've done all of this before // looks like we've done all of this before
OAUTH3.authz.redirectWithToken(CONFIG.host, session, clientParams, scopes); OAUTH3.authz.redirectWithToken(CONFIG.host, session, clientObj, scopes);
return; return;
} }
@ -139,12 +138,10 @@ $(function () {
// TODO secure iFrame from click-jacking by requiring input? // TODO secure iFrame from click-jacking by requiring input?
// ex: input.security-code[type="text"].val(Math.random()); input.js-verify-code[placeholder="Type what you see"] // ex: input.security-code[type="text"].val(Math.random()); input.js-verify-code[placeholder="Type what you see"]
if (OAUTH3._browser.isIframe()) { if (OAUTH3._browser.isIframe()) {
location.href = clientParams.redirect_uri +'#'+ OAUTH3.query.stringify({ callbackUrl = clientObj.redirect_uri + '#state=' + clientObj.state + '&error=access_denied&error_description='
state: clientParams.state + encodeURIComponent("You're requesting permission in an iframe, but the permissions have not yet been granted")
, error: 'access_denied' + '&error_uri=' + encodeURIComponent('https://oauth3.org/docs/errors/#E_IFRAME_DENIED');
, error_description: encodeURIComponent("You're requesting permission in an iframe, but the permissions have not yet been granted") location.href = callbackUrl;
, error_uri: encodeURIComponent('https://oauth3.org/docs/errors/#E_IFRAME_DENIED')
});
return; return;
} }
@ -168,13 +165,8 @@ $(function () {
$scope.find('.js-scope-desc').text(grantDescriptions[scope]); $scope.find('.js-scope-desc').text(grantDescriptions[scope]);
} }
else { else {
//This disables the check/checkbox when we have an unrecognized grant. $scope.find('.js-scope-toggle').prop('checked', false);
//This is disabled for testing until we can discover grants automatically. $scope.find('.js-scope-toggle').prop('disabled', true);
//TODO: Enable this when grants are discoverable
//TODO: Indicate to user that this is disabled, not just unchecked.
//$scope.find('.js-scope-toggle').prop('checked', false);
//$scope.find('.check').attr("src", "./img/unpressed-check.png");
//$scope.find('.js-scope-toggle').prop('disabled', true);
$scope.find('.js-scope-desc').text(scope); $scope.find('.js-scope-desc').text(scope);
} }
@ -182,6 +174,9 @@ $(function () {
}); });
$('.js-authz').show().addClass('in'); $('.js-authz').show().addClass('in');
}, function (err) {
window.alert('grantResults: ' + err.message);
console.error('scope results', err);
}); });
} }
@ -217,6 +212,19 @@ $(function () {
// TODO loading // TODO loading
email = $('.js-oauth3-email').val(); email = $('.js-oauth3-email').val();
return OAUTH3.authn.loginMeta(CONFIG.directives, {email: email, mock: true}).then(function (userResults) {
if (!userResults.data.error) {
console.log('User exists:', userResults);
}
if (userResults.data.error) {
$('.js-authn-show').removeAttr('disabled');
console.warn('User does not exist:', email);
console.warn('User Results:', userResults);
//window.alert('userResults: ' + userResults.data.error_description || userResults.data.error.message);
//return;
}
return OAUTH3.authn.otp(CONFIG.directives, {email: email, mock: true}).then(function (otpResults) { return OAUTH3.authn.otp(CONFIG.directives, {email: email, mock: true}).then(function (otpResults) {
if (otpResults.data.error) { if (otpResults.data.error) {
@ -232,12 +240,28 @@ $(function () {
$('.js-user-email').text(email); $('.js-user-email').text(email);
}); });
});
};
util.rememberDevice = function (ev) {
ev.preventDefault();
ev.stopPropagation();
util.submitLoginCode({
rememberDevice: true
});
};
util.rememberDeviceNot = function (ev) {
ev.preventDefault();
ev.stopPropagation();
util.submitLoginCode({
rememberDevice: false
});
}; };
// Reference Implementation // Reference Implementation
util.submitLoginCode = function (ev) {
ev.preventDefault(); util.submitLoginCode = function (opts) {
ev.stopPropagation();
// TODO // TODO
// perhaps we should check that the code is valid before continuing to login (so that we don't send the key) // perhaps we should check that the code is valid before continuing to login (so that we don't send the key)
@ -245,6 +269,7 @@ $(function () {
// TODO // TODO
// we should be sending the public key for this device as a jwk along with the authentication // we should be sending the public key for this device as a jwk along with the authentication
// (and how long to remember this device) // (and how long to remember this device)
var uuid = $('.js-authn-otp-uuid').val(); var uuid = $('.js-authn-otp-uuid').val();
var code = $('.js-authn-otp-code').val().trim(); var code = $('.js-authn-otp-code').val().trim();
return OAUTH3.authn.resourceOwnerPassword(CONFIG.directives, { return OAUTH3.authn.resourceOwnerPassword(CONFIG.directives, {
@ -258,10 +283,13 @@ $(function () {
// TODO should be otp_id (agnostic of uuid) // TODO should be otp_id (agnostic of uuid)
, otp_uuid: uuid , otp_uuid: uuid
// add expiration to the refresh token and/or public key // add expiration to the refresh token and/or public key
, remember_device: $('.js-remember-label').find('.js-remember-checkbox').prop('checked') , expire: opts.rememberDevice || (1 * 60 * 60 * 1000)
, mock: true , mock: true
}).then(function (session) { }).then(function (session) {
$('.js-authn').removeClass('in').hide(); $('.js-authn').removeClass('in').hide();
function getAccount(session) {
if (session.token.sub) { if (session.token.sub) {
return OAUTH3.PromiseA.resolve(session); return OAUTH3.PromiseA.resolve(session);
} }
@ -278,15 +306,13 @@ $(function () {
, refresh_token: (results.refresh_token || results.refreshToken) , refresh_token: (results.refresh_token || results.refreshToken)
}); });
}); });
}).then(function (session) { }
return getGrants(session).catch(function (err) {
window.alert('grantResults: ' + err.message); return getAccount(session).then(function () {
console.error('scope results', err); return getGrants(session);
}); });
}, function (error) {
console.error(error);
$('.error-msg').text('Incorrect code');
}); });
}; };
util.acceptScopesAndLogin = function (ev) { util.acceptScopesAndLogin = function (ev) {
ev.preventDefault(); ev.preventDefault();
@ -303,6 +329,8 @@ $(function () {
}); });
getSession(CONFIG.host).then(function (session) { getSession(CONFIG.host).then(function (session) {
var clientParams = OAUTH3.query.parse(loc.hash || loc.search);
return OAUTH3.authz.scopes(CONFIG.host, session, clientParams).then(function (scopes) { return OAUTH3.authz.scopes(CONFIG.host, session, clientParams).then(function (scopes) {
scopes.new = acceptedScopes; scopes.new = acceptedScopes;
return OAUTH3.authz.redirectWithToken(CONFIG.host, session, clientParams, scopes); return OAUTH3.authz.redirectWithToken(CONFIG.host, session, clientParams, scopes);
@ -316,17 +344,21 @@ $(function () {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
var loginWinObj = OAUTH3.query.parse(loc.hash || loc.search);
var denyObj = { var denyObj = {
error: 'access_denied' error: 'access_denied'
, error_description: 'The user has denied access.' , error_description: 'The user has denied access.'
, error_uri: 'https://' + CONFIG.host + '/.well-known/oauth3/errors.html#/?error=access_denied' , error_uri: 'https://' + CONFIG.host + '/.well-known/oauth3/errors.html#/?error=access_denied'
, state: clientParams.state , state: loginWinObj.state
, scope: clientParams.scope , scope: loginWinObj.scope
}; };
window.location = clientParams.redirect_uri + '#' + OAUTH3.query.stringify(denyObj); window.location = loginWinObj.redirect_uri + '#' + OAUTH3.query.stringify(denyObj);
}; };
util.handleLogout = function () { util.handleLogout = function () {
var clientParams = OAUTH3.query.parse(loc.hash || loc.search);
localStorage.clear(); localStorage.clear();
clientParams.redirect_uri += '?' + OAUTH3.query.stringify({ clientParams.redirect_uri += '?' + OAUTH3.query.stringify({
@ -339,21 +371,21 @@ $(function () {
util.editEmail = function () { util.editEmail = function () {
$('.js-authn').hide(); $('.js-authn').hide();
$('.js-userid-container').show(); $('.js-userid-container').show();
debugger;
}; };
// //
// Page Setup // Page Setup
// //
$('.js-authorization-dialog').hide();
$('.js-logout-container').hide();
$('.js-userid-container').hide(); $('.js-userid-container').hide();
$('.js-authn').hide(); $('.js-authn').hide();
$('.js-authz').hide(); $('.js-authz').hide();
$('body').on('click', '.js-logout', util.handleLogout); $('body').on('click', '.js-logout', util.handleLogout);
$('body').on('click', '.js-authn-show', util.submitAuthEmail); $('body').on('click', '.js-authn-show', util.submitAuthEmail);
$('body').on('click', '.js-submit-code-btn', util.submitLoginCode); $('body').on('click', '.js-authz-remember-me', util.rememberDevice);
$('body').on('click', '.js-authz-remember-me-not', util.rememberDeviceNot);
$('body').on('click', '.js-login-allow', util.acceptScopesAndLogin); $('body').on('click', '.js-login-allow', util.acceptScopesAndLogin);
$('body').on('click', '.js-login-deny', util.closeLoginDeny); $('body').on('click', '.js-login-deny', util.closeLoginDeny);
$('body').on('click', '.js-edit-email-button', util.editEmail); $('body').on('click', '.js-edit-email-button', util.editEmail);
@ -362,33 +394,40 @@ $(function () {
function handleAuthorizationDialog() { function handleAuthorizationDialog() {
return getSession(CONFIG.host).then(function (session) { return getSession(CONFIG.host).then(function (session) {
return getGrants(session); return getGrants(session);
}).catch(function () { }, function (e) {
var clientObj = OAUTH3.query.parse(loc.hash || loc.search);
// TODO select the providers the client wants to show // TODO select the providers the client wants to show
// providers=daplie.com,facebook.com,google.com // etc // providers=daplie.com,facebook.com,google.com // etc
// TODO let the client specify switch_user // TODO let the client specify switch_user
// TODO let the client specify relogin if stale // TODO let the client specify relogin if stale
if (OAUTH3._browser.isIframe()) { if (OAUTH3._browser.isIframe()) {
location.href = clientParams.redirect_uri +'#'+ OAUTH3.query.stringify({ var callbackUrl = clientObj.redirect_uri + '#state=' + clientObj.state + '&error=access_denied&error_description='
state: clientParams.state + encodeURIComponent("You're requesting permission in an iframe, but the user is not yet authenticated")
, error: 'access_denied' + '&error_uri=' + encodeURIComponent('https://oauth3.org/docs/errors/#E_IFRAME_DENIED');
, error_description: encodeURIComponent("You're requesting permission in an iframe, but the user is not yet authenticated") location.href = callbackUrl;
, error_uri: encodeURIComponent('https://oauth3.org/docs/errors/#E_IFRAME_DENIED')
});
} }
if (clientParams.subject) { if (clientParams.subject) {
$('.js-oauth3-email').val(clientParams.subject); $('.js-oauth3-email').val(clientParams.subject);
$('.js-authn-show').prop('disabled', false); $('.js-authn-show').prop('disabled', false);
} }
$('.js-userid-container').show(); $('.js-userid-container').show();
}).then(function () {
//$('body').addClass('in');
}); });
} }
// Session initialization // Session initialization
return OAUTH3.discover(CONFIG.host, { client_uri: CONFIG.host }).then(function (directives) { return OAUTH3.discover(
OAUTH3.clientUri(window.location)
, { client_uri: OAUTH3.clientUri(window.location) }
).then(function (directives) {
// TODO cache directives in memory (and storage) // TODO cache directives in memory (and storage)
CONFIG.directives = directives; CONFIG.directives = directives;
directives.issuer = directives.issuer || (window.location.host + window.location.pathname).replace(/\/$/, ''); directives.issuer = directives.issuer || (window.location.host + window.location.pathname).replace(/\/$/, '');
$('.js-authorization-dialog').hide();
$('.js-logout-container').hide();
if (/authorization_dialog/.test(window.location.href)) { if (/authorization_dialog/.test(window.location.href)) {
$('.js-authorization-dialog').show(); $('.js-authorization-dialog').show();
handleAuthorizationDialog(); handleAuthorizationDialog();
@ -397,13 +436,8 @@ $(function () {
$('.js-logout-container').show(); $('.js-logout-container').show();
} }
if (document.location.hash.slice(1) || document.location.search) { $('body').addClass('in');
console.log('[DEBUG] search:', document.location.search);
console.log('[DEBUG] hash:', document.location.search);
$('.mock-main').addClass('in');
} else {
console.log('[DEBUG] not an auth window');
$('.mock-bare').addClass('in');
}
}); });
}); });

View File

@ -47,33 +47,30 @@ $('body').on('click', '.js-remember-label', function (ev) {
$('body').on('click', '.check', function () { $('body').on('click', '.check', function () {
'use strict'; 'use strict';
var $img = $(this);
if($img.attr("src") === "./img/pressed-check.png") {
$img.attr("src", "./img/unpressed-check.png");
$img.removeClass("is-checked");
} else if($img.attr("src") === "./img/unpressed-check.png") {
$img.attr("src", "./img/pressed-check.png");
$img.addClass("is-checked");
}
}); });
$('body').on('click', '.js-auth-li-enabled', function (ev) { $('body').on('click', '.js-auth-li-enabled', function (ev) {
'use strict'; 'use strict';
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
var $this = $(this); var $this = $(this);
var $hiddenCheckbox = $this.find('.js-auth-checkbox'); if ($this.find('.js-auth-checkbox').is(':checked') === true) {
var $img = $this.find('.check'); $this.find('.js-auth-checkbox').prop( "checked", false );
var newStatus = $hiddenCheckbox.prop('checked') ? "unchecked" : "checked";
if(newStatus === 'checked') {
$img.attr('src', './img/pressed-check.png');
$img.addClass("is-checked");
$hiddenCheckbox.prop( "checked", true );
} else { } else {
$img.attr("src", "./img/unpressed-check.png"); $this.find('.js-auth-checkbox').prop( "checked", true );
$img.removeClass("is-checked");
$hiddenCheckbox.prop( "checked", false );
} }
}); });
$('body').on('keyup keypress', '.js-authn-otp-code', function (e) { // $('body').on('keyup keypress', '.js-authn-otp-code', function (e) {
'use strict'; // 'use strict';
// var keyCode = e.keyCode || e.which; // var keyCode = e.keyCode || e.which;
// var regex = new RegExp('^[0-9 \-]+$'); // var regex = new RegExp('^[0-9 \-]+$');
// var key = String.fromCharCode(!e.charCode ? e.which : e.charCode); // var key = String.fromCharCode(!e.charCode ? e.which : e.charCode);
@ -93,13 +90,7 @@ $('body').on('keyup keypress', '.js-authn-otp-code', function (e) {
// if($(this).val().length === $(this).attr("maxlength")){ // if($(this).val().length === $(this).attr("maxlength")){
// $('.submit-btn').prop("disabled", false); // $('.submit-btn').prop("disabled", false);
// } // }
if ($(this).val().length === 14) { // });
$('.submit-btn').prop('disabled', false);
} else {
$('.error-msg').empty();
$('.submit-btn').prop('disabled', true);
}
});
$('.js-authn-otp-code').mask('####-####-####'); $('.js-authn-otp-code').mask('####-####-####');