mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Port Master Password dialog to React. Fixes #7342
This commit is contained in:
parent
e59471d87d
commit
b283c0ba18
Binary file not shown.
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 36 KiB |
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 29 KiB |
@ -14,6 +14,7 @@ New features
|
|||||||
Housekeeping
|
Housekeeping
|
||||||
************
|
************
|
||||||
|
|
||||||
|
| `Issue #7342 <https://redmine.postgresql.org/issues/7342>`_ - Port Master Password dialog to React.
|
||||||
| `Issue #7492 <https://redmine.postgresql.org/issues/7492>`_ - Removing dynamic module loading and replacing it with static loading.
|
| `Issue #7492 <https://redmine.postgresql.org/issues/7492>`_ - Removing dynamic module loading and replacing it with static loading.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
|
@ -743,30 +743,11 @@ def get_nodes():
|
|||||||
|
|
||||||
|
|
||||||
def form_master_password_response(existing=True, present=False, errmsg=None):
|
def form_master_password_response(existing=True, present=False, errmsg=None):
|
||||||
content_new = (
|
|
||||||
gettext("Set Master Password"),
|
|
||||||
"<br/>".join([
|
|
||||||
gettext("Please set a master password for pgAdmin."),
|
|
||||||
gettext("This will be used to secure and later unlock saved "
|
|
||||||
"passwords and other credentials.")])
|
|
||||||
)
|
|
||||||
content_existing = (
|
|
||||||
gettext("Unlock Saved Passwords"),
|
|
||||||
"<br/>".join([
|
|
||||||
gettext("Please enter your master password."),
|
|
||||||
gettext("This is required to unlock saved passwords and "
|
|
||||||
"reconnect to the database server(s).")])
|
|
||||||
)
|
|
||||||
|
|
||||||
return make_json_response(data={
|
return make_json_response(data={
|
||||||
'present': present,
|
'present': present,
|
||||||
'title': content_existing[0] if existing else content_new[0],
|
'reset': existing,
|
||||||
'content': render_template(
|
'errmsg': errmsg,
|
||||||
'browser/master_password.html',
|
'is_error': True if errmsg else False
|
||||||
content_text=content_existing[1] if existing else content_new[1],
|
|
||||||
errmsg=errmsg
|
|
||||||
),
|
|
||||||
'reset': existing
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -814,6 +795,10 @@ def set_master_password():
|
|||||||
|
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
|
if request.form:
|
||||||
|
data = request.form
|
||||||
|
elif request.data:
|
||||||
|
data = request.data
|
||||||
if hasattr(request.data, 'decode'):
|
if hasattr(request.data, 'decode'):
|
||||||
data = request.data.decode('utf-8')
|
data = request.data.decode('utf-8')
|
||||||
|
|
||||||
@ -828,7 +813,7 @@ def set_master_password():
|
|||||||
and config.MASTER_PASSWORD_REQUIRED:
|
and config.MASTER_PASSWORD_REQUIRED:
|
||||||
# if master pass is set previously
|
# if master pass is set previously
|
||||||
if current_user.masterpass_check is not None and \
|
if current_user.masterpass_check is not None and \
|
||||||
data.get('button_click') and \
|
data.get('submit_password', False) and \
|
||||||
not validate_master_password(data.get('password')):
|
not validate_master_password(data.get('password')):
|
||||||
return form_master_password_response(
|
return form_master_password_response(
|
||||||
existing=True,
|
existing=True,
|
||||||
@ -864,7 +849,7 @@ def set_master_password():
|
|||||||
)
|
)
|
||||||
elif not get_crypt_key()[1]:
|
elif not get_crypt_key()[1]:
|
||||||
error_message = None
|
error_message = None
|
||||||
if data.get('button_click') and data.get('password') == '':
|
if data.get('submit_password') and data.get('password') == '':
|
||||||
# If user attempted to enter a blank password, then throw error
|
# If user attempted to enter a blank password, then throw error
|
||||||
error_message = gettext("Master password cannot be empty")
|
error_message = gettext("Master password cannot be empty")
|
||||||
return form_master_password_response(
|
return form_master_password_response(
|
||||||
|
115
web/pgadmin/browser/static/js/MasterPassowrdContent.jsx
Normal file
115
web/pgadmin/browser/static/js/MasterPassowrdContent.jsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import gettext from 'sources/gettext';
|
||||||
|
import url_for from 'sources/url_for';
|
||||||
|
|
||||||
|
import { Box } from '@material-ui/core';
|
||||||
|
import CloseIcon from '@material-ui/icons/CloseRounded';
|
||||||
|
import DeleteForeverIcon from '@material-ui/icons/DeleteForever';
|
||||||
|
import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
|
||||||
|
import HelpIcon from '@material-ui/icons/Help';
|
||||||
|
|
||||||
|
import { DefaultButton, PrimaryButton, PgIconButton } from '../../../static/js/components/Buttons';
|
||||||
|
import { useModalStyles } from '../../../static/js/helpers/ModalProvider';
|
||||||
|
import { FormFooterMessage, InputText, MESSAGE_TYPE } from '../../../static/js/components/FormComponents';
|
||||||
|
|
||||||
|
export default function MasterPasswordContent({ closeModal, onResetPassowrd, onOK, onCancel, setHeight, isPWDPresent, data}) {
|
||||||
|
const classes = useModalStyles();
|
||||||
|
const containerRef = useRef();
|
||||||
|
const firstEleRef = useRef();
|
||||||
|
const okBtnRef = useRef();
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
password: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const onTextChange = (e, id) => {
|
||||||
|
let val = e;
|
||||||
|
if (e && e.target) {
|
||||||
|
val = e.target.value;
|
||||||
|
}
|
||||||
|
setFormData((prev) => ({ ...prev, [id]: val }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (e) => {
|
||||||
|
// If enter key is pressed then click on OK button
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
okBtnRef.current?.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
firstEleRef.current && firstEleRef.current.focus();
|
||||||
|
}, 275);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setHeight?.(containerRef.current?.offsetHeight);
|
||||||
|
}, [containerRef.current]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box display="flex" flexDirection="column" className={classes.container} ref={containerRef}>
|
||||||
|
<Box flexGrow="1" p={2}>
|
||||||
|
<Box>
|
||||||
|
<span style={{ fontWeight: 'bold' }}>
|
||||||
|
{isPWDPresent ? gettext('Please enter your master password.') : gettext('Please set a master password for pgAdmin.')}
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
<span style={{ fontWeight: 'bold' }}>
|
||||||
|
{isPWDPresent ? gettext('This is required to unlock saved passwords and reconnect to the database server(s).') : gettext('This will be used to secure and later unlock saved passwords and other credentials.')}
|
||||||
|
</span>
|
||||||
|
</Box>
|
||||||
|
<Box marginTop='12px'>
|
||||||
|
<InputText inputRef={firstEleRef} type="password" value={formData['password']} maxLength={null}
|
||||||
|
onChange={(e) => onTextChange(e, 'password')} onKeyDown={(e) => onKeyDown(e)}/>
|
||||||
|
</Box>
|
||||||
|
<FormFooterMessage type={MESSAGE_TYPE.ERROR} message={data.errmsg} closable={false} style={{
|
||||||
|
position: 'unset', padding: '12px 0px 0px'
|
||||||
|
}} />
|
||||||
|
</Box>
|
||||||
|
<Box className={classes.footer}>
|
||||||
|
<Box style={{ marginRight: 'auto' }}>
|
||||||
|
<PgIconButton data-test="help-masterpassword" title={gettext('Help')} style={{ padding: '0.3rem', paddingLeft: '0.7rem' }} startIcon={<HelpIcon />} onClick={() => {
|
||||||
|
let _url = url_for('help.static', {
|
||||||
|
'filename': 'master_password.html',
|
||||||
|
});
|
||||||
|
window.open(_url, 'pgadmin_help');
|
||||||
|
}} >
|
||||||
|
</PgIconButton>
|
||||||
|
{isPWDPresent &&
|
||||||
|
<DefaultButton data-test="reset-masterpassword" style={{ marginLeft: '0.5rem' }} startIcon={<DeleteForeverIcon />}
|
||||||
|
onClick={() => {onResetPassowrd?.();}} >
|
||||||
|
{gettext('Reset Master Password')}
|
||||||
|
</DefaultButton>
|
||||||
|
}
|
||||||
|
</Box>
|
||||||
|
<DefaultButton data-test="close" startIcon={<CloseIcon />} onClick={() => {
|
||||||
|
onCancel?.();
|
||||||
|
closeModal();
|
||||||
|
}} >{gettext('Cancel')}</DefaultButton>
|
||||||
|
<PrimaryButton ref={okBtnRef} data-test="save" className={classes.margin} startIcon={<CheckRoundedIcon />}
|
||||||
|
disabled={formData.password.length == 0}
|
||||||
|
onClick={() => {
|
||||||
|
let postFormData = new FormData();
|
||||||
|
postFormData.append('password', formData.password);
|
||||||
|
postFormData.append('submit_password', true);
|
||||||
|
onOK?.(postFormData);
|
||||||
|
closeModal();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{gettext('OK')}
|
||||||
|
</PrimaryButton>
|
||||||
|
</Box>
|
||||||
|
</Box>);
|
||||||
|
}
|
||||||
|
|
||||||
|
MasterPasswordContent.propTypes = {
|
||||||
|
closeModal: PropTypes.func,
|
||||||
|
onResetPassowrd: PropTypes.func,
|
||||||
|
onOK: PropTypes.func,
|
||||||
|
onCancel: PropTypes.func,
|
||||||
|
setHeight: PropTypes.func,
|
||||||
|
isPWDPresent: PropTypes.bool,
|
||||||
|
data: PropTypes.object,
|
||||||
|
};
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
import { generateNodeUrl } from './node_ajax';
|
import { generateNodeUrl } from './node_ajax';
|
||||||
import Notify, {initializeModalProvider, initializeNotifier} from '../../../static/js/helpers/Notifier';
|
import Notify, {initializeModalProvider, initializeNotifier} from '../../../static/js/helpers/Notifier';
|
||||||
|
import { checkMasterPassword } from './password_dialogs';
|
||||||
|
|
||||||
define('pgadmin.browser', [
|
define('pgadmin.browser', [
|
||||||
'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore',
|
'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore',
|
||||||
@ -569,101 +570,6 @@ define('pgadmin.browser', [
|
|||||||
Notify.alert(error);
|
Notify.alert(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
init_master_password: function() {
|
|
||||||
let self = this;
|
|
||||||
// Master password dialog
|
|
||||||
if (!Alertify.dlgMasterPass) {
|
|
||||||
Alertify.dialog('dlgMasterPass', function factory() {
|
|
||||||
return {
|
|
||||||
main: function(title, message, reset) {
|
|
||||||
this.set('title', title);
|
|
||||||
this.message = message;
|
|
||||||
this.reset = reset;
|
|
||||||
},
|
|
||||||
build: function() {
|
|
||||||
Alertify.pgDialogBuild.apply(this);
|
|
||||||
},
|
|
||||||
setup:function() {
|
|
||||||
return {
|
|
||||||
buttons:[{
|
|
||||||
text: '',
|
|
||||||
className: 'btn btn-primary-icon pull-left fa fa-question pg-alertify-icon-button',
|
|
||||||
attrs: {
|
|
||||||
name: 'dialog_help',
|
|
||||||
type: 'button',
|
|
||||||
label: gettext('Master password'),
|
|
||||||
url: url_for('help.static', {
|
|
||||||
'filename': 'master_password.html',
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},{
|
|
||||||
text: gettext('Reset Master Password'), className: 'btn btn-secondary fa fa-trash-alt pg-alertify-button pull-left',
|
|
||||||
},{
|
|
||||||
text: gettext('Cancel'), className: 'btn btn-secondary fa fa-times pg-alertify-button',
|
|
||||||
key: 27,
|
|
||||||
},{
|
|
||||||
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
|
|
||||||
}],
|
|
||||||
focus: {element: '#password', select: true},
|
|
||||||
options: {
|
|
||||||
modal: true, resizable: false, maximizable: false, pinnable: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
prepare:function() {
|
|
||||||
let _self = this;
|
|
||||||
_self.setContent(_self.message);
|
|
||||||
/* Reset button hide */
|
|
||||||
if(!_self.reset) {
|
|
||||||
$(_self.__internal.buttons[1].element).addClass('d-none');
|
|
||||||
} else {
|
|
||||||
$(_self.__internal.buttons[1].element).removeClass('d-none');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
callback: function(event) {
|
|
||||||
let parentDialog = this;
|
|
||||||
|
|
||||||
if (event.index == 3) {
|
|
||||||
/* OK Button */
|
|
||||||
self.set_master_password(
|
|
||||||
$('#frmMasterPassword #password').val(),
|
|
||||||
true,parentDialog.set_callback,
|
|
||||||
);
|
|
||||||
} else if(event.index == 2) {
|
|
||||||
/* Cancel button */
|
|
||||||
self.masterpass_callback_queue = [];
|
|
||||||
self.cancel_callback();
|
|
||||||
} else if(event.index == 1) {
|
|
||||||
/* Reset Button */
|
|
||||||
event.cancel = true;
|
|
||||||
|
|
||||||
Notify.confirm(gettext('Reset Master Password'),
|
|
||||||
gettext('This will remove all the saved passwords. This will also remove established connections to '
|
|
||||||
+ 'the server and you may need to reconnect again. Do you wish to continue?'),
|
|
||||||
function() {
|
|
||||||
/* If user clicks Yes */
|
|
||||||
self.reset_master_password();
|
|
||||||
parentDialog.close();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
function() {/* If user clicks No */ return true;}
|
|
||||||
);
|
|
||||||
} else if(event.index == 0) {
|
|
||||||
/* help Button */
|
|
||||||
event.cancel = true;
|
|
||||||
self.showHelp(
|
|
||||||
event.button.element.name,
|
|
||||||
event.button.element.getAttribute('url'),
|
|
||||||
null, null
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
check_master_password: function(on_resp_callback) {
|
check_master_password: function(on_resp_callback) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url_for('browser.check_master_password'),
|
url: url_for('browser.check_master_password'),
|
||||||
@ -697,40 +603,21 @@ define('pgadmin.browser', [
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
set_master_password: function(password='', button_click=false,
|
set_master_password: function(password='',
|
||||||
set_callback=()=>{/*This is intentional (SonarQube)*/},
|
set_callback=()=>{/*This is intentional (SonarQube)*/},
|
||||||
cancel_callback=()=>{/*This is intentional (SonarQube)*/}) {
|
cancel_callback=()=>{/*This is intentional (SonarQube)*/}) {
|
||||||
let data=null, self = this;
|
let data=null, self = this;
|
||||||
|
|
||||||
data = JSON.stringify({
|
// data = JSON.stringify({
|
||||||
|
// 'password': password,
|
||||||
|
// });
|
||||||
|
data = {
|
||||||
'password': password,
|
'password': password,
|
||||||
'button_click': button_click,
|
};
|
||||||
});
|
|
||||||
|
|
||||||
self.masterpass_callback_queue.push(set_callback);
|
self.masterpass_callback_queue.push(set_callback);
|
||||||
self.cancel_callback = cancel_callback;
|
// Check master passowrd.
|
||||||
|
checkMasterPassword(data, self.masterpass_callback_queue, cancel_callback);
|
||||||
$.ajax({
|
|
||||||
url: url_for('browser.set_master_password'),
|
|
||||||
type: 'POST',
|
|
||||||
data: data,
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json',
|
|
||||||
}).done((res)=> {
|
|
||||||
if(!res.data.present) {
|
|
||||||
self.init_master_password();
|
|
||||||
Alertify.dlgMasterPass(res.data.title, res.data.content, res.data.reset);
|
|
||||||
} else {
|
|
||||||
setTimeout(()=>{
|
|
||||||
while(self.masterpass_callback_queue.length > 0) {
|
|
||||||
let callback = self.masterpass_callback_queue.shift();
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
}).fail(function(xhr, status, error) {
|
|
||||||
Notify.pgRespErrorNotify(xhr, error);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
bind_beforeunload: function() {
|
bind_beforeunload: function() {
|
||||||
|
@ -13,7 +13,11 @@ import pgAdmin from 'sources/pgadmin';
|
|||||||
import ConnectServerContent from './ConnectServerContent';
|
import ConnectServerContent from './ConnectServerContent';
|
||||||
import Theme from 'sources/Theme';
|
import Theme from 'sources/Theme';
|
||||||
import url_for from 'sources/url_for';
|
import url_for from 'sources/url_for';
|
||||||
|
import gettext from 'sources/gettext';
|
||||||
|
|
||||||
import getApiInstance from '../../../static/js/api_instance';
|
import getApiInstance from '../../../static/js/api_instance';
|
||||||
|
import MasterPasswordContent from './MasterPassowrdContent';
|
||||||
|
import Notify from '../../../static/js/helpers/Notifier';
|
||||||
|
|
||||||
function setNewSize(panel, width, height) {
|
function setNewSize(panel, width, height) {
|
||||||
// Add height of the header
|
// Add height of the header
|
||||||
@ -130,3 +134,92 @@ export function showSchemaDiffServerPassword() {
|
|||||||
/>
|
/>
|
||||||
</Theme>, j[0]);
|
</Theme>, j[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function masterPassCallbacks(masterpass_callback_queue) {
|
||||||
|
while(masterpass_callback_queue.length > 0) {
|
||||||
|
let callback = masterpass_callback_queue.shift();
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkMasterPassword(data, masterpass_callback_queue, cancel_callback) {
|
||||||
|
const api = getApiInstance();
|
||||||
|
api.post(url_for('browser.set_master_password'), data).then((res)=> {
|
||||||
|
if(!res.data.data.present) {
|
||||||
|
showMasterPassword(res.data.data.reset, res.data.data.errmsg, masterpass_callback_queue, cancel_callback);
|
||||||
|
} else {
|
||||||
|
masterPassCallbacks(masterpass_callback_queue);
|
||||||
|
}
|
||||||
|
}).catch(function(xhr, status, error) {
|
||||||
|
Notify.pgRespErrorNotify(xhr, error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// This functions is used to show the master password dialog.
|
||||||
|
export function showMasterPassword(isPWDPresent, errmsg=null, masterpass_callback_queue, cancel_callback) {
|
||||||
|
const api = getApiInstance();
|
||||||
|
var pgBrowser = pgAdmin.Browser;
|
||||||
|
|
||||||
|
// Register dialog panel
|
||||||
|
pgBrowser.Node.registerUtilityPanel();
|
||||||
|
var panel = pgBrowser.Node.addUtilityPanel(pgBrowser.stdW.md),
|
||||||
|
j = panel.$container.find('.obj_properties').first();
|
||||||
|
|
||||||
|
let title = isPWDPresent ? gettext('Unlock Saved Passwords') : gettext('Set Master Password');
|
||||||
|
panel.title(title);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Theme>
|
||||||
|
<MasterPasswordContent
|
||||||
|
isPWDPresent= {isPWDPresent}
|
||||||
|
data={{'errmsg': errmsg}}
|
||||||
|
setHeight={(containerHeight) => {
|
||||||
|
setNewSize(panel, pgBrowser.stdW.md, containerHeight);
|
||||||
|
}}
|
||||||
|
closeModal={() => {
|
||||||
|
panel.close();
|
||||||
|
}}
|
||||||
|
onResetPassowrd={()=>{
|
||||||
|
Notify.confirm(gettext('Reset Master Password'),
|
||||||
|
gettext('This will remove all the saved passwords. This will also remove established connections to '
|
||||||
|
+ 'the server and you may need to reconnect again. Do you wish to continue?'),
|
||||||
|
function() {
|
||||||
|
var _url = url_for('browser.reset_master_password');
|
||||||
|
|
||||||
|
api.delete(_url)
|
||||||
|
.then(() => {
|
||||||
|
panel.close();
|
||||||
|
showMasterPassword(false, null, masterpass_callback_queue, cancel_callback);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
Notify.error(err.message);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
function() {/* If user clicks No */ return true;}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
onCancel={()=>{
|
||||||
|
cancel_callback?.();
|
||||||
|
}}
|
||||||
|
onOK={(formData) => {
|
||||||
|
panel.close();
|
||||||
|
checkMasterPassword(formData, masterpass_callback_queue, cancel_callback);
|
||||||
|
// var _url = url_for('browser.set_master_password');
|
||||||
|
|
||||||
|
// api.post(_url, formData)
|
||||||
|
// .then(res => {
|
||||||
|
// panel.close();
|
||||||
|
// if(res.data.data.is_error) {
|
||||||
|
// showMasterPassword(true, res.data.data.errmsg, masterpass_callback_queue, cancel_callback);
|
||||||
|
// } else {
|
||||||
|
// masterPassCallbacks(masterpass_callback_queue);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .catch((err) => {
|
||||||
|
// Notify.error(err.message);
|
||||||
|
// });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Theme>, j[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
<form name="frmMasterPassword" id="frmMasterPassword" style="height: 100%; width: 100%" onsubmit="return false;">
|
|
||||||
<div>
|
|
||||||
<div><strong>{{ content_text|safe }}</strong></div>
|
|
||||||
<div class="input-group row py-2">
|
|
||||||
<label for="password" class="col-sm-2 col-form-label">{{ _('Password') }}</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="password" class="form-control" id="password" name="password">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if errmsg %}
|
|
||||||
<div class='pg-prop-status-bar p-0'>
|
|
||||||
<div class="error-in-footer">
|
|
||||||
<div class="d-flex px-2 py-1">
|
|
||||||
<div class="pr-2">
|
|
||||||
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i>
|
|
||||||
</div>
|
|
||||||
<div class="alert-text">{{ errmsg }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
@ -25,30 +25,20 @@ class MasterPasswordTestCase(BaseTestGenerator):
|
|||||||
# This testcase validates invalid confirmation password
|
# This testcase validates invalid confirmation password
|
||||||
('TestCase for Create master password dialog', dict(
|
('TestCase for Create master password dialog', dict(
|
||||||
password="",
|
password="",
|
||||||
content=(
|
errmsg=None,
|
||||||
"Set Master Password",
|
is_error=False
|
||||||
[
|
|
||||||
"Please set a master password for pgAdmin.",
|
|
||||||
"This will be used to secure and later unlock saved "
|
|
||||||
"passwords and other credentials."
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)),
|
)),
|
||||||
('TestCase for Setting Master Password', dict(
|
('TestCase for Setting Master Password', dict(
|
||||||
password="masterpasstest",
|
password="masterpasstest",
|
||||||
check_if_set=True,
|
check_if_set=True,
|
||||||
|
errmsg=None,
|
||||||
|
is_error=False
|
||||||
)),
|
)),
|
||||||
('TestCase for Resetting Master Password', dict(
|
('TestCase for Resetting Master Password', dict(
|
||||||
reset=True,
|
reset=True,
|
||||||
password="",
|
password="",
|
||||||
content=(
|
errmsg=None,
|
||||||
"Set Master Password",
|
is_error=False
|
||||||
[
|
|
||||||
"Please set a master password for pgAdmin.",
|
|
||||||
"This will be used to secure and later unlock saved "
|
|
||||||
"passwords and other credentials."
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)),
|
)),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -90,13 +80,6 @@ class MasterPasswordTestCase(BaseTestGenerator):
|
|||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
if hasattr(self, 'content'):
|
|
||||||
self.assertEqual(response.json['data']['title'],
|
|
||||||
self.content[0])
|
|
||||||
|
|
||||||
for text in self.content[1]:
|
|
||||||
self.assertIn(text, response.json['data']['content'])
|
|
||||||
|
|
||||||
if hasattr(self, 'check_if_set'):
|
if hasattr(self, 'check_if_set'):
|
||||||
response = self.tester.get(
|
response = self.tester.get(
|
||||||
'/browser/master_password'
|
'/browser/master_password'
|
||||||
|
@ -196,7 +196,7 @@ var Notifier = {
|
|||||||
|
|
||||||
if(resp.info == 'CRYPTKEY_MISSING') {
|
if(resp.info == 'CRYPTKEY_MISSING') {
|
||||||
var pgBrowser = window.pgAdmin.Browser;
|
var pgBrowser = window.pgAdmin.Browser;
|
||||||
pgBrowser.set_master_password('', false, ()=> {
|
pgBrowser.set_master_password('', ()=> {
|
||||||
if(onJSONResult && typeof(onJSONResult) == 'function') {
|
if(onJSONResult && typeof(onJSONResult) == 'function') {
|
||||||
onJSONResult('CRYPTKEY_SET');
|
onJSONResult('CRYPTKEY_SET');
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user