| const mongoose = require('mongoose'); |
| const crypto = require('crypto'); |
| const signPayload = require('../server/services/signPayload'); |
| const { REFRESH_TOKEN_EXPIRY } = process.env ?? {}; |
| const expires = eval(REFRESH_TOKEN_EXPIRY) ?? 1000 * 60 * 60 * 24 * 7; |
|
|
| const sessionSchema = mongoose.Schema({ |
| refreshTokenHash: { |
| type: String, |
| required: true, |
| }, |
| expiration: { |
| type: Date, |
| required: true, |
| expires: 0, |
| }, |
| user: { |
| type: mongoose.Schema.Types.ObjectId, |
| ref: 'User', |
| required: true, |
| }, |
| }); |
|
|
| sessionSchema.methods.generateRefreshToken = async function () { |
| try { |
| let expiresIn; |
| if (this.expiration) { |
| expiresIn = this.expiration.getTime(); |
| } else { |
| expiresIn = Date.now() + expires; |
| this.expiration = new Date(expiresIn); |
| } |
|
|
| const refreshToken = await signPayload({ |
| payload: { id: this.user }, |
| secret: process.env.JWT_REFRESH_SECRET, |
| expirationTime: Math.floor((expiresIn - Date.now()) / 1000), |
| }); |
|
|
| const hash = crypto.createHash('sha256'); |
| this.refreshTokenHash = hash.update(refreshToken).digest('hex'); |
|
|
| await this.save(); |
|
|
| return refreshToken; |
| } catch (error) { |
| console.error( |
| 'Error generating refresh token. Have you set a JWT_REFRESH_SECRET in the .env file?\n\n', |
| error, |
| ); |
| throw error; |
| } |
| }; |
|
|
| sessionSchema.statics.deleteAllUserSessions = async function (userId) { |
| try { |
| if (!userId) { |
| return; |
| } |
| const result = await this.deleteMany({ user: userId }); |
| if (result && result?.deletedCount > 0) { |
| console.log(`Deleted ${result.deletedCount} sessions for user ${userId}.`); |
| } |
| } catch (error) { |
| console.log('Error in deleting user sessions:', error); |
| throw error; |
| } |
| }; |
|
|
| const Session = mongoose.model('Session', sessionSchema); |
|
|
| module.exports = Session; |
|
|