import mongoose from 'mongoose'; const SessionSchema = new mongoose.Schema( { userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true, index: true, }, steamId: { type: String, required: true, index: true, }, token: { type: String, required: true, unique: true, }, refreshToken: { type: String, required: true, unique: true, }, ip: { type: String, default: null, }, userAgent: { type: String, default: null, }, device: { type: String, default: null, }, browser: { type: String, default: null, }, os: { type: String, default: null, }, location: { country: { type: String, default: null }, city: { type: String, default: null }, region: { type: String, default: null }, }, isActive: { type: Boolean, default: true, }, lastActivity: { type: Date, default: Date.now, }, expiresAt: { type: Date, required: true, index: { expires: 0 }, // TTL index - automatically delete expired sessions }, }, { timestamps: true, } ); // Index for cleaning up old sessions SessionSchema.index({ createdAt: 1 }); SessionSchema.index({ userId: 1, isActive: 1 }); // Method to mark session as inactive SessionSchema.methods.deactivate = async function () { this.isActive = false; return this.save(); }; // Method to update last activity SessionSchema.methods.updateActivity = async function () { this.lastActivity = Date.now(); return this.save(); }; // Static method to clean up inactive sessions for a user SessionSchema.statics.cleanupUserSessions = async function (userId, keepCurrent = null) { const query = { userId, isActive: false, }; if (keepCurrent) { query._id = { $ne: keepCurrent }; } return this.deleteMany(query); }; // Static method to get active sessions for a user SessionSchema.statics.getActiveSessions = async function (userId) { return this.find({ userId, isActive: true, expiresAt: { $gt: new Date() }, }).sort({ lastActivity: -1 }); }; // Static method to revoke all sessions except current SessionSchema.statics.revokeAllExcept = async function (userId, currentSessionId) { return this.updateMany( { userId, _id: { $ne: currentSessionId }, isActive: true, }, { $set: { isActive: false }, } ); }; // Static method to revoke all sessions SessionSchema.statics.revokeAll = async function (userId) { return this.updateMany( { userId, isActive: true, }, { $set: { isActive: false }, } ); }; export default mongoose.model('Session', SessionSchema);