/** * Migration: Add session and role mapping configuration to tenants * Adds session_timeout, require_mfa, allow_concurrent_sessions, and role_mappings fields */ 'use strict'; module.exports = { up: async (queryInterface, Sequelize) => { // Check if the columns already exist const tableDescription = await queryInterface.describeTable('tenants'); // Add session configuration fields if (!tableDescription.session_timeout) { await queryInterface.addColumn('tenants', 'session_timeout', { type: Sequelize.INTEGER, defaultValue: 480, // 8 hours in minutes allowNull: false, comment: 'Session timeout in minutes' }); console.log('✅ Added session_timeout column to tenants table'); } else { console.log('⚠️ Column session_timeout already exists, skipping...'); } if (!tableDescription.require_mfa) { await queryInterface.addColumn('tenants', 'require_mfa', { type: Sequelize.BOOLEAN, defaultValue: false, allowNull: false, comment: 'Whether multi-factor authentication is required' }); console.log('✅ Added require_mfa column to tenants table'); } else { console.log('⚠️ Column require_mfa already exists, skipping...'); } if (!tableDescription.allow_concurrent_sessions) { await queryInterface.addColumn('tenants', 'allow_concurrent_sessions', { type: Sequelize.BOOLEAN, defaultValue: true, allowNull: false, comment: 'Whether users can have multiple concurrent sessions' }); console.log('✅ Added allow_concurrent_sessions column to tenants table'); } else { console.log('⚠️ Column allow_concurrent_sessions already exists, skipping...'); } if (!tableDescription.role_mappings) { await queryInterface.addColumn('tenants', 'role_mappings', { type: Sequelize.JSONB, allowNull: true, comment: 'Mapping of external groups/attributes to system roles' }); console.log('✅ Added role_mappings column to tenants table'); } else { console.log('⚠️ Column role_mappings already exists, skipping...'); } // Update auth_provider enum to include 'ad' - only if it doesn't exist try { await queryInterface.sequelize.query(` DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_enum WHERE enumlabel = 'ad' AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = 'enum_tenants_auth_provider' ) ) THEN ALTER TYPE "enum_tenants_auth_provider" ADD VALUE 'ad'; END IF; END$$; `); console.log('✅ Added ad to auth_provider enum'); } catch (error) { console.log('⚠️ Auth provider enum already includes ad or error occurred:', error.message); } }, down: async (queryInterface, Sequelize) => { // Remove the added columns await queryInterface.removeColumn('tenants', 'session_timeout'); await queryInterface.removeColumn('tenants', 'require_mfa'); await queryInterface.removeColumn('tenants', 'allow_concurrent_sessions'); await queryInterface.removeColumn('tenants', 'role_mappings'); // Note: Removing enum values is complex in PostgreSQL and typically not done in production // The 'ad' value will remain in the enum even after this rollback } };