182 lines
4.8 KiB
TypeScript
182 lines
4.8 KiB
TypeScript
import { Knex } from 'knex';
|
||
import * as knexLib from 'knex';
|
||
|
||
/**
|
||
* Create a Knex connection for tenant database
|
||
*/
|
||
function createKnexConnection(database: string): Knex {
|
||
return knexLib.default({
|
||
client: 'mysql2',
|
||
connection: {
|
||
host: process.env.DB_HOST || 'db',
|
||
port: parseInt(process.env.DB_PORT || '3306'),
|
||
user: 'root',
|
||
password: 'asjdnfqTash37faggT',
|
||
database: database,
|
||
},
|
||
});
|
||
}
|
||
|
||
interface RoleWithPermissions {
|
||
name: string;
|
||
description: string;
|
||
objectPermissions: {
|
||
[objectApiName: string]: {
|
||
canCreate: boolean;
|
||
canRead: boolean;
|
||
canEdit: boolean;
|
||
canDelete: boolean;
|
||
canViewAll: boolean;
|
||
canModifyAll: boolean;
|
||
};
|
||
};
|
||
}
|
||
|
||
const DEFAULT_ROLES: RoleWithPermissions[] = [
|
||
{
|
||
name: 'System Administrator',
|
||
description: 'Full access to all objects and records. Can view and modify all data.',
|
||
objectPermissions: {
|
||
'*': {
|
||
canCreate: true,
|
||
canRead: true,
|
||
canEdit: true,
|
||
canDelete: true,
|
||
canViewAll: true,
|
||
canModifyAll: true,
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: 'Standard User',
|
||
description: 'Can create, read, edit, and delete own records. Respects OWD settings.',
|
||
objectPermissions: {
|
||
'*': {
|
||
canCreate: true,
|
||
canRead: true,
|
||
canEdit: true,
|
||
canDelete: true,
|
||
canViewAll: false,
|
||
canModifyAll: false,
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: 'Read Only',
|
||
description: 'Can only read records based on OWD settings. No create, edit, or delete.',
|
||
objectPermissions: {
|
||
'*': {
|
||
canCreate: false,
|
||
canRead: true,
|
||
canEdit: false,
|
||
canDelete: false,
|
||
canViewAll: false,
|
||
canModifyAll: false,
|
||
},
|
||
},
|
||
},
|
||
];
|
||
|
||
async function seedRolesForTenant(knex: Knex, tenantName: string) {
|
||
console.log(`\n🌱 Seeding roles for tenant: ${tenantName}`);
|
||
|
||
// Get all object definitions
|
||
const objectDefinitions = await knex('object_definitions').select('id', 'apiName');
|
||
|
||
for (const roleData of DEFAULT_ROLES) {
|
||
// Check if role already exists
|
||
const existingRole = await knex('roles')
|
||
.where({ name: roleData.name })
|
||
.first();
|
||
|
||
let roleId: string;
|
||
|
||
if (existingRole) {
|
||
console.log(` ℹ️ Role "${roleData.name}" already exists, skipping...`);
|
||
roleId = existingRole.id;
|
||
} else {
|
||
// Create role
|
||
await knex('roles').insert({
|
||
name: roleData.name,
|
||
guardName: 'api',
|
||
description: roleData.description,
|
||
});
|
||
|
||
// Get the inserted role
|
||
const newRole = await knex('roles')
|
||
.where({ name: roleData.name })
|
||
.first();
|
||
|
||
roleId = newRole.id;
|
||
console.log(` ✅ Created role: ${roleData.name}`);
|
||
}
|
||
|
||
// Create object permissions for all objects
|
||
const wildcardPermissions = roleData.objectPermissions['*'];
|
||
|
||
for (const objectDef of objectDefinitions) {
|
||
// Check if permission already exists
|
||
const existingPermission = await knex('role_object_permissions')
|
||
.where({
|
||
roleId: roleId,
|
||
objectDefinitionId: objectDef.id,
|
||
})
|
||
.first();
|
||
|
||
if (!existingPermission) {
|
||
await knex('role_object_permissions').insert({
|
||
roleId: roleId,
|
||
objectDefinitionId: objectDef.id,
|
||
canCreate: wildcardPermissions.canCreate,
|
||
canRead: wildcardPermissions.canRead,
|
||
canEdit: wildcardPermissions.canEdit,
|
||
canDelete: wildcardPermissions.canDelete,
|
||
canViewAll: wildcardPermissions.canViewAll,
|
||
canModifyAll: wildcardPermissions.canModifyAll,
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log(` 📋 Set permissions for ${objectDefinitions.length} objects`);
|
||
}
|
||
}
|
||
|
||
async function seedAllTenants() {
|
||
console.log('🚀 Starting role seeding for all tenants...\n');
|
||
|
||
// For now, seed the main tenant database
|
||
const databases = ['tenant_tenant1'];
|
||
|
||
let successCount = 0;
|
||
let errorCount = 0;
|
||
|
||
for (const database of databases) {
|
||
try {
|
||
const knex = createKnexConnection(database);
|
||
await seedRolesForTenant(knex, database);
|
||
await knex.destroy();
|
||
successCount++;
|
||
} catch (error) {
|
||
console.error(`❌ ${database}: Seeding failed:`, error.message);
|
||
errorCount++;
|
||
}
|
||
}
|
||
|
||
console.log('\n============================================================');
|
||
console.log('📊 Seeding Summary');
|
||
console.log('============================================================');
|
||
console.log(`✅ Successful: ${successCount}`);
|
||
console.log(`❌ Failed: ${errorCount}`);
|
||
|
||
if (errorCount === 0) {
|
||
console.log('\n🎉 All tenant roles seeded successfully!');
|
||
}
|
||
}
|
||
|
||
seedAllTenants()
|
||
.then(() => process.exit(0))
|
||
.catch((error) => {
|
||
console.error('Unhandled error:', error);
|
||
process.exit(1);
|
||
});
|