✨ Subscribable notification
This commit is contained in:
		| @@ -17,6 +17,7 @@ func RunMigration(source *gorm.DB) error { | ||||
| 		&models.ThirdClient{}, | ||||
| 		&models.ActionEvent{}, | ||||
| 		&models.Notification{}, | ||||
| 		&models.NotificationSubscriber{}, | ||||
| 	); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
| @@ -17,21 +17,22 @@ const ( | ||||
| type Account struct { | ||||
| 	BaseModel | ||||
|  | ||||
| 	Name          string           `json:"name" gorm:"uniqueIndex"` | ||||
| 	Nick          string           `json:"nick"` | ||||
| 	Avatar        string           `json:"avatar"` | ||||
| 	State         AccountState     `json:"state"` | ||||
| 	Profile       AccountProfile   `json:"profile"` | ||||
| 	Sessions      []AuthSession    `json:"sessions"` | ||||
| 	Challenges    []AuthChallenge  `json:"challenges"` | ||||
| 	Factors       []AuthFactor     `json:"factors"` | ||||
| 	Contacts      []AccountContact `json:"contacts"` | ||||
| 	Events        []ActionEvent    `json:"events"` | ||||
| 	MagicTokens   []MagicToken     `json:"-" gorm:"foreignKey:AssignTo"` | ||||
| 	ThirdClients  []ThirdClient    `json:"clients"` | ||||
| 	Notifications []Notification   `json:"notifications" gorm:"foreignKey:RecipientID"` | ||||
| 	ConfirmedAt   *time.Time       `json:"confirmed_at"` | ||||
| 	PowerLevel    int              `json:"power_level"` | ||||
| 	Name              string                   `json:"name" gorm:"uniqueIndex"` | ||||
| 	Nick              string                   `json:"nick"` | ||||
| 	Avatar            string                   `json:"avatar"` | ||||
| 	State             AccountState             `json:"state"` | ||||
| 	Profile           AccountProfile           `json:"profile"` | ||||
| 	Sessions          []AuthSession            `json:"sessions"` | ||||
| 	Challenges        []AuthChallenge          `json:"challenges"` | ||||
| 	Factors           []AuthFactor             `json:"factors"` | ||||
| 	Contacts          []AccountContact         `json:"contacts"` | ||||
| 	Events            []ActionEvent            `json:"events"` | ||||
| 	MagicTokens       []MagicToken             `json:"-" gorm:"foreignKey:AssignTo"` | ||||
| 	ThirdClients      []ThirdClient            `json:"clients"` | ||||
| 	Notifications     []Notification           `json:"notifications" gorm:"foreignKey:RecipientID"` | ||||
| 	NotifySubscribers []NotificationSubscriber `json:"notify_subscribers"` | ||||
| 	ConfirmedAt       *time.Time               `json:"confirmed_at"` | ||||
| 	PowerLevel        int                      `json:"power_level"` | ||||
| } | ||||
|  | ||||
| func (v Account) GetPrimaryEmail() AccountContact { | ||||
|   | ||||
| @@ -12,3 +12,16 @@ type Notification struct { | ||||
| 	SenderID    *uint      `json:"sender_id"` | ||||
| 	RecipientID uint       `json:"recipient_id"` | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	NotifySubscriberFirebase = "firebase" | ||||
| ) | ||||
|  | ||||
| type NotificationSubscriber struct { | ||||
| 	BaseModel | ||||
|  | ||||
| 	UserAgent string `json:"user_agent"` | ||||
| 	Provider  string `json:"provider"` | ||||
| 	DeviceID  string `json:"device_id"` | ||||
| 	AccountID uint   `json:"account_id"` | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package server | ||||
| import ( | ||||
| 	"code.smartsheep.studio/hydrogen/passport/pkg/database" | ||||
| 	"code.smartsheep.studio/hydrogen/passport/pkg/models" | ||||
| 	"code.smartsheep.studio/hydrogen/passport/pkg/services" | ||||
| 	"github.com/gofiber/fiber/v2" | ||||
| 	"github.com/samber/lo" | ||||
| 	"time" | ||||
| @@ -57,3 +58,28 @@ func markNotificationRead(c *fiber.Ctx) error { | ||||
| 		return c.SendStatus(fiber.StatusOK) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func addNotifySubscriber(c *fiber.Ctx) error { | ||||
| 	user := c.Locals("principal").(models.Account) | ||||
|  | ||||
| 	var data struct { | ||||
| 		Provider string `json:"provider" validate:"required"` | ||||
| 		DeviceID string `json:"device_id" validate:"required"` | ||||
| 	} | ||||
|  | ||||
| 	if err := BindAndValidate(c, &data); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	subscriber, err := services.AddNotifySubscriber( | ||||
| 		user, | ||||
| 		data.Provider, | ||||
| 		data.DeviceID, | ||||
| 		c.Get(fiber.HeaderUserAgent), | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return fiber.NewError(fiber.StatusBadRequest, err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return c.JSON(subscriber) | ||||
| } | ||||
|   | ||||
| @@ -62,6 +62,7 @@ func NewServer() { | ||||
|  | ||||
| 		api.Get("/notifications", auth, getNotifications) | ||||
| 		api.Put("/notifications/:notificationId/read", auth, markNotificationRead) | ||||
| 		api.Post("/notification/subscribe", auth, addNotifySubscriber) | ||||
|  | ||||
| 		api.Get("/users/me", auth, getUserinfo) | ||||
| 		api.Put("/users/me", auth, editUserinfo) | ||||
|   | ||||
| @@ -5,6 +5,19 @@ import ( | ||||
| 	"code.smartsheep.studio/hydrogen/passport/pkg/models" | ||||
| ) | ||||
|  | ||||
| func AddNotifySubscriber(user models.Account, provider, device, ua string) (models.NotificationSubscriber, error) { | ||||
| 	subscriber := models.NotificationSubscriber{ | ||||
| 		UserAgent: ua, | ||||
| 		Provider:  provider, | ||||
| 		DeviceID:  ua, | ||||
| 		AccountID: user.ID, | ||||
| 	} | ||||
|  | ||||
| 	err := database.C.Save(&subscriber).Error | ||||
|  | ||||
| 	return subscriber, err | ||||
| } | ||||
|  | ||||
| func NewNotification(user models.ThirdClient, target models.Account, subject, content string, important bool) error { | ||||
| 	notification := models.Notification{ | ||||
| 		Subject:     subject, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user