package db_cold import ( "log" "reflect" "time" "gorm.io/gorm" ) const EXPIRATION_BUFFER = 5 * time.Minute type UserAuth struct { gorm.Model UserID string `gorm:"primarykey"` UserName string UserLogin string UserEmail string AccessToken string RefreshToken string TokenExpires time.Time } func (db *DBColdConn) initUserAuth() { db.Gorm.AutoMigrate(&UserAuth{}) } func (db *DBColdConn) GetAllUserAuth() ([]UserAuth, error) { var userAuths []UserAuth res := db.Gorm.Find(&userAuths) if res.Error != nil { return nil, res.Error } return userAuths, nil } // add or update user auth, based on ID func (db *DBColdConn) updateUserAuthTime(userID, userName, userLogin, accessToken, refreshToken string, tokenExpires time.Time) error { userAuth := UserAuth{ UserID: userID, UserName: userName, UserLogin: userLogin, AccessToken: accessToken, RefreshToken: refreshToken, TokenExpires: tokenExpires, } rows, err := gorm.G[UserAuth](db.Gorm).Where("id = ?", userID).Find(db.Ctx) if err != nil { return err } if len(rows) > 0 { // update _, err := gorm.G[UserAuth](db.Gorm).Where("id = ?", userID).Updates(db.Ctx, userAuth) if err != nil { return err } } else { // add err := gorm.G[UserAuth](db.Gorm).Create(db.Ctx, &userAuth) if err != nil { return err } } return nil } func (db *DBColdConn) updateUserAuthDuration(userID, userName, userLogin, accessToken, refreshToken string, tokenExpires time.Duration) error { return db.updateUserAuthTime(userID, userName, userLogin, accessToken, refreshToken, time.Now().Add(tokenExpires-EXPIRATION_BUFFER)) } func (db *DBColdConn) updateUserAuthInt(userID, userName, userLogin, accessToken, refreshToken string, tokenExpires int) error { return db.updateUserAuthDuration(userID, userName, userLogin, accessToken, refreshToken, time.Duration(tokenExpires)*time.Second) } /** tokenExpires: time.Time | time.Duration | int */ func (db *DBColdConn) UpdateUserAuth(userID, userName, userLogin, accessToken, refreshToken string, tokenExpires any) error { /* expires can be: - time.Time - passed directly - time.Duration - converted to time.Time from now - int - converted to time.Duration in seconds then time.Time from now */ switch exp := tokenExpires.(type) { case time.Time: return db.updateUserAuthTime(userID, userName, userLogin, accessToken, refreshToken, exp) case time.Duration: return db.updateUserAuthDuration(userID, userName, userLogin, accessToken, refreshToken, exp) case int: return db.updateUserAuthInt(userID, userName, userLogin, accessToken, refreshToken, exp) default: log.Panicf("invalid type passed to any field in TwitchAuth.updateUserDetails(): %s, value: %v", reflect.TypeOf(tokenExpires), tokenExpires) panic("we've already panicked") } }