Allow to set user admin status in dialog
This commit is contained in:
parent
aa9d507d12
commit
e6ab7d61f1
@ -50,6 +50,20 @@ class UserTest extends UloggerDatabaseTestCase {
|
|||||||
$this->assertFalse($userInvalid->setPass($newPass), "Setting pass for nonexistant user should fail");
|
$this->assertFalse($userInvalid->setPass($newPass), "Setting pass for nonexistant user should fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSetAdmin() {
|
||||||
|
$this->addTestUser($this->testUser);
|
||||||
|
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
|
||||||
|
$user = new uUser($this->testUser);
|
||||||
|
$this->assertFalse((bool) $this->pdoGetColumn("SELECT admin FROM users"), "User should not be admin");
|
||||||
|
$this->assertFalse($user->isAdmin, "User should not be admin");
|
||||||
|
$user->setAdmin(true);
|
||||||
|
$this->assertTrue((bool) $this->pdoGetColumn("SELECT admin FROM users"), "User should be admin");
|
||||||
|
$this->assertTrue($user->isAdmin, "User should be admin");
|
||||||
|
$user->setAdmin(false);
|
||||||
|
$this->assertFalse((bool) $this->pdoGetColumn("SELECT admin FROM users"), "User should not be admin");
|
||||||
|
$this->assertFalse($user->isAdmin, "User should not be admin");
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetAll() {
|
public function testGetAll() {
|
||||||
$this->addTestUser($this->testUser);
|
$this->addTestUser($this->testUser);
|
||||||
$this->addTestUser($this->testUser2);
|
$this->addTestUser($this->testUser2);
|
||||||
|
@ -126,6 +126,27 @@
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set user admin status
|
||||||
|
*
|
||||||
|
* @param bool $isAdmin True if is admin
|
||||||
|
* @return bool True on success, false otherwise
|
||||||
|
*/
|
||||||
|
public function setAdmin($isAdmin) {
|
||||||
|
$ret = false;
|
||||||
|
try {
|
||||||
|
$query = "UPDATE " . self::db()->table('users') . " SET admin = ? WHERE login = ?";
|
||||||
|
$stmt = self::db()->prepare($query);
|
||||||
|
$stmt->execute([ $isAdmin, $this->login ]);
|
||||||
|
$ret = true;
|
||||||
|
$this->isAdmin = $isAdmin;
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
// TODO: handle exception
|
||||||
|
syslog(LOG_ERR, $e->getMessage());
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set user password
|
* Set user password
|
||||||
*
|
*
|
||||||
|
@ -149,6 +149,10 @@
|
|||||||
return self::requestString($name, $default, INPUT_GET);
|
return self::requestString($name, $default, INPUT_GET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function postBool($name, $default = NULL) {
|
||||||
|
return self::requestValue($name, $default, INPUT_POST, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
public static function getBool($name, $default = NULL) {
|
public static function getBool($name, $default = NULL) {
|
||||||
return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_BOOLEAN);
|
return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_BOOLEAN);
|
||||||
}
|
}
|
||||||
|
@ -31,14 +31,16 @@ export default class uUser extends uListItem {
|
|||||||
/**
|
/**
|
||||||
* @param {number} id
|
* @param {number} id
|
||||||
* @param {string} login
|
* @param {string} login
|
||||||
|
* @param {boolean=} isAdmin
|
||||||
*/
|
*/
|
||||||
constructor(id, login) {
|
constructor(id, login, isAdmin = null) {
|
||||||
super();
|
super();
|
||||||
if (!Number.isSafeInteger(id) || id <= 0) {
|
if (!Number.isSafeInteger(id) || id <= 0) {
|
||||||
throw new Error('Invalid argument for user constructor');
|
throw new Error('Invalid argument for user constructor');
|
||||||
}
|
}
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.login = login;
|
this.login = login;
|
||||||
|
this.isAdmin = isAdmin;
|
||||||
this.listItem(id, login);
|
this.listItem(id, login);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +67,7 @@ export default class uUser extends uListItem {
|
|||||||
return uAjax.get('utils/getusers.php').then((_users) => {
|
return uAjax.get('utils/getusers.php').then((_users) => {
|
||||||
const users = [];
|
const users = [];
|
||||||
for (const user of _users) {
|
for (const user of _users) {
|
||||||
users.push(new uUser(user.id, user.login));
|
users.push(new uUser(user.id, user.login, user.isAdmin));
|
||||||
}
|
}
|
||||||
return users;
|
return users;
|
||||||
});
|
});
|
||||||
@ -101,8 +103,8 @@ export default class uUser extends uListItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} password
|
* @param {string} password New password
|
||||||
* @param {string=} oldPassword Needed when changing own password
|
* @param {string} oldPassword Current password
|
||||||
* @return {Promise<void, Error>}
|
* @return {Promise<void, Error>}
|
||||||
*/
|
*/
|
||||||
setPassword(password, oldPassword) {
|
setPassword(password, oldPassword) {
|
||||||
@ -113,4 +115,23 @@ export default class uUser extends uListItem {
|
|||||||
oldpass: oldPassword
|
oldpass: oldPassword
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} isAdmin
|
||||||
|
* @param {string|null} password
|
||||||
|
* @return {Promise<void, Error>}
|
||||||
|
*/
|
||||||
|
modify(isAdmin, password = null) {
|
||||||
|
const data = {
|
||||||
|
action: 'update',
|
||||||
|
login: this.login,
|
||||||
|
admin: isAdmin
|
||||||
|
};
|
||||||
|
if (password) {
|
||||||
|
data.pass = password;
|
||||||
|
}
|
||||||
|
return uUser.update(data)
|
||||||
|
.then(() => { this.isAdmin = isAdmin; });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,18 +33,22 @@ export default class UserDialogModel extends ViewModel {
|
|||||||
super({
|
super({
|
||||||
onUserDelete: null,
|
onUserDelete: null,
|
||||||
onUserUpdate: null,
|
onUserUpdate: null,
|
||||||
|
onPassChange: null,
|
||||||
onUserAdd: null,
|
onUserAdd: null,
|
||||||
onCancel: null,
|
onCancel: null,
|
||||||
|
passVisibility: false,
|
||||||
login: null,
|
login: null,
|
||||||
password: null,
|
password: null,
|
||||||
password2: null,
|
password2: null,
|
||||||
oldPassword: null
|
oldPassword: null,
|
||||||
|
admin: false
|
||||||
});
|
});
|
||||||
this.user = viewModel.state.currentUser;
|
this.user = viewModel.state.currentUser;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.userVM = viewModel;
|
this.userVM = viewModel;
|
||||||
this.model.onUserDelete = () => this.onUserDelete();
|
this.model.onUserDelete = () => this.onUserDelete();
|
||||||
this.model.onUserUpdate = () => this.onUserUpdate();
|
this.model.onUserUpdate = () => this.onUserUpdate();
|
||||||
|
this.model.onPassChange = () => this.onPassChange();
|
||||||
this.model.onUserAdd = () => this.onUserAdd();
|
this.model.onUserAdd = () => this.onUserAdd();
|
||||||
this.model.onCancel = () => this.onCancel();
|
this.model.onCancel = () => this.onCancel();
|
||||||
}
|
}
|
||||||
@ -54,6 +58,14 @@ export default class UserDialogModel extends ViewModel {
|
|||||||
this.dialog = new uDialog(html);
|
this.dialog = new uDialog(html);
|
||||||
this.dialog.show();
|
this.dialog.show();
|
||||||
this.bindAll(this.dialog.element);
|
this.bindAll(this.dialog.element);
|
||||||
|
const passInput = this.getBoundElement('passInput');
|
||||||
|
this.onChanged('passVisibility', () => {
|
||||||
|
if (passInput.style.display === 'none') {
|
||||||
|
passInput.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
passInput.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onUserDelete() {
|
onUserDelete() {
|
||||||
@ -67,8 +79,16 @@ export default class UserDialogModel extends ViewModel {
|
|||||||
|
|
||||||
onUserUpdate() {
|
onUserUpdate() {
|
||||||
if (this.validate()) {
|
if (this.validate()) {
|
||||||
const user = this.type === 'pass' ? auth.user : this.user;
|
const password = this.model.passVisibility ? this.model.password : null;
|
||||||
user.setPassword(this.model.password, this.model.oldPassword)
|
this.user.modify(this.model.admin, password)
|
||||||
|
.then(() => this.dialog.destroy())
|
||||||
|
.catch((e) => { uUtils.error(e, `${$._('actionfailure')}\n${e.message}`); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPassChange() {
|
||||||
|
if (this.validate()) {
|
||||||
|
auth.user.setPassword(this.model.password, this.model.oldPassword)
|
||||||
.then(() => this.dialog.destroy())
|
.then(() => this.dialog.destroy())
|
||||||
.catch((e) => { uUtils.error(e, `${$._('actionfailure')}\n${e.message}`); });
|
.catch((e) => { uUtils.error(e, `${$._('actionfailure')}\n${e.message}`); });
|
||||||
}
|
}
|
||||||
@ -76,7 +96,7 @@ export default class UserDialogModel extends ViewModel {
|
|||||||
|
|
||||||
onUserAdd() {
|
onUserAdd() {
|
||||||
if (this.validate()) {
|
if (this.validate()) {
|
||||||
uUser.add(this.model.login, this.model.password).then((user) => {
|
uUser.add(this.model.login, this.model.password, this.model.admin).then((user) => {
|
||||||
this.userVM.onUserAdded(user);
|
this.userVM.onUserAdded(user);
|
||||||
this.dialog.destroy();
|
this.dialog.destroy();
|
||||||
}).catch((e) => { uUtils.error(e, `${$._('actionfailure')}\n${e.message}`); });
|
}).catch((e) => { uUtils.error(e, `${$._('actionfailure')}\n${e.message}`); });
|
||||||
@ -103,17 +123,19 @@ export default class UserDialogModel extends ViewModel {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.model.password || !this.model.password2) {
|
if (this.type === 'pass' || this.model.passVisibility) {
|
||||||
alert($._('allrequired'));
|
if (!this.model.password || !this.model.password2) {
|
||||||
return false;
|
alert($._('allrequired'));
|
||||||
}
|
return false;
|
||||||
if (this.model.password !== this.model.password2) {
|
}
|
||||||
alert($._('passnotmatch'));
|
if (this.model.password !== this.model.password2) {
|
||||||
return false;
|
alert($._('passnotmatch'));
|
||||||
}
|
return false;
|
||||||
if (!config.passRegex.test(this.model.password)) {
|
}
|
||||||
alert($._('passlenmin') + '\n' + $._('passrules'));
|
if (!config.passRegex.test(this.model.password)) {
|
||||||
return false;
|
alert($._('passlenmin') + '\n' + $._('passrules'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -134,20 +156,28 @@ export default class UserDialogModel extends ViewModel {
|
|||||||
fields = `<label><b>${$._('password')}</b></label>
|
fields = `<label><b>${$._('password')}</b></label>
|
||||||
<input type="password" placeholder="${$._('passwordenter')}" name="password" data-bind="password" required>
|
<input type="password" placeholder="${$._('passwordenter')}" name="password" data-bind="password" required>
|
||||||
<label><b>${$._('passwordrepeat')}</b></label>
|
<label><b>${$._('passwordrepeat')}</b></label>
|
||||||
<input type="password" placeholder="${$._('passwordenter')}" name="password2" data-bind="password2" required>`;
|
<input type="password" placeholder="${$._('passwordenter')}" name="password2" data-bind="password2" required>
|
||||||
|
<label><b>${$._('admin')}</b></label>
|
||||||
|
<input type="checkbox" name="admin" data-bind="admin">`;
|
||||||
break;
|
break;
|
||||||
case 'edit':
|
case 'edit':
|
||||||
observer = 'onUserUpdate';
|
observer = 'onUserUpdate';
|
||||||
deleteButton = `<div class="red-button button-resolve"><b><a data-bind="onUserDelete">${$._('deluser')}</a></b></div>
|
deleteButton = `<div class="red-button button-resolve"><b><a data-bind="onUserDelete">${$._('deluser')}</a></b></div>
|
||||||
<div>${$._('editinguser', `<b>${uUtils.htmlEncode(this.user.login)}</b>`)}</div>
|
<div>${$._('editinguser', `<b>${uUtils.htmlEncode(this.user.login)}</b>`)}</div>
|
||||||
<div style="clear: both; padding-bottom: 1em;"></div>`;
|
<div style="clear: both; padding-bottom: 1em;"></div>`;
|
||||||
fields = `<label><b>${$._('password')}</b></label>
|
fields = `<label><b>${$._('changepass')}</b></label>
|
||||||
<input type="password" placeholder="${$._('passwordenter')}" name="password" data-bind="password" required>
|
<input type="checkbox" name="changepass" data-bind="passVisibility"><br>
|
||||||
<label><b>${$._('passwordrepeat')}</b></label>
|
<div style="display: none;" data-bind="passInput">
|
||||||
<input type="password" placeholder="${$._('passwordenter')}" name="password2" data-bind="password2" required>`;
|
<label><b>${$._('password')}</b></label>
|
||||||
|
<input type="password" placeholder="${$._('passwordenter')}" name="password" data-bind="password" required>
|
||||||
|
<label><b>${$._('passwordrepeat')}</b></label>
|
||||||
|
<input type="password" placeholder="${$._('passwordenter')}" name="password2" data-bind="password2" required>
|
||||||
|
</div>
|
||||||
|
<label><b>${$._('admin')}</b></label>
|
||||||
|
<input type="checkbox" name="admin" data-bind="admin" ${this.user.isAdmin ? 'checked' : ''}>`;
|
||||||
break;
|
break;
|
||||||
case 'pass':
|
case 'pass':
|
||||||
observer = 'onUserUpdate';
|
observer = 'onPassChange';
|
||||||
fields = `<label><b>${$._('oldpassword')}</b></label>
|
fields = `<label><b>${$._('oldpassword')}</b></label>
|
||||||
<input type="password" placeholder="${$._('passwordenter')}" name="old-password" data-bind="oldPassword" required>
|
<input type="password" placeholder="${$._('passwordenter')}" name="old-password" data-bind="oldPassword" required>
|
||||||
<label><b>${$._('newpassword')}</b></label>
|
<label><b>${$._('newpassword')}</b></label>
|
||||||
|
@ -46,6 +46,8 @@ describe('UserDialogModel tests', () => {
|
|||||||
dm.user = new uUser(1, 'testUser');
|
dm.user = new uUser(1, 'testUser');
|
||||||
spyOn(dm.user, 'delete').and.returnValue(Promise.resolve());
|
spyOn(dm.user, 'delete').and.returnValue(Promise.resolve());
|
||||||
spyOn(dm.user, 'setPassword').and.returnValue(Promise.resolve());
|
spyOn(dm.user, 'setPassword').and.returnValue(Promise.resolve());
|
||||||
|
spyOn(dm.user, 'modify').and.callThrough();
|
||||||
|
spyOn(uUser, 'update').and.returnValue(Promise.resolve());
|
||||||
spyOn(auth.user, 'setPassword').and.returnValue(Promise.resolve());
|
spyOn(auth.user, 'setPassword').and.returnValue(Promise.resolve());
|
||||||
spyOn(uUser, 'add').and.returnValue(Promise.resolve(newUser));
|
spyOn(uUser, 'add').and.returnValue(Promise.resolve(newUser));
|
||||||
spyOn(config.passRegex, 'test').and.returnValue(true);
|
spyOn(config.passRegex, 'test').and.returnValue(true);
|
||||||
@ -92,7 +94,7 @@ describe('UserDialogModel tests', () => {
|
|||||||
dm.init();
|
dm.init();
|
||||||
// then
|
// then
|
||||||
expect(document.querySelector('#modal')).toBeInstanceOf(HTMLDivElement);
|
expect(document.querySelector('#modal')).toBeInstanceOf(HTMLDivElement);
|
||||||
expect(dm.dialog.element.querySelector("[data-bind='onUserUpdate']")).toBeInstanceOf(HTMLButtonElement);
|
expect(dm.dialog.element.querySelector("[data-bind='onPassChange']")).toBeInstanceOf(HTMLButtonElement);
|
||||||
expect(dm.dialog.element.querySelector("[data-bind='onUserDelete']")).toBe(null);
|
expect(dm.dialog.element.querySelector("[data-bind='onUserDelete']")).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -135,16 +137,67 @@ describe('UserDialogModel tests', () => {
|
|||||||
dm.type = 'edit';
|
dm.type = 'edit';
|
||||||
dm.init();
|
dm.init();
|
||||||
const button = dm.dialog.element.querySelector("[data-bind='onUserUpdate']");
|
const button = dm.dialog.element.querySelector("[data-bind='onUserUpdate']");
|
||||||
|
const passVisibility = dm.dialog.element.querySelector("[data-bind='passVisibility']");
|
||||||
const passEl = dm.dialog.element.querySelector("[data-bind='password']");
|
const passEl = dm.dialog.element.querySelector("[data-bind='password']");
|
||||||
const newPassword = 'newpass';
|
const newPassword = 'newpass';
|
||||||
// when
|
// when
|
||||||
|
passVisibility.checked = true;
|
||||||
|
passVisibility.dispatchEvent(new Event('change'));
|
||||||
passEl.value = newPassword;
|
passEl.value = newPassword;
|
||||||
passEl.dispatchEvent(new Event('change'));
|
passEl.dispatchEvent(new Event('change'));
|
||||||
button.click();
|
button.click();
|
||||||
// then
|
// then
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(dm.user.setPassword).toHaveBeenCalledTimes(1);
|
expect(dm.user.modify).toHaveBeenCalledTimes(1);
|
||||||
expect(dm.user.setPassword).toHaveBeenCalledWith(newPassword, null);
|
expect(dm.user.modify).toHaveBeenCalledWith(dm.model.admin, newPassword);
|
||||||
|
expect(document.querySelector('#modal')).toBe(null);
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should toggle password input fields visibility on user edit form', (done) => {
|
||||||
|
// given
|
||||||
|
dm.type = 'edit';
|
||||||
|
dm.init();
|
||||||
|
const passInput = dm.getBoundElement('passInput');
|
||||||
|
const passVisibility = dm.dialog.element.querySelector("[data-bind='passVisibility']");
|
||||||
|
|
||||||
|
expect(passInput.style.display).toBe('none');
|
||||||
|
// when
|
||||||
|
passVisibility.checked = true;
|
||||||
|
passVisibility.dispatchEvent(new Event('change'));
|
||||||
|
// then
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(passInput.style.display).toBe('block');
|
||||||
|
// when
|
||||||
|
passVisibility.checked = false;
|
||||||
|
passVisibility.dispatchEvent(new Event('change'));
|
||||||
|
// then
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(passInput.style.display).toBe('none');
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update user admin status and hide edit dialog on positive button clicked', (done) => {
|
||||||
|
// given
|
||||||
|
spyOn(dm, 'validate').and.returnValue(true);
|
||||||
|
dm.type = 'edit';
|
||||||
|
dm.init();
|
||||||
|
const button = dm.dialog.element.querySelector("[data-bind='onUserUpdate']");
|
||||||
|
const adminEl = dm.dialog.element.querySelector("[data-bind='admin']");
|
||||||
|
const isAdmin = true;
|
||||||
|
// when
|
||||||
|
adminEl.checked = isAdmin;
|
||||||
|
adminEl.dispatchEvent(new Event('change'));
|
||||||
|
button.click();
|
||||||
|
// then
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(dm.user.modify).toHaveBeenCalledTimes(1);
|
||||||
|
expect(dm.user.modify).toHaveBeenCalledWith(isAdmin, null);
|
||||||
|
expect(dm.user.isAdmin).toBeTrue();
|
||||||
expect(document.querySelector('#modal')).toBe(null);
|
expect(document.querySelector('#modal')).toBe(null);
|
||||||
done();
|
done();
|
||||||
}, 100);
|
}, 100);
|
||||||
@ -155,7 +208,7 @@ describe('UserDialogModel tests', () => {
|
|||||||
spyOn(dm, 'validate').and.returnValue(true);
|
spyOn(dm, 'validate').and.returnValue(true);
|
||||||
dm.type = 'pass';
|
dm.type = 'pass';
|
||||||
dm.init();
|
dm.init();
|
||||||
const button = dm.dialog.element.querySelector("[data-bind='onUserUpdate']");
|
const button = dm.dialog.element.querySelector("[data-bind='onPassChange']");
|
||||||
const passEl = dm.dialog.element.querySelector("[data-bind='password']");
|
const passEl = dm.dialog.element.querySelector("[data-bind='password']");
|
||||||
const passOldEl = dm.dialog.element.querySelector("[data-bind='oldPassword']");
|
const passOldEl = dm.dialog.element.querySelector("[data-bind='oldPassword']");
|
||||||
const newPassword = 'newpass';
|
const newPassword = 'newpass';
|
||||||
@ -194,7 +247,7 @@ describe('UserDialogModel tests', () => {
|
|||||||
// then
|
// then
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(uUser.add).toHaveBeenCalledTimes(1);
|
expect(uUser.add).toHaveBeenCalledTimes(1);
|
||||||
expect(uUser.add).toHaveBeenCalledWith(newUser.login, newPassword);
|
expect(uUser.add).toHaveBeenCalledWith(newUser.login, newPassword, false);
|
||||||
expect(mockVM.onUserAdded).toHaveBeenCalledWith(newUser);
|
expect(mockVM.onUserAdded).toHaveBeenCalledWith(newUser);
|
||||||
expect(document.querySelector('#modal')).toBe(null);
|
expect(document.querySelector('#modal')).toBe(null);
|
||||||
done();
|
done();
|
||||||
@ -257,6 +310,7 @@ describe('UserDialogModel tests', () => {
|
|||||||
it('should return false on add user dialog passwords not match', () => {
|
it('should return false on add user dialog passwords not match', () => {
|
||||||
// given
|
// given
|
||||||
dm.model.login = 'test';
|
dm.model.login = 'test';
|
||||||
|
dm.model.passVisibility = true;
|
||||||
dm.model.password = 'password';
|
dm.model.password = 'password';
|
||||||
dm.model.password2 = 'password2';
|
dm.model.password2 = 'password2';
|
||||||
// when
|
// when
|
||||||
@ -266,10 +320,24 @@ describe('UserDialogModel tests', () => {
|
|||||||
expect(window.alert).toHaveBeenCalledTimes(1);
|
expect(window.alert).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return true and ignore passwords on add user dialog passwords hidden', () => {
|
||||||
|
// given
|
||||||
|
dm.model.login = 'test';
|
||||||
|
dm.model.passVisibility = false;
|
||||||
|
dm.model.password = 'password';
|
||||||
|
dm.model.password2 = 'password2';
|
||||||
|
// when
|
||||||
|
const result = dm.validate();
|
||||||
|
// then
|
||||||
|
expect(result).toBe(true);
|
||||||
|
expect(window.alert).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('should test password regex on dialog validate', () => {
|
it('should test password regex on dialog validate', () => {
|
||||||
// given
|
// given
|
||||||
const password = 'password';
|
const password = 'password';
|
||||||
dm.model.login = 'test';
|
dm.model.login = 'test';
|
||||||
|
dm.model.passVisibility = true;
|
||||||
dm.model.password = password;
|
dm.model.password = password;
|
||||||
dm.model.password2 = password;
|
dm.model.password2 = password;
|
||||||
// when
|
// when
|
||||||
|
@ -82,6 +82,7 @@ $lang["units"] = "Units";
|
|||||||
$lang["metric"] = "Metric";
|
$lang["metric"] = "Metric";
|
||||||
$lang["imperial"] = "Imperial/US";
|
$lang["imperial"] = "Imperial/US";
|
||||||
$lang["nautical"] = "Nautical";
|
$lang["nautical"] = "Nautical";
|
||||||
|
$lang["admin"] = "Administrator";
|
||||||
$lang["adminmenu"] = "Administration";
|
$lang["adminmenu"] = "Administration";
|
||||||
$lang["passwordrepeat"] = "Repeat password";
|
$lang["passwordrepeat"] = "Repeat password";
|
||||||
$lang["passwordenter"] = "Enter password";
|
$lang["passwordenter"] = "Enter password";
|
||||||
|
@ -35,7 +35,9 @@ if ($usersArr === false) {
|
|||||||
$result = [ "error" => true ];
|
$result = [ "error" => true ];
|
||||||
} else if (!empty($usersArr)) {
|
} else if (!empty($usersArr)) {
|
||||||
foreach ($usersArr as $user) {
|
foreach ($usersArr as $user) {
|
||||||
$result[] = [ "id" => $user->id, "login" => $user->login ];
|
// only load admin status on admin user request
|
||||||
|
$isAdmin = $auth->isAdmin() ? $user->isAdmin : null;
|
||||||
|
$result[] = [ "id" => $user->id, "login" => $user->login, "isAdmin" => $isAdmin ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header("Content-type: application/json");
|
header("Content-type: application/json");
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
$action = uUtils::postString('action');
|
$action = uUtils::postString('action');
|
||||||
$login = uUtils::postString('login');
|
$login = uUtils::postString('login');
|
||||||
$pass = uUtils::postPass('pass');
|
$pass = uUtils::postPass('pass');
|
||||||
|
$admin = uUtils::postBool('admin', false);
|
||||||
|
|
||||||
$lang = (new uLang(uConfig::$lang))->getStrings();
|
$lang = (new uLang(uConfig::$lang))->getStrings();
|
||||||
|
|
||||||
@ -34,6 +35,10 @@
|
|||||||
uUtils::exitWithError($lang["servererror"]);
|
uUtils::exitWithError($lang["servererror"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($admin && !$auth->isAdmin()) {
|
||||||
|
uUtils::exitWithError($lang["notauthorized"]);
|
||||||
|
}
|
||||||
|
|
||||||
$aUser = new uUser($login);
|
$aUser = new uUser($login);
|
||||||
$data = NULL;
|
$data = NULL;
|
||||||
|
|
||||||
@ -42,7 +47,7 @@
|
|||||||
if ($aUser->isValid) {
|
if ($aUser->isValid) {
|
||||||
uUtils::exitWithError($lang["userexists"]);
|
uUtils::exitWithError($lang["userexists"]);
|
||||||
}
|
}
|
||||||
if (empty($pass) || ($userId = uUser::add($login, $pass)) === false) {
|
if (empty($pass) || ($userId = uUser::add($login, $pass, $admin)) === false) {
|
||||||
uUtils::exitWithError($lang["servererror"]);
|
uUtils::exitWithError($lang["servererror"]);
|
||||||
} else {
|
} else {
|
||||||
$data = [ 'id' => $userId ];
|
$data = [ 'id' => $userId ];
|
||||||
@ -50,8 +55,10 @@
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'update':
|
case 'update':
|
||||||
// update password
|
if ($aUser->setAdmin($admin) === false) {
|
||||||
if (empty($pass) || $aUser->setPass($pass) === false) {
|
uUtils::exitWithError($lang["servererror"]);
|
||||||
|
}
|
||||||
|
if (!empty($pass) && $aUser->setPass($pass) === false) {
|
||||||
uUtils::exitWithError($lang["servererror"]);
|
uUtils::exitWithError($lang["servererror"]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user