Skip to content

Commit

Permalink
Merge pull request #230 from forio/release-candidate
Browse files Browse the repository at this point in the history
Two factor auth
  • Loading branch information
wglasshusain authored Jul 5, 2019
2 parents 9e66242 + 27f72c8 commit 16c0e48
Show file tree
Hide file tree
Showing 25 changed files with 5,883 additions and 4,160 deletions.
7 changes: 1 addition & 6 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"commonjs": true,
"node": false
},
"plugins": ["jsdoc"],
"globals": {
"$": false
},
Expand Down Expand Up @@ -45,12 +46,6 @@
"no-unexpected-multiline": 1,
"no-unreachable": 2,
"use-isnan": 1,
"valid-jsdoc": [1, {
"requireReturn": false,
"requireReturnType": false,
"requireParamDescription": false,
"requireReturnDescription": false
}],
"valid-typeof": 2,

"accessor-pairs": 2,
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<a name="2.11.0"></a>
### 2.11.0

### Features
- login.js now supports multifactor authentication. See ```src/components/login/index.html``` for the necessary HTML components that must be on the login page.

<a name="2.10.0"></a>
### 2.10.0

### Features
- Added a `keepOnline` flag to Presence Service.
Expand Down
2 changes: 1 addition & 1 deletion dist/components/assignment/assignment.min.js.map

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions dist/components/login/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,20 @@
<h4 class="text-center">Please Login to this Simulation</h4>
<hr>
<div class="form-group control">
<label for="">Username</label>
<label for="username">Username</label>
<input id="username" type="text" class="form-control">
</div>
<div class="form-group control">
<label for="">Password</label>
<label for="password">Password</label>
<input id="password" type="password" class="form-control">
</div>
<div class="form-group control hidden mfa">
<label for="mfaCode"> Authentication Code</label>
<input id="mfaCode" type="number" class="form-control" />
<p class="help-block">
This account has two-factor authentication enabled. Use your Authenticator app to view your Authentication Code.
</p>
</div>
<!-- account and project fields are optional, normally account/project are extracted from the url -->
<input type="hidden" id="account">
<input type="hidden" id="project">
Expand Down
7 changes: 7 additions & 0 deletions dist/components/login/login.css
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,10 @@ body {
background-position: 50%;

}

.error-text {
display: none;
}
.has-error .error-text {
display: block;
}
112 changes: 75 additions & 37 deletions dist/components/login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ $(function () {
select.find('[value!=""]').remove();
$.each(groups, function () {
$('<option>')
.attr('value', this.groupId)
.attr('value', this.groupKey)
.text(this.name)
.appendTo(select);
});
Expand Down Expand Up @@ -61,8 +61,13 @@ $(function () {
var project = $('#project:not([data-local])').val() || fromUrl.project || $('#project').val();
var groupId = ($('#groupId').length ? $('#groupId') : $('<input type="hidden" id="groupId">').appendTo(form)).val();

var mfaCode = $('#mfaCode').val();

$('button', form).attr('disabled', 'disabled').addClass('disabled');
$('#login-message').text('').hide();
$('.mfa input').on('change', function () {
$('.mfa').removeClass('has-error');
});

if (!account) {
console.log('No account was specified and it cannot be extracted from the URL. You may not be able to login.');
Expand All @@ -72,45 +77,78 @@ $(function () {
console.log('No project was specified and it cannot be extracted from the URL.');
}

var auth = new F.manager.AuthManager();
auth.login({
userName: userName,
password: password,
var auth = new F.v3.manager.AuthManager({
account: account,
project: project,
groupId: groupId
})
.fail(function (error) {
if (error.status === 401) {
showError('Invalid user name or password.');
} else if (error.status === 403) {
if (error.type === 'MULTIPLE_GROUPS') {
selectGroup(userName, password, account, project, error.userGroups, action);
} else if (error.type === 'NO_GROUPS') {
showError('The user has no groups associated in this account');
} else {
showError(error.statusText || error.message || ('Unknown Error' + error.status));
}
} else {
showError('Unknown error occured. Please try again. (' + error.status + ')');
project: project
});
const loginParams = {
handle: userName,
password: password,
};
if (groupId) loginParams.groupKey = groupId;
if (mfaCode) loginParams.mfaCode = mfaCode;
auth.login(loginParams).then(function () {
var session = auth.getCurrentUserSessionInfo();
if ($('#log-login').length) {
var url = $('#log-login').val();
$.get(url + '?userName=' + session.userName + '&groupName=' + session.groupName);
}
var newPage = action;
var facPage = $('#fac-redirect-page').val();
if ((session.isFac || session.isTeamMember) && facPage) {
newPage = facPage;
}
window.location = newPage;
$('.group-selection-dialog').hide();
}, function (error) {
if (error.type === 'MULTIPLE_GROUPS') {
selectGroup(userName, password, account, project, error.context.possibleGroups, action);
} else if (error.type === 'NO_GROUPS') {
showError('User is not a member of a simulation group.');
$('.mfa').addClass('hidden');
$('#mfaCode').val('');
$('#username').prop('disabled', false);
$('#password').prop('disabled', false);
} else if (error.type === 'AUTHORIZATION_FAILURE') {
showError('Could not login, please check username/ password and try again.');
$('.mfa').addClass('hidden');
$('#mfaCode').val('');
$('#username').prop('disabled', false);
$('#password').prop('disabled', false);
} else if (error.type === 'PASSWORD_EXPIRATION') {
showError('Your password has expired. Please contact your administrator and request a password reset.');
$('.mfa').addClass('hidden');
$('#mfaCode').val('');
$('#username').prop('disabled', false);
$('#password').prop('disabled', false);
} else if (error.type === 'MULTI_FACTOR_AUTHENTICATION_FAILURE') {
showError('Could not login, please check username, password and/or authentication code and try again.');
$('.mfa').addClass('hidden');
$('#mfaCode').val('');
$('#username').prop('disabled', false);
$('#password').prop('disabled', false);
} else if (error.type === 'MULTI_FACTOR_AUTHENTICATION_REQUIRED') {
showError('Could not login, this project requires a user set up with multi factor authentication.');
$('.mfa').addClass('hidden');
$('#mfaCode').val('');
$('#username').prop('disabled', false);
$('#password').prop('disabled', false);
} else if (error.type === 'MULTI_FACTOR_AUTHENTICATION_MISSING') {
if ($('.mfa').hasClass('hidden')) {
$('.mfa').removeClass('hidden');
}
$('#username').prop('disabled', true);
$('#password').prop('disabled', true);
} else {
showError('Unknown error occured. Please try again. (' + error.type + ')');
$('.mfa').addClass('hidden');
$('#mfaCode').val('');
$('#username').prop('disabled', false);
$('#password').prop('disabled', false);
}

$('button', form).attr('disabled', null).removeClass('disabled');
})
.then(function () {
var session = auth.getCurrentUserSessionInfo();
if ($('#log-login').length) {
var url = $('#log-login').val();
$.get(url + '?userName=' + session.userName + '&groupName=' + session.groupName);
}
var newPage = action;
var facPage = $('#fac-redirect-page').val();
if ((session.isFac || session.isTeamMember) && facPage) {
newPage = facPage;
}
window.location = newPage;
$('.group-selection-dialog').hide();
});
$('button', form).attr('disabled', null).removeClass('disabled');
});
});

groupSelectionTemplate = window.groupSelectionTemplate = '<form>\
Expand Down
2 changes: 1 addition & 1 deletion dist/components/login/login.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit 16c0e48

Please sign in to comment.