Files
ActiveDirectoryManager/updateSchema.ts
T
2025-04-08 02:23:25 +00:00

190 lines
5.7 KiB
TypeScript

import pg from 'pg';
import * as schema from './shared/schema';
const { Pool } = pg;
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
async function main() {
console.log('Updating database schema...');
const client = await pool.connect();
try {
await client.query('BEGIN');
// Create roles table if it doesn't exist
await client.query(`
CREATE TABLE IF NOT EXISTS "roles" (
"id" serial PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"description" text,
"is_default" boolean DEFAULT false,
"created_at" timestamp DEFAULT now(),
CONSTRAINT "roles_name_unique" UNIQUE("name")
);
`);
// Create role_permissions table if it doesn't exist
await client.query(`
CREATE TABLE IF NOT EXISTS "role_permissions" (
"role_id" integer NOT NULL,
"permission" text NOT NULL,
CONSTRAINT "role_permissions_role_id_permission_pk" PRIMARY KEY("role_id","permission")
);
`);
// Add foreign key constraint to role_permissions table
await client.query(`
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'role_permissions_role_id_roles_id_fk'
) THEN
ALTER TABLE "role_permissions"
ADD CONSTRAINT "role_permissions_role_id_roles_id_fk"
FOREIGN KEY ("role_id") REFERENCES "roles"("id") ON DELETE cascade;
END IF;
END $$;
`);
// Update users table to add role_id column if it doesn't exist
await client.query(`
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'users' AND column_name = 'role_id'
) THEN
ALTER TABLE "users" ADD COLUMN "role_id" integer;
ALTER TABLE "users"
ADD CONSTRAINT "users_role_id_roles_id_fk"
FOREIGN KEY ("role_id") REFERENCES "roles"("id");
END IF;
END $$;
`);
// Update api_tokens table
await client.query(`
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'api_tokens' AND column_name = 'role_id'
) THEN
ALTER TABLE "api_tokens" ADD COLUMN "role_id" integer;
ALTER TABLE "api_tokens"
ADD CONSTRAINT "api_tokens_role_id_roles_id_fk"
FOREIGN KEY ("role_id") REFERENCES "roles"("id");
END IF;
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'api_tokens' AND column_name = 'permissions'
) THEN
ALTER TABLE "api_tokens" RENAME COLUMN "permissions" TO "custom_permissions";
END IF;
END $$;
`);
await client.query('COMMIT');
console.log('Schema update completed');
// Insert default roles if they don't exist
await client.query('BEGIN');
const { rows: adminExists } = await client.query(`
SELECT id FROM roles WHERE name = 'admin' LIMIT 1
`);
if (adminExists.length === 0) {
console.log('Creating admin role...');
const { rows: adminRole } = await client.query(`
INSERT INTO roles (name, description, is_default)
VALUES ('admin', 'Administrator with full system access', false)
RETURNING id
`);
// Add all permissions to admin role
for (const permission of Object.values(schema.PERMISSIONS)) {
await client.query(`
INSERT INTO role_permissions (role_id, permission)
VALUES ($1, $2)
`, [adminRole[0].id, permission]);
}
}
const { rows: userExists } = await client.query(`
SELECT id FROM roles WHERE name = 'user' LIMIT 1
`);
if (userExists.length === 0) {
console.log('Creating user role...');
const { rows: userRole } = await client.query(`
INSERT INTO roles (name, description, is_default)
VALUES ('user', 'Regular user with limited access', true)
RETURNING id
`);
// Add basic permissions to user role
const basicPermissions = [
schema.PERMISSIONS.VIEW_USERS,
schema.PERMISSIONS.VIEW_LDAP_CONNECTIONS,
schema.PERMISSIONS.VIEW_AD_USERS,
schema.PERMISSIONS.VIEW_AD_GROUPS,
schema.PERMISSIONS.VIEW_AD_OUS,
schema.PERMISSIONS.VIEW_AD_COMPUTERS,
schema.PERMISSIONS.VIEW_AD_DOMAINS
];
for (const permission of basicPermissions) {
await client.query(`
INSERT INTO role_permissions (role_id, permission)
VALUES ($1, $2)
`, [userRole[0].id, permission]);
}
}
const { rows: apiExists } = await client.query(`
SELECT id FROM roles WHERE name = 'api' LIMIT 1
`);
if (apiExists.length === 0) {
console.log('Creating api role...');
await client.query(`
INSERT INTO roles (name, description, is_default)
VALUES ('api', 'API access with customizable permissions', false)
`);
}
// Update existing users to have the admin role if they have no role assigned
await client.query(`
DO $$
DECLARE
admin_role_id integer;
BEGIN
SELECT id INTO admin_role_id FROM roles WHERE name = 'admin' LIMIT 1;
IF admin_role_id IS NOT NULL THEN
UPDATE users SET role_id = admin_role_id WHERE role_id IS NULL;
END IF;
END $$;
`);
await client.query('COMMIT');
console.log('Data migration completed successfully');
} catch (error) {
await client.query('ROLLBACK');
console.error('Migration failed:', error);
} finally {
client.release();
await pool.end();
}
}
main();