/*********************************************************************************************************************************************************************** * File Name: trusted_devices.mdl.js * Type of Program: Model * Description: Sequelize model for the `trusted_devices` table. * One rolling row per (user_id, fingerprint_hash) — lets a login * from an already-verified device skip the OTP gate until the * trust window lapses or is explicitly revoked. * Has a Many-to-One relationship with Users and UserSessions. * Author: Kenneth Obsequio * Date Created: Jul. 5, 2026 ***********************************************************************************************************************************************************************/ const { DataTypes } = require('sequelize'); const sequelize = require('../../config/db.config'); const mdl_Users = require('./users.mdl'); const mdl_UserSessions = require('./user_sessions.mdl'); const mdl_TrustedDevices = sequelize.define('TrustedDevices', { id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true }, user_id: { type: DataTypes.BIGINT, allowNull: false, references: { model: mdl_Users, key: 'user_id' }, }, // SHA-256 of the opaque token stored in the `device_trust` cookie. device_token_hash: { type: DataTypes.TEXT, allowNull: false }, // SHA-256 of `browser|os|device` parsed from the User-Agent header. fingerprint_hash: { type: DataTypes.TEXT, allowNull: false }, // Most recent user_sessions row minted for this device — lets a single // session termination revoke just this device's trust. last_session_id: { type: DataTypes.BIGINT, allowNull: true, references: { model: mdl_UserSessions, key: 'session_id' }, }, expires_at: { type: DataTypes.DATE, allowNull: false }, revoked_at: { type: DataTypes.DATE, allowNull: true }, // ── Audit trails ──────────────────────────────────────────────────────────── createdBy: { type: DataTypes.BIGINT, allowNull: true, label: "Created By" }, updatedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Modified By" }, deletedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Deleted By" }, }, { tableName: 'trusted_devices', timestamps: true, paranoid: true, // enables soft delete — sets deleted_at instead of DELETE }); // Associations mdl_TrustedDevices.belongsTo(mdl_Users, { foreignKey: 'user_id' }); mdl_Users.hasMany(mdl_TrustedDevices, { foreignKey: 'user_id' }); mdl_TrustedDevices.belongsTo(mdl_UserSessions, { foreignKey: 'last_session_id' }); module.exports = mdl_TrustedDevices;