✨ Status system
This commit is contained in:
@ -25,6 +25,17 @@ func GetAccount(id uint) (models.Account, error) {
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func GetAccountWithName(alias string) (models.Account, error) {
|
||||
var account models.Account
|
||||
if err := database.C.Where(models.Account{
|
||||
Name: alias,
|
||||
}).First(&account).Error; err != nil {
|
||||
return account, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func LookupAccount(probe string) (models.Account, error) {
|
||||
var account models.Account
|
||||
if err := database.C.Where(models.Account{Name: probe}).First(&account).Error; err == nil {
|
||||
|
@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/samber/lo"
|
||||
"strings"
|
||||
|
||||
@ -81,7 +82,8 @@ func GetFactorCode(factor models.AuthFactor) (bool, error) {
|
||||
subject := fmt.Sprintf("[%s] Login verification code", viper.GetString("name"))
|
||||
content := fmt.Sprintf(EmailPasswordTemplate, user.Name, factor.Secret, viper.GetString("maintainer"))
|
||||
if err := SendMail(user.GetPrimaryEmail().Content, subject, content); err != nil {
|
||||
return true, err
|
||||
log.Warn().Err(err).Uint("factor", factor.ID).Msg("Failed to delivery one-time-password via mail...")
|
||||
return true, nil
|
||||
}
|
||||
return true, nil
|
||||
|
||||
|
@ -65,7 +65,10 @@ func PushNotification(notification models.Notification) error {
|
||||
}.Marshal())
|
||||
}
|
||||
|
||||
// TODO Detect the push notification is turned off (still push when IsForcePush is on)
|
||||
// Skip push notify
|
||||
if GetStatusDisturbable(notification.RecipientID) != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var subscribers []models.NotificationSubscriber
|
||||
if err := database.C.Where(&models.NotificationSubscriber{
|
||||
|
59
pkg/internal/services/statuses.go
Normal file
59
pkg/internal/services/statuses.go
Normal file
@ -0,0 +1,59 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
var statusCache = make(map[uint]models.Status)
|
||||
|
||||
func NewStatus(user models.Account, status models.Status) (models.Status, error) {
|
||||
if err := database.C.Save(&status).Error; err != nil {
|
||||
return status, err
|
||||
} else {
|
||||
statusCache[user.ID] = status
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
||||
func GetStatus(uid uint) (models.Status, error) {
|
||||
if status, ok := statusCache[uid]; ok {
|
||||
return status, nil
|
||||
}
|
||||
var status models.Status
|
||||
if err := database.C.
|
||||
Where("account_id = ?", uid).
|
||||
Where("clear_at < ?", time.Now()).
|
||||
First(&status).Error; err != nil {
|
||||
return status, err
|
||||
} else {
|
||||
statusCache[uid] = status
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
||||
func GetStatusDisturbable(uid uint) error {
|
||||
status, err := GetStatus(uid)
|
||||
isOnline := wsConn[uid] == nil || len(wsConn[uid]) < 0
|
||||
if isOnline && err != nil {
|
||||
return nil
|
||||
} else if err == nil && status.IsNoDisturb {
|
||||
return fmt.Errorf("do not disturb")
|
||||
} else {
|
||||
return fmt.Errorf("offline")
|
||||
}
|
||||
}
|
||||
|
||||
func GetStatusOnline(uid uint) error {
|
||||
status, err := GetStatus(uid)
|
||||
isOnline := wsConn[uid] == nil || len(wsConn[uid]) < 0
|
||||
if isOnline && err != nil {
|
||||
return nil
|
||||
} else if err == nil && status.IsInvisible {
|
||||
return fmt.Errorf("invisible")
|
||||
} else {
|
||||
return fmt.Errorf("offline")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user