Skip to content

Commit

Permalink
Adding usernamepassword/login support for hosted login page
Browse files Browse the repository at this point in the history
  • Loading branch information
luisrudge committed Feb 1, 2018
1 parent 6a9119e commit c043c17
Show file tree
Hide file tree
Showing 5 changed files with 560 additions and 0 deletions.
16 changes: 16 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ <h2>Login with database connection:</h2>
<input type="button" class="login-db" value="login" />
</div>

<div>
<h2>Login with database connection (from universal login):</h2>
<input class="login-username" value="johnfoo@gmail.com" />
<input class="login-password" value="1234" />
<input type="button" class="universal-login" value="login" />
</div>

<div>
<h2>Login with passwordless connection:</h2>
<div>
Expand Down Expand Up @@ -261,6 +268,15 @@ <h2>Console:</h2>
}, htmlConsole.dumpCallback.bind(htmlConsole));
});

$('.universal-login').click(function (e) {
e.preventDefault();
webAuth._hostedPages.login({
connection: 'acme',
username: $('.login-username').val(),
password: $('.login-password').val()
}, htmlConsole.dumpCallback.bind(htmlConsole));
});

$('.passwordless-login-verify').click(function (e) {
e.preventDefault();
webAuthPasswordless.passwordlessLogin({
Expand Down
98 changes: 98 additions & 0 deletions src/web-auth/hosted-pages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
var UsernamePassword = require('./username-password');
var objectHelper = require('../helper/object');
var windowHelper = require('../helper/window');
var Warn = require('../helper/warn');
var assert = require('../helper/assert');

function HostedPages(client, options) {
this.baseOptions = options;
this.client = client;

this.warn = new Warn({
disableWarnings: !!options._disableDeprecationWarnings
});
}

/**
* @callback credentialsCallback
* @param {Error} [err] error returned by Auth0 with the reason of the Auth failure
* @param {Object} [result] result of the AuthN request
* @param {String} result.accessToken token that can be used with {@link userinfo}
* @param {String} [result.idToken] token that identifies the user
* @param {String} [result.refreshToken] token that can be used to get new access tokens from Auth0. Note that not all clients can request them or the resource server might not allow them.
*/

/**
* Performs authentication with username/email and password with a database connection
*
* This method is not compatible with API Auth so if you need to fetch API tokens with audience
* you should use {@link authorize} or {@link login}.
*
* @method loginWithCredentials
* @param {Object} options
* @param {String} [options.redirectUri] url that the Auth0 will redirect after Auth with the Authorization Response
* @param {String} [options.responseType] type of the response used. It can be any of the values `code` and `token`
* @param {String} [options.responseMode] how the AuthN response is encoded and redirected back to the client. Supported values are `query` and `fragment`
* @param {String} [options.scope] scopes to be requested during AuthN. e.g. `openid email`
* @param {credentialsCallback} cb
*/
HostedPages.prototype.login = function(options, cb) {
if (windowHelper.getWindow().location.host !== this.baseOptions.domain) {
throw new Error('This method is meant to be used only inside the Universal Login Page.');
}
var usernamePassword;

var params = objectHelper
.merge(this.baseOptions, [
'clientID',
'redirectUri',
'tenant',
'responseType',
'responseMode',
'scope',
'audience',
'_csrf',
'state',
'_intstate',
'nonce'
])
.with(options);

assert.check(
params,
{ type: 'object', message: 'options parameter is not valid' },
{
responseType: { type: 'string', message: 'responseType option is required' }
}
);

usernamePassword = new UsernamePassword(this.baseOptions);
return usernamePassword.login(params, function(err, data) {
if (err) {
return cb(err);
}
return usernamePassword.callback(data);
});
};

/**
* Signs up a new user and automatically logs the user in after the signup.
*
* @method signupAndLogin
* @param {Object} options
* @param {String} options.email user email address
* @param {String} options.password user password
* @param {String} options.connection name of the connection where the user will be created
* @param {credentialsCallback} cb
*/
HostedPages.prototype.signupAndLogin = function(options, cb) {
var _this = this;
return _this.client.client.dbConnection.signup(options, function(err) {
if (err) {
return cb(err);
}
return _this.login(options, cb);
});
};

module.exports = HostedPages;
2 changes: 2 additions & 0 deletions src/web-auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var Popup = require('./popup');
var SilentAuthenticationHandler = require('./silent-authentication-handler');
var CrossOriginAuthentication = require('./cross-origin-authentication');
var WebMessageHandler = require('./web-message-handler');
var HostedPages = require('./hosted-pages');

/**
* Handles all the browser's AuthN/AuthZ flows
Expand Down Expand Up @@ -107,6 +108,7 @@ function WebAuth(options) {
this.popup = new Popup(this, this.baseOptions);
this.crossOriginAuthentication = new CrossOriginAuthentication(this, this.baseOptions);
this.webMessageHandler = new WebMessageHandler(this);
this._hostedPages = new HostedPages(this, this.baseOptions);
}

/**
Expand Down
55 changes: 55 additions & 0 deletions src/web-auth/username-password.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
var urljoin = require('url-join');

var objectHelper = require('../helper/object');
var RequestBuilder = require('../helper/request-builder');
var responseHandler = require('../helper/response-handler');
var windowHelper = require('../helper/window');
var TransactionManager = require('./transaction-manager');

function UsernamePassword(options) {
this.baseOptions = options;
this.request = new RequestBuilder(options);
this.transactionManager = new TransactionManager(this.baseOptions.transaction);
}

UsernamePassword.prototype.login = function(options, cb) {
var url;
var body;

url = urljoin(this.baseOptions.rootUrl, 'usernamepassword', 'login');

options.username = options.username || options.email; // eslint-disable-line

options = objectHelper.blacklist(options, ['email']); // eslint-disable-line

body = objectHelper
.merge(this.baseOptions, [
'clientID',
'redirectUri',
'tenant',
'responseType',
'responseMode',
'scope',
'audience'
])
.with(options);
body = this.transactionManager.process(body);

body = objectHelper.toSnakeCase(body, ['auth0Client']);

return this.request.post(url).send(body).end(responseHandler(cb));
};

UsernamePassword.prototype.callback = function(formHtml) {
var div;
var form;
var _document = windowHelper.getDocument();

div = _document.createElement('div');
div.innerHTML = formHtml;
form = _document.body.appendChild(div).children[0];

form.submit();
};

module.exports = UsernamePassword;
Loading

0 comments on commit c043c17

Please sign in to comment.