- Fixed permission check in canUserEditEvent() method to properly check user roles
- Changed from checking non-existent 'hvac_trainer' capability to in_array('hvac_trainer', $user->roles)
- Trainers can now create new events and edit their own events
- Security maintained: trainers cannot edit others' events
- Added initial CSS file to fix narrow width and navigation z-index issues
- Page now displays at proper 1200px max width matching other trainer pages
- Navigation menu no longer hidden under site header (z-index: 100)
🤖 Generated with Claude Code (https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
170 lines
No EOL
6.9 KiB
JavaScript
170 lines
No EOL
6.9 KiB
JavaScript
/**
|
||
* Test to verify the security fixes are working correctly
|
||
*/
|
||
|
||
const { chromium } = require('playwright');
|
||
|
||
async function testSecurityFixes() {
|
||
console.log('🔍 Security Fix Verification Test...\n');
|
||
|
||
const browser = await chromium.launch({
|
||
headless: false,
|
||
args: ['--disable-dev-shm-usage', '--no-sandbox']
|
||
});
|
||
|
||
const context = await browser.newContext({
|
||
viewport: { width: 1280, height: 720 }
|
||
});
|
||
|
||
const page = await context.newPage();
|
||
const baseUrl = 'https://upskill-staging.measurequick.com';
|
||
|
||
try {
|
||
// Step 1: Login as test_trainer
|
||
console.log('1️⃣ Logging in as test_trainer...');
|
||
await page.goto(`${baseUrl}/training-login/`);
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
await page.fill('input[name="log"]', 'test_trainer');
|
||
await page.fill('input[name="pwd"]', 'TestTrainer123!');
|
||
await page.press('input[name="pwd"]', 'Enter');
|
||
|
||
await page.waitForURL('**/trainer/dashboard/**', { timeout: 10000 });
|
||
console.log('✅ Login successful');
|
||
|
||
// Step 2: Check that debug output is removed
|
||
console.log('\n2️⃣ Checking for debug output removal...');
|
||
await page.goto(`${baseUrl}/trainer/event/edit/`);
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
const pageSource = await page.content();
|
||
const hasDebugComments = pageSource.includes('HVAC_Custom_Event_Edit::') ||
|
||
pageSource.includes('<!-- HVAC_Custom_Event_Edit');
|
||
|
||
if (hasDebugComments) {
|
||
console.log('❌ Debug comments still present in page source');
|
||
} else {
|
||
console.log('✅ Debug comments successfully removed');
|
||
}
|
||
|
||
// Step 3: Test new event creation (should work)
|
||
console.log('\n3️⃣ Testing new event creation access...');
|
||
const newEventCheck = await page.evaluate(() => {
|
||
const title = document.title;
|
||
const hasForm = document.querySelector('input[name="post_title"]') !== null;
|
||
const hasError = title.includes('Error') || document.body.innerText.includes('permission');
|
||
|
||
return { title, hasForm, hasError };
|
||
});
|
||
|
||
console.log(' Page title:', newEventCheck.title);
|
||
console.log(' Has form:', newEventCheck.hasForm);
|
||
console.log(' Has error:', newEventCheck.hasError);
|
||
|
||
if (newEventCheck.hasForm && !newEventCheck.hasError) {
|
||
console.log(' ✅ Can create new events');
|
||
} else {
|
||
console.log(' ❌ Cannot create new events');
|
||
}
|
||
|
||
// Step 4: Test editing someone else's event (should NOT work with new fix)
|
||
console.log('\n4️⃣ Testing access to event not owned by test_trainer...');
|
||
await page.goto(`${baseUrl}/trainer/event/edit/?event_id=6161`);
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
const otherEventCheck = await page.evaluate(() => {
|
||
const title = document.title;
|
||
const bodyText = document.body.innerText;
|
||
const hasPermissionError = bodyText.includes('permission') ||
|
||
bodyText.includes('Permission') ||
|
||
title.includes('Error');
|
||
const hasForm = document.querySelector('input[name="post_title"]') !== null;
|
||
|
||
return {
|
||
title,
|
||
hasPermissionError,
|
||
hasForm,
|
||
bodySnippet: bodyText.substring(0, 200)
|
||
};
|
||
});
|
||
|
||
console.log(' Page title:', otherEventCheck.title);
|
||
console.log(' Has permission error:', otherEventCheck.hasPermissionError);
|
||
console.log(' Has edit form:', otherEventCheck.hasForm);
|
||
|
||
if (otherEventCheck.hasPermissionError && !otherEventCheck.hasForm) {
|
||
console.log(' ✅ SECURITY FIX WORKING: Cannot edit other users\' events');
|
||
} else if (otherEventCheck.hasForm) {
|
||
console.log(' ❌ SECURITY ISSUE: Can still edit other users\' events!');
|
||
console.log(' This indicates the authorization fix may not be fully working');
|
||
}
|
||
|
||
// Step 5: Check that page ID is no longer hardcoded
|
||
console.log('\n5️⃣ Checking for hardcoded page ID...');
|
||
const pageContent = await page.evaluate(() => document.body.innerHTML);
|
||
const hasHardcodedId = pageContent.includes('6177');
|
||
|
||
if (hasHardcodedId) {
|
||
console.log(' ⚠️ Page ID 6177 may still be referenced (check if it\'s just in content)');
|
||
} else {
|
||
console.log(' ✅ No hardcoded page ID found in output');
|
||
}
|
||
|
||
// Summary
|
||
console.log('\n📋 SECURITY FIX VERIFICATION SUMMARY:');
|
||
console.log('================================');
|
||
|
||
const allChecks = {
|
||
debugRemoved: !hasDebugComments,
|
||
newEventAccess: newEventCheck.hasForm && !newEventCheck.hasError,
|
||
otherEventBlocked: otherEventCheck.hasPermissionError && !otherEventCheck.hasForm,
|
||
noHardcodedId: !hasHardcodedId
|
||
};
|
||
|
||
const passedChecks = Object.values(allChecks).filter(v => v).length;
|
||
const totalChecks = Object.values(allChecks).length;
|
||
|
||
console.log(`✅ Debug output removed: ${allChecks.debugRemoved ? 'YES' : 'NO'}`);
|
||
console.log(`✅ Can create new events: ${allChecks.newEventAccess ? 'YES' : 'NO'}`);
|
||
console.log(`✅ Cannot edit others' events: ${allChecks.otherEventBlocked ? 'YES' : 'NO'}`);
|
||
console.log(`✅ No hardcoded page ID: ${allChecks.noHardcodedId ? 'YES' : 'NO'}`);
|
||
|
||
console.log(`\nResult: ${passedChecks}/${totalChecks} security checks passed`);
|
||
|
||
if (passedChecks === totalChecks) {
|
||
console.log('🎉 ALL SECURITY FIXES VERIFIED SUCCESSFULLY!');
|
||
} else {
|
||
console.log('⚠️ Some security issues may still need attention');
|
||
}
|
||
|
||
// Take screenshot
|
||
await page.screenshot({
|
||
path: `security-verification-${Date.now()}.png`,
|
||
fullPage: true
|
||
});
|
||
console.log('\n📸 Screenshot saved');
|
||
|
||
} catch (error) {
|
||
console.error('\n❌ Test failed:', error.message);
|
||
|
||
await page.screenshot({
|
||
path: `error-security-test-${Date.now()}.png`,
|
||
fullPage: true
|
||
});
|
||
} finally {
|
||
console.log('\n⏸️ Keeping browser open for inspection...');
|
||
await page.waitForTimeout(10000);
|
||
await browser.close();
|
||
}
|
||
}
|
||
|
||
// Run test
|
||
testSecurityFixes()
|
||
.then(() => {
|
||
console.log('\n✨ Test completed!');
|
||
process.exit(0);
|
||
})
|
||
.catch(error => {
|
||
console.error('\n💥 Test failed:', error);
|
||
process.exit(1);
|
||
}); |