tableSessions.go (2875B)
1 package database 2 3 import ( 4 "github.com/sirupsen/logrus" 5 "time" 6 7 "dkforest/pkg/utils" 8 ) 9 10 // Session table 11 type Session struct { 12 Token string // 32 bytes random token 13 ExpiresAt time.Time // Time at which the session expires 14 DeletedAt *time.Time // Time at which a session was soft deleted 15 CreatedAt time.Time // Time at which a session was created 16 UserID UserID // User that owns the session 17 ClientIP string // IP address used to create the session 18 UserAgent string // Browser UserAgent that was used to create the session 19 User User // User object for association queries 20 } 21 22 // GetActiveUserSessions gets all user sessions 23 func (d *DkfDB) GetActiveUserSessions(userID UserID) (out []Session) { 24 d.db.Order("created_at DESC").Find(&out, "user_id = ? AND expires_at > DATETIME('now', 'localtime') AND deleted_at IS NULL", userID) 25 return 26 } 27 28 // CreateSession creates a session for a user 29 func (d *DkfDB) CreateSession(userID UserID, userAgent string, sessionDuration time.Duration) (Session, error) { 30 // Delete all sessions except the last 4 31 if err := d.db.Exec(`DELETE FROM sessions WHERE user_id = ? AND token NOT IN (SELECT s2.token FROM sessions s2 WHERE s2.user_id = ? ORDER BY s2.created_at DESC LIMIT 4)`, userID, userID).Error; err != nil { 32 logrus.Error(err) 33 } 34 session := Session{ 35 Token: utils.GenerateToken32(), 36 UserID: userID, 37 ClientIP: "", 38 UserAgent: userAgent, 39 ExpiresAt: time.Now().Add(sessionDuration), 40 } 41 err := d.db.Create(&session).Error 42 return session, err 43 } 44 45 // DoCreateSession same as CreateSession but log the error instead of returning it 46 func (d *DkfDB) DoCreateSession(userID UserID, userAgent string, sessionDuration time.Duration) Session { 47 session, err := d.CreateSession(userID, userAgent, sessionDuration) 48 if err != nil { 49 logrus.Error("Failed to create session : ", err) 50 } 51 return session 52 } 53 54 // DeleteUserSessions all sessions of the user. 55 func (d *DkfDB) DeleteUserSessions(userID UserID) error { 56 return d.db.Unscoped().Where("user_id = ?", userID).Delete(&Session{}).Error 57 } 58 59 // DeleteSessionByToken a session by its token 60 func (d *DkfDB) DeleteSessionByToken(token string) error { 61 return d.db.Unscoped().Where("token = ?", token).Delete(&Session{}).Error 62 } 63 64 func (d *DkfDB) DeleteUserSessionByToken(userID UserID, token string) error { 65 return d.db.Unscoped().Where("user_id = ? AND token = ?", userID, token).Delete(&Session{}).Error 66 } 67 68 func (d *DkfDB) DeleteUserOtherSessions(userID UserID, currentToken string) error { 69 return d.db.Unscoped().Where("user_id = ? AND token != ?", userID, currentToken).Delete(&Session{}).Error 70 } 71 72 func (d *DkfDB) DeleteOldSessions() { 73 if err := d.db.Unscoped().Delete(Session{}, "expires_at < date('now', '-32 Day') OR (expires_at < date('now', '-32 Day') AND deleted_at IS NOT NULL)").Error; err != nil { 74 logrus.Error(err) 75 } 76 }