mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-06-01 04:06:12 -04:00
Push missing language strings file changes and HomeTest
Signed-off-by: objec <objecttothis@gmail.com>
This commit is contained in:
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'மெயில்சிம்ப் நிலை',
|
||||
'description' => 'வாடிக்கையாளர்கள் உருவாக்கப்படும்போது அல்லது புதுப்பிக்கப்படும்போது அவர்களை மின்னஞ்சல் பட்டியல்களுடன் ஒத்திசைக்க மெயில்சிம்புடன் ஒருங்கிணைக்கவும்.',
|
||||
'email_client' => 'மின்னஞ்சல் வாடிக்கையாளர்',
|
||||
|
||||
'info' => 'மெயில்சிம்ப்',
|
||||
'key_successfully' => 'API சாவி சரியானது.',
|
||||
'key_unsuccessfully' => 'API சாவி தவறானது.',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'สถานะของระบบส่งเมล์เมล์ชิม',
|
||||
'description' => 'เชื่อมต่อกับ Mailchimp เพื่อซิงโครไนซ์ลูกค้าเข้ากับรายการเมล์เมื่อมีการสร้างหรืออัปเดต',
|
||||
'email_client' => 'โปรแกรมรับส่งเมล',
|
||||
|
||||
'info' => 'ระบบส่งอีเมล์ชิม',
|
||||
'key_successfully' => 'คีย์ API ถูกต้อง',
|
||||
'key_unsuccessfully' => 'คีย์ API ไม่ถูกต้อง',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'Mailchimp status',
|
||||
'description' => 'I-ugnay ang Mailchimp upang i-sync ang mga customer sa mga mailing list kapag sila ay ginawa o na-update.',
|
||||
'email_client' => 'Email client',
|
||||
|
||||
'info' => 'Mailchimp',
|
||||
'key_successfully' => 'Ang API key ay valid.',
|
||||
'key_unsuccessfully' => 'Ang API key ay invalid.',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'MailChimp durumu',
|
||||
'description' => 'Mailchimp ile entegre olarak, müşteriler oluşturulduğunda veya güncellendiğinde onları posta listeleriyle senkronize edin.',
|
||||
'email_client' => 'E-posta istemcisi',
|
||||
|
||||
'info' => 'MailChimp',
|
||||
'key_successfully' => 'API anahtarı geçerli.',
|
||||
'key_unsuccessfully' => 'API anahtarı geçersiz.',
|
||||
|
||||
@@ -13,7 +13,6 @@ return [
|
||||
'description' => 'Інтегруйте Mailchimp для синхронізації клієнтів зі списками розсилки при їх створенні або оновленні.',
|
||||
'email_client' => 'Поштовий клієнт',
|
||||
|
||||
|
||||
'info' => 'MailChimp',
|
||||
'key_successfully' => 'API-ключ дійсний.',
|
||||
'key_unsuccessfully' => 'API-ключ недійсний.',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'میل چیمپ گاہک کی صورتحال',
|
||||
'description' => 'جب گاہک بنائے جائیں یا اپ ڈیٹ کیے جائیں تو انہیں میلنگ لسٹوں کے ساتھ ہم آہنگ کرنے کے لیے میل چیمپ کے ساتھ انٹیگریٹ کریں۔',
|
||||
'email_client' => 'ای میل کلائنٹ',
|
||||
|
||||
'info' => 'میل چیمپ',
|
||||
'key_successfully' => 'API کلید درست ہے۔',
|
||||
'key_unsuccessfully' => 'API کلید غلط ہے۔',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'Trạng thái tài khoản Mailchimp',
|
||||
'description' => 'Tích hợp với Mailchimp để đồng bộ hóa khách hàng với danh sách gửi thư khi họ được tạo hoặc cập nhật.',
|
||||
'email_client' => 'Trình khách nhận thư',
|
||||
|
||||
'info' => 'Mailchimp',
|
||||
'key_successfully' => 'Khóa API hợp lệ.',
|
||||
'key_unsuccessfully' => 'Khóa API không hợp lệ.',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'Mailchimp 客户状态',
|
||||
'description' => '与 Mailchimp 集成,在创建或更新客户时将客户同步到邮件列表。',
|
||||
'email_client' => '邮件客户端',
|
||||
|
||||
'info' => 'Mailchimp',
|
||||
'key_successfully' => 'API 密钥有效。',
|
||||
'key_unsuccessfully' => 'API 密钥无效。',
|
||||
|
||||
@@ -12,7 +12,6 @@ return [
|
||||
'customer_status' => 'MailChimp 電子報行銷狀態',
|
||||
'description' => '與 Mailchimp 集成,在創建或更新客戶時將客戶同步到郵件列表。',
|
||||
'email_client' => '電郵客戶端',
|
||||
|
||||
'info' => '邮件猩猩',
|
||||
'key_successfully' => 'API 密鑰有效。',
|
||||
'key_unsuccessfully' => 'API 密鑰無效。',
|
||||
|
||||
@@ -10,7 +10,7 @@ use App\Models\Employee;
|
||||
|
||||
/**
|
||||
* Test suite for Home controller password validation
|
||||
*
|
||||
*
|
||||
* Tests the critical fix for password minimum length validation bypass
|
||||
* Issue: Code was checking hashed password length (always 60 chars) instead of actual password
|
||||
* Fix: Validate raw password length BEFORE hashing
|
||||
@@ -35,13 +35,13 @@ class HomeTest extends CIUnitTestCase
|
||||
|
||||
/**
|
||||
* Test password validation rejects passwords shorter than 8 characters
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPasswordMinLength_Rejects7Characters(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
|
||||
// Attempt to change password to 7 characters
|
||||
$response = $this->post('/home/save', [
|
||||
'employee_id' => 1,
|
||||
@@ -49,29 +49,29 @@ class HomeTest extends CIUnitTestCase
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => '1234567' // 7 characters
|
||||
]);
|
||||
|
||||
|
||||
// Assert failure response
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success'], 'Password with 7 chars should be rejected');
|
||||
$this->assertEquals(-1, $result['id']);
|
||||
|
||||
|
||||
// Verify password was not changed
|
||||
$employee = model(Employee::class);
|
||||
$admin = $employee->get_info(1);
|
||||
$this->assertTrue(password_verify('pointofsale', $admin->password),
|
||||
$admin = $employee->getInfo(1);
|
||||
$this->assertTrue(password_verify('pointofsale', $admin->password),
|
||||
'Password should not have been changed');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test password validation accepts passwords with exactly 8 characters
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPasswordMinLength_Accepts8Characters(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
|
||||
// Change password to exactly 8 characters
|
||||
$response = $this->post('/home/save', [
|
||||
'employee_id' => 1,
|
||||
@@ -79,19 +79,19 @@ class HomeTest extends CIUnitTestCase
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => 'pa$$w0rd' // Exactly 8 characters including special chars
|
||||
]);
|
||||
|
||||
|
||||
// Assert success response
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success'], 'Password with 8 chars should be accepted');
|
||||
$this->assertEquals(1, $result['id']);
|
||||
|
||||
|
||||
// Verify password was changed
|
||||
$employee = model(Employee::class);
|
||||
$admin = $employee->get_info(1);
|
||||
$this->assertTrue(password_verify('pa$$w0rd', $admin->password),
|
||||
$admin = $employee->getInfo(1);
|
||||
$this->assertTrue(password_verify('pa$$w0rd', $admin->password),
|
||||
'Password with 8 chars should be accepted');
|
||||
|
||||
|
||||
// Restore original password
|
||||
$employee->change_password([
|
||||
'username' => 'admin',
|
||||
@@ -99,16 +99,16 @@ class HomeTest extends CIUnitTestCase
|
||||
'hash_version' => 2
|
||||
], 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test password validation rejects empty password
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPasswordMinLength_RejectsEmptyString(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
|
||||
// Attempt to set empty password
|
||||
$response = $this->post('/home/save', [
|
||||
'employee_id' => 1,
|
||||
@@ -116,22 +116,22 @@ class HomeTest extends CIUnitTestCase
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => '' // Empty string
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success'], 'Empty password should be rejected');
|
||||
$this->assertEquals(-1, $result['id']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test password validation rejects whitespace-only passwords
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPasswordMinLength_RejectsWhitespaceOnly(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
|
||||
// Attempt to set password as only whitespace
|
||||
$response = $this->post('/home/save', [
|
||||
'employee_id' => 1,
|
||||
@@ -139,42 +139,42 @@ class HomeTest extends CIUnitTestCase
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => ' ' // 8 spaces but empty actual password
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success'], 'Whitespace only password should be rejected');
|
||||
$this->assertEquals(-1, $result['id']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test password validation accepts passwords with special characters
|
||||
* as long as they meet minimum length
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPasswordMinLength_AcceptsSpecialCharacters(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
|
||||
$specialPassword = 'Str0ng!@#$'; // 11 characters with special chars
|
||||
|
||||
|
||||
$response = $this->post('/home/save', [
|
||||
'employee_id' => 1,
|
||||
'username' => 'admin',
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => $specialPassword
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success'], 'Password with special chars should be accepted');
|
||||
$this->assertEquals(1, $result['id']);
|
||||
|
||||
|
||||
// Verify password works
|
||||
$employee = model(Employee::class);
|
||||
$admin = $employee->get_info(1);
|
||||
$admin = $employee->getInfo(1);
|
||||
$this->assertTrue(password_verify($specialPassword, $admin->password));
|
||||
|
||||
|
||||
// Restore original password
|
||||
$employee->change_password([
|
||||
'username' => 'admin',
|
||||
@@ -182,20 +182,20 @@ class HomeTest extends CIUnitTestCase
|
||||
'hash_version' => 2
|
||||
], 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Regression test: Verify previous vulnerable behavior is fixed
|
||||
*
|
||||
*
|
||||
* Before fix: 1-character passwords like "a" were accepted because
|
||||
* code checked len(hashed_password) which is always 60 for bcrypt
|
||||
* After fix: Raw password is validated before hashing
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPasswordMinLength_RejectsPreviousBehavior(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
|
||||
// Attempt the previously vulnerable case: single character password
|
||||
$response = $this->post('/home/save', [
|
||||
'employee_id' => 1,
|
||||
@@ -203,23 +203,23 @@ class HomeTest extends CIUnitTestCase
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => 'a' // Previously allowed due to bug
|
||||
]);
|
||||
|
||||
|
||||
// This should now fail
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success'], 'Single character password should be rejected (CVE fix)');
|
||||
$this->assertEquals(-1, $result['id']);
|
||||
|
||||
|
||||
// Verify password was NOT changed
|
||||
$employee = model(Employee::class);
|
||||
$admin = $employee->get_info(1);
|
||||
$this->assertTrue(password_verify('pointofsale', $admin->password),
|
||||
$admin = $employee->getInfo(1);
|
||||
$this->assertTrue(password_verify('pointofsale', $admin->password),
|
||||
'Single character password should be rejected (CVE fix)');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to reset session
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function resetSession(): void
|
||||
@@ -228,10 +228,10 @@ class HomeTest extends CIUnitTestCase
|
||||
$session->destroy();
|
||||
$session->set('person_id', 1); // Admin user
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a non-admin employee for testing
|
||||
*
|
||||
*
|
||||
* @param array $overrides Optional overrides for username, email, password, etc.
|
||||
* @return int The person_id of the created employee
|
||||
*/
|
||||
@@ -243,7 +243,7 @@ class HomeTest extends CIUnitTestCase
|
||||
'email' => $overrides['email'] ?? 'nonadmin@test.com',
|
||||
'phone_number' => $overrides['phone_number'] ?? '555-1234'
|
||||
];
|
||||
|
||||
|
||||
$employeeData = [
|
||||
'username' => $overrides['username'] ?? 'nonadmin',
|
||||
'password' => password_hash($overrides['password'] ?? 'password123', PASSWORD_DEFAULT),
|
||||
@@ -251,21 +251,21 @@ class HomeTest extends CIUnitTestCase
|
||||
'language_code' => 'en',
|
||||
'language' => 'english'
|
||||
];
|
||||
|
||||
|
||||
$grantsData = [
|
||||
['permission_id' => 'customers', 'menu_group' => 'home'],
|
||||
['permission_id' => 'sales', 'menu_group' => 'home']
|
||||
];
|
||||
|
||||
|
||||
$employeeModel = model(Employee::class);
|
||||
$employeeModel->save_employee($personData, $employeeData, $grantsData, NEW_ENTRY);
|
||||
|
||||
|
||||
return $employeeModel->get_found_rows('');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Login as a specific user
|
||||
*
|
||||
*
|
||||
* @param int $personId
|
||||
* @return void
|
||||
*/
|
||||
@@ -276,150 +276,150 @@ class HomeTest extends CIUnitTestCase
|
||||
$session->set('person_id', $personId);
|
||||
$session->set('menu_group', 'home');
|
||||
}
|
||||
|
||||
|
||||
// ========== BOLA Authorization Tests ==========
|
||||
|
||||
|
||||
/**
|
||||
* Test non-admin cannot view admin password change form
|
||||
* BOLA vulnerability fix: GHSA-q58g-gg7v-f9rf
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNonAdminCannotViewAdminPasswordForm(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId);
|
||||
|
||||
|
||||
$response = $this->get('/home/changePassword/1');
|
||||
|
||||
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test non-admin cannot change admin password
|
||||
* BOLA vulnerability fix: GHSA-q58g-gg7v-f9rf
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNonAdminCannotChangeAdminPassword(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId);
|
||||
|
||||
|
||||
$response = $this->post('/home/save/1', [
|
||||
'username' => 'admin',
|
||||
'current_password' => 'pointofsale',
|
||||
'password' => 'hacked123'
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(403);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success']);
|
||||
|
||||
|
||||
// Verify admin password was NOT changed
|
||||
$employee = model(Employee::class);
|
||||
$admin = $employee->get_info(1);
|
||||
$this->assertTrue(password_verify('pointofsale', $admin->password),
|
||||
$admin = $employee->getInfo(1);
|
||||
$this->assertTrue(password_verify('pointofsale', $admin->password),
|
||||
'Admin password should not have been changed by non-admin');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test user can view their own password change form
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUserCanViewOwnPasswordForm(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId);
|
||||
|
||||
|
||||
$response = $this->get('/home/changePassword/' . $nonAdminId);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('nonadmin'); // Username should be visible
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test user can change their own password
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUserCanChangeOwnPassword(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId);
|
||||
|
||||
|
||||
$response = $this->post('/home/save/' . $nonAdminId, [
|
||||
'username' => 'nonadmin',
|
||||
'current_password' => 'password123',
|
||||
'password' => 'newpassword123'
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success']);
|
||||
|
||||
|
||||
// Verify password was changed
|
||||
$employee = model(Employee::class);
|
||||
$user = $employee->get_info($nonAdminId);
|
||||
$user = $employee->getInfo($nonAdminId);
|
||||
$this->assertTrue(password_verify('newpassword123', $user->password));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test admin can view any user's password form
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAdminCanViewAnyPasswordForm(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->resetSession(); // Login as admin
|
||||
|
||||
|
||||
$response = $this->get('/home/changePassword/' . $nonAdminId);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('nonadmin');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test admin can change any user's password
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAdminCanChangeAnyPassword(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->resetSession(); // Login as admin
|
||||
|
||||
|
||||
$response = $this->post('/home/save/' . $nonAdminId, [
|
||||
'username' => 'nonadmin',
|
||||
'current_password' => 'password123',
|
||||
'password' => 'adminset123'
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success']);
|
||||
|
||||
|
||||
// Verify password was changed
|
||||
$employee = model(Employee::class);
|
||||
$user = $employee->get_info($nonAdminId);
|
||||
$user = $employee->getInfo($nonAdminId);
|
||||
$this->assertTrue(password_verify('adminset123', $user->password));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test default employee_id parameter uses current user
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDefaultEmployeeIdUsesCurrentUser(): void
|
||||
{
|
||||
$nonAdminId = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId);
|
||||
|
||||
|
||||
// Calling without employee_id should use current user
|
||||
$response = $this->get('/home/changePassword');
|
||||
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('nonadmin');
|
||||
}
|
||||
@@ -427,56 +427,56 @@ class HomeTest extends CIUnitTestCase
|
||||
/**
|
||||
* Test non-admin cannot view another non-admin's password form
|
||||
* IDOR vulnerability fix: GHSA-mcc2-8rp2-q6ch
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNonAdminCannotViewOtherNonAdminPasswordForm(): void
|
||||
{
|
||||
$nonAdminId1 = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId1);
|
||||
|
||||
|
||||
$otherUserId = $this->createNonAdminEmployee([
|
||||
'username' => 'otheruser',
|
||||
'email' => 'other@test.com',
|
||||
'password' => 'password456'
|
||||
]);
|
||||
|
||||
|
||||
$response = $this->get('/home/changePassword/' . $otherUserId);
|
||||
|
||||
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test non-admin cannot change another non-admin's password
|
||||
* IDOR vulnerability fix: GHSA-mcc2-8rp2-q6ch
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNonAdminCannotChangeOtherNonAdminPassword(): void
|
||||
{
|
||||
$nonAdminId1 = $this->createNonAdminEmployee();
|
||||
$this->loginAs($nonAdminId1);
|
||||
|
||||
|
||||
$victimId = $this->createNonAdminEmployee([
|
||||
'username' => 'victimuser',
|
||||
'email' => 'victim@test.com',
|
||||
'password' => 'victimpass123'
|
||||
]);
|
||||
|
||||
|
||||
$response = $this->post('/home/save/' . $victimId, [
|
||||
'username' => 'victimuser',
|
||||
'current_password' => 'victimpass123',
|
||||
'password' => 'hacked123456'
|
||||
]);
|
||||
|
||||
|
||||
$response->assertStatus(403);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success']);
|
||||
|
||||
|
||||
// Verify victim's password was NOT changed
|
||||
$employeeModel = model(Employee::class);
|
||||
$victim = $employeeModel->get_info($victimId);
|
||||
$this->assertTrue(password_verify('victimpass123', $victim->password),
|
||||
$victim = $employeeModel->getInfo($victimId);
|
||||
$this->assertTrue(password_verify('victimpass123', $victim->password),
|
||||
'Non-admin should not be able to change another non-admin password');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user