![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/lavocat.ca/private_html/scripts/ |
#!/usr/bin/env ts-node
import * as fs from 'fs';
import * as path from 'path';
import * as glob from 'glob';
interface ApiFix {
file: string;
oldImport: string;
newImport: string;
oldCheck: string;
newCheck: string;
}
class AdminApiFixer {
private fixes: ApiFix[] = [];
async fixAllAdminApis() {
console.log('š§ Fixing Admin API Permission Checks...\n');
const apiFiles = glob.sync('src/pages/api/admin/**/*.ts', { ignore: ['**/node_modules/**'] });
for (const file of apiFiles) {
await this.fixApiFile(file);
}
this.generateReport();
}
private async fixApiFile(filePath: string) {
const content = fs.readFileSync(filePath, 'utf-8');
let modified = false;
let newContent = content;
// Fix 1: Replace canAccessAdmin with isEffectiveAdmin
if (content.includes('canAccessAdmin')) {
newContent = newContent.replace(
/import\s*{\s*([^}]*)\s*}\s*from\s*['"]@\/lib\/auth-utils['"]/g,
(match, imports) => {
const importList = imports.split(',').map((imp: string) => imp.trim());
if (importList.includes('canAccessAdmin')) {
importList[importList.indexOf('canAccessAdmin')] = 'isEffectiveAdmin';
}
return `import { ${importList.join(', ')} } from '@/lib/auth-utils'`;
}
);
newContent = newContent.replace(
/if\s*\(\s*!session\s*\|\|\s*!canAccessAdmin\s*\(\s*session\s*\)\s*\)/g,
'if (!session || !isEffectiveAdmin(session))'
);
this.fixes.push({
file: filePath,
oldImport: 'canAccessAdmin',
newImport: 'isEffectiveAdmin',
oldCheck: 'canAccessAdmin(session)',
newCheck: 'isEffectiveAdmin(session)'
});
modified = true;
}
// Fix 2: Replace isSuperAdmin with isEffectiveSuperAdmin for SuperAdmin-only endpoints
if (content.includes('isSuperAdmin') && !content.includes('ADMIN')) {
newContent = newContent.replace(
/import\s*{\s*([^}]*)\s*}\s*from\s*['"]@\/lib\/auth-utils['"]/g,
(match, imports) => {
const importList = imports.split(',').map((imp: string) => imp.trim());
if (importList.includes('isSuperAdmin')) {
importList[importList.indexOf('isSuperAdmin')] = 'isEffectiveSuperAdmin';
}
return `import { ${importList.join(', ')} } from '@/lib/auth-utils'`;
}
);
newContent = newContent.replace(
/if\s*\(\s*!session\s*\|\|\s*!isSuperAdmin\s*\(\s*session\s*\)\s*\)/g,
'if (!session || !isEffectiveSuperAdmin(session))'
);
newContent = newContent.replace(
/if\s*\(\s*!isSuperAdmin\s*\(\s*session\s*\)\s*\)/g,
'if (!isEffectiveSuperAdmin(session))'
);
this.fixes.push({
file: filePath,
oldImport: 'isSuperAdmin',
newImport: 'isEffectiveSuperAdmin',
oldCheck: 'isSuperAdmin(session)',
newCheck: 'isEffectiveSuperAdmin(session)'
});
modified = true;
}
// Fix 3: Replace isSuperAdmin with isEffectiveAdmin for Admin+SuperAdmin endpoints
if (content.includes('isSuperAdmin') && content.includes('ADMIN')) {
newContent = newContent.replace(
/import\s*{\s*([^}]*)\s*}\s*from\s*['"]@\/lib\/auth-utils['"]/g,
(match, imports) => {
const importList = imports.split(',').map((imp: string) => imp.trim());
if (importList.includes('isSuperAdmin')) {
importList[importList.indexOf('isSuperAdmin')] = 'isEffectiveAdmin';
}
return `import { ${importList.join(', ')} } from '@/lib/auth-utils'`;
}
);
newContent = newContent.replace(
/if\s*\(\s*!session\s*\|\|\s*!\(\s*isSuperAdmin\s*\(\s*session\s*\)\s*\|\|\s*session\.user\.role\s*===\s*['"]ADMIN['"]\s*\)\s*\)/g,
'if (!session || !isEffectiveAdmin(session))'
);
this.fixes.push({
file: filePath,
oldImport: 'isSuperAdmin',
newImport: 'isEffectiveAdmin',
oldCheck: 'isSuperAdmin(session) || session.user.role === \'ADMIN\'',
newCheck: 'isEffectiveAdmin(session)'
});
modified = true;
}
if (modified) {
fs.writeFileSync(filePath, newContent);
console.log(`ā
Fixed: ${filePath}`);
}
}
private generateReport() {
console.log('\nš ADMIN API FIX REPORT\n');
console.log('=' .repeat(50));
if (this.fixes.length === 0) {
console.log('ā
All admin APIs already use effective permission functions!');
return;
}
console.log(`š§ Fixed ${this.fixes.length} admin API endpoints:\n`);
this.fixes.forEach((fix, index) => {
console.log(`${index + 1}. ${fix.file}`);
console.log(` Import: ${fix.oldImport} ā ${fix.newImport}`);
console.log(` Check: ${fix.oldCheck} ā ${fix.newCheck}`);
console.log('');
});
console.log('šÆ SUMMARY:');
console.log('- All admin APIs now use effective permission functions');
console.log('- Impersonation will work correctly for all admin features');
console.log('- SuperAdmin and Admin roles can access admin features while impersonating');
// Save detailed report
const reportPath = 'admin-api-fix-report.json';
fs.writeFileSync(reportPath, JSON.stringify(this.fixes, null, 2));
console.log(`\nš Detailed report saved to: ${reportPath}`);
}
}
// Run the fixer
async function main() {
const fixer = new AdminApiFixer();
await fixer.fixAllAdminApis();
}
if (require.main === module) {
main().catch(console.error);
}
export { AdminApiFixer };