mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-10-05 12:20:10 +00:00
Finish MFA implementation
This commit is contained in:
@@ -202,7 +202,46 @@ module.exports = {
|
||||
return fetch('get', '');
|
||||
},
|
||||
|
||||
Mfa: {
|
||||
create: function () {
|
||||
return fetch('post', 'mfa/create');
|
||||
},
|
||||
enable: function (token) {
|
||||
return fetch('post', 'mfa/enable', {token: token});
|
||||
},
|
||||
check: function () {
|
||||
return fetch('get', 'mfa/check');
|
||||
}
|
||||
},
|
||||
|
||||
Tokens: {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} identity
|
||||
* @param {String} secret
|
||||
* @param {String} token
|
||||
* @param {Boolean} wipe
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
loginWithMFA: function (identity, secret, mfaToken, wipe) {
|
||||
return fetch('post', 'tokens', {identity: identity, secret: secret, mfa_token: mfaToken})
|
||||
.then(response => {
|
||||
if (response.token) {
|
||||
if (wipe) {
|
||||
Tokens.clearTokens();
|
||||
}
|
||||
|
||||
// Set storage token
|
||||
Tokens.addToken(response.token);
|
||||
return response.token;
|
||||
} else {
|
||||
Tokens.clearTokens();
|
||||
throw(new Error('No token returned'));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {String} identity
|
||||
|
@@ -25,6 +25,16 @@
|
||||
<div class="invalid-feedback secret-error"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<button type="button" class="btn btn-info add-mfa">Add MFA</button>
|
||||
<p class="qr-instructions" style="display: none;">Scan this QR code in your authenticator app to set up MFA and then enter the current MFA code in the input field.</p>
|
||||
<div class="mfa-validation-container" style="display: none;">
|
||||
<label class="form-label"><%- i18n('str', 'mfa') %> <span class="form-required">*</span></label>
|
||||
<input name="mfa_validation" type="text" class="form-control" placeholder="000000" value="" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if (isAdmin() && !isSelf()) { %>
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-label"><%- i18n('roles', 'title') %></div>
|
||||
|
@@ -14,7 +14,10 @@ module.exports = Mn.View.extend({
|
||||
buttons: '.modal-footer button',
|
||||
cancel: 'button.cancel',
|
||||
save: 'button.save',
|
||||
error: '.secret-error'
|
||||
error: '.secret-error',
|
||||
addMfa: '.add-mfa',
|
||||
mfaValidation: '.mfa-validation-container', // added binding
|
||||
qrInstructions: '.qr-instructions' // added binding for instructions
|
||||
},
|
||||
|
||||
events: {
|
||||
@@ -25,6 +28,10 @@ module.exports = Mn.View.extend({
|
||||
let view = this;
|
||||
let data = this.ui.form.serializeJSON();
|
||||
|
||||
// Save "mfa_validation" value and remove it from data
|
||||
let mfaToken = data.mfa_validation;
|
||||
delete data.mfa_validation;
|
||||
|
||||
let show_password = this.model.get('email') === 'admin@example.com';
|
||||
|
||||
// admin@example.com is not allowed
|
||||
@@ -62,6 +69,15 @@ module.exports = Mn.View.extend({
|
||||
}
|
||||
|
||||
view.model.set(result);
|
||||
|
||||
if (mfaToken) {
|
||||
return App.Api.Mfa.enable(mfaToken)
|
||||
.then(() => result);
|
||||
}
|
||||
console.log(result);
|
||||
return result;
|
||||
})
|
||||
.then(result => {
|
||||
App.UI.closeModal(function () {
|
||||
if (method === App.Api.Users.create) {
|
||||
// Show permissions dialog immediately
|
||||
@@ -75,6 +91,18 @@ module.exports = Mn.View.extend({
|
||||
this.ui.error.text(err.message).show();
|
||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||
});
|
||||
},
|
||||
'click @ui.addMfa': function (e) {
|
||||
let view = this;
|
||||
App.Api.Mfa.create()
|
||||
.then(response => {
|
||||
view.ui.addMfa.replaceWith(`<img class="qr-code" src="${response.qrCode}" alt="QR Code">`);
|
||||
view.ui.qrInstructions.show();
|
||||
view.ui.mfaValidation.show();
|
||||
})
|
||||
.catch(err => {
|
||||
view.ui.error.text(err.message).show();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -104,5 +132,24 @@ module.exports = Mn.View.extend({
|
||||
if (typeof options.model === 'undefined' || !options.model) {
|
||||
this.model = new UserModel.Model();
|
||||
}
|
||||
},
|
||||
|
||||
onRender: function () {
|
||||
let view = this;
|
||||
App.Api.Mfa.check()
|
||||
.then(response => {
|
||||
if (response.active) {
|
||||
view.ui.addMfa.hide();
|
||||
view.ui.qrInstructions.hide();
|
||||
view.ui.mfaValidation.hide();
|
||||
} else {
|
||||
view.ui.addMfa.show();
|
||||
view.ui.qrInstructions.hide();
|
||||
view.ui.mfaValidation.hide();
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
view.ui.error.text(err.message).show();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user