"use strict"; /** @type {import('sequelize-cli').Migration} */ module.exports = { async up(queryInterface, Sequelize) { // Add TOTP configuration fields await queryInterface.addColumn("Users", "twoFactorEnabled", { type: Sequelize.BOOLEAN, defaultValue: false, allowNull: false, }); await queryInterface.addColumn("Users", "twoFactorMethod", { type: Sequelize.ENUM("totp", "email"), allowNull: true, }); await queryInterface.addColumn("Users", "totpSecret", { type: Sequelize.STRING, allowNull: true, }); await queryInterface.addColumn("Users", "totpSecretIv", { type: Sequelize.STRING, allowNull: true, }); await queryInterface.addColumn("Users", "twoFactorEnabledAt", { type: Sequelize.DATE, allowNull: true, }); // Add Email OTP fields (backup method) await queryInterface.addColumn("Users", "emailOtpCode", { type: Sequelize.STRING, allowNull: true, }); await queryInterface.addColumn("Users", "emailOtpExpiry", { type: Sequelize.DATE, allowNull: true, }); await queryInterface.addColumn("Users", "emailOtpAttempts", { type: Sequelize.INTEGER, defaultValue: 0, allowNull: false, }); // Add Recovery Codes fields await queryInterface.addColumn("Users", "recoveryCodesHash", { type: Sequelize.TEXT, allowNull: true, }); await queryInterface.addColumn("Users", "recoveryCodesGeneratedAt", { type: Sequelize.DATE, allowNull: true, }); await queryInterface.addColumn("Users", "recoveryCodesUsedCount", { type: Sequelize.INTEGER, defaultValue: 0, allowNull: false, }); // Add Step-up session tracking await queryInterface.addColumn("Users", "twoFactorVerifiedAt", { type: Sequelize.DATE, allowNull: true, }); // Add temporary secret storage during setup await queryInterface.addColumn("Users", "twoFactorSetupPendingSecret", { type: Sequelize.STRING, allowNull: true, }); await queryInterface.addColumn("Users", "twoFactorSetupPendingSecretIv", { type: Sequelize.STRING, allowNull: true, }); }, async down(queryInterface, Sequelize) { // Remove all 2FA fields in reverse order await queryInterface.removeColumn("Users", "twoFactorSetupPendingSecretIv"); await queryInterface.removeColumn("Users", "twoFactorSetupPendingSecret"); await queryInterface.removeColumn("Users", "twoFactorVerifiedAt"); await queryInterface.removeColumn("Users", "recoveryCodesUsedCount"); await queryInterface.removeColumn("Users", "recoveryCodesGeneratedAt"); await queryInterface.removeColumn("Users", "recoveryCodesHash"); await queryInterface.removeColumn("Users", "emailOtpAttempts"); await queryInterface.removeColumn("Users", "emailOtpExpiry"); await queryInterface.removeColumn("Users", "emailOtpCode"); await queryInterface.removeColumn("Users", "twoFactorEnabledAt"); await queryInterface.removeColumn("Users", "totpSecretIv"); await queryInterface.removeColumn("Users", "totpSecret"); await queryInterface.removeColumn("Users", "twoFactorMethod"); await queryInterface.removeColumn("Users", "twoFactorEnabled"); // Remove the ENUM type await queryInterface.sequelize.query( 'DROP TYPE IF EXISTS "enum_Users_twoFactorMethod";' ); }, };