feat: stamp users.last_seen on login and token refresh
One conditional UPDATE writes it at most once per five minutes per user. A failed write is logged and never fails authentication, and no user payload carries the column.
This commit is contained in:
27
classes/last_seen.go
Normal file
27
classes/last_seen.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package classes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// TouchLastSeen stamps users.last_seen with the current time, at most once
|
||||
// per five minutes per user: it is one UPDATE that matches the row only when
|
||||
// last_seen is NULL or older than five minutes, so a busy client costs one
|
||||
// write per window. It does not touch updated_at, and it applies to a
|
||||
// deactivated user too. Login and token refresh call it and ignore its
|
||||
// error apart from logging it: authentication never depends on this write.
|
||||
func TouchLastSeen(ctx context.Context, db *gorm.DB, userID uint) error {
|
||||
if db == nil {
|
||||
return fmt.Errorf("golem15.user: gorm handle is missing")
|
||||
}
|
||||
if userID == 0 {
|
||||
return nil
|
||||
}
|
||||
return fresh(ctx, db).Exec(
|
||||
`UPDATE users SET last_seen = NOW() WHERE id = ? AND (last_seen IS NULL OR last_seen < NOW() - INTERVAL '5 minutes')`,
|
||||
userID,
|
||||
).Error
|
||||
}
|
||||
Reference in New Issue
Block a user