86 lines
2.7 KiB
Go
86 lines
2.7 KiB
Go
package controllers
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"doormile/db"
|
|
"doormile/models"
|
|
"doormile/utils"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
// Device registration — §10 of the contract.
|
|
//
|
|
// One row per device token rather than one column on the customer. A customer
|
|
// with a phone and a tablet has to get the delivery notification on both, and
|
|
// appcustomers.device_token could only ever hold whichever registered last —
|
|
// so the older device silently stopped receiving anything.
|
|
|
|
// RegisterCxDevice records a push token for the signed-in customer.
|
|
func RegisterCxDevice(c *fiber.Ctx) error {
|
|
customerID := c.Locals("userid").(int)
|
|
|
|
var req struct {
|
|
Token string `json:"token"`
|
|
Platform string `json:"platform"`
|
|
AppVersion string `json:"appVersion"`
|
|
}
|
|
if err := c.BodyParser(&req); err != nil {
|
|
return utils.CxBadRequest(c, "We could not read that request")
|
|
}
|
|
token := strings.TrimSpace(req.Token)
|
|
if token == "" {
|
|
return utils.CxBadRequest(c, "A device token is required")
|
|
}
|
|
|
|
platform := strings.ToLower(strings.TrimSpace(req.Platform))
|
|
if platform != "android" && platform != "ios" {
|
|
platform = ""
|
|
}
|
|
|
|
device := models.CustomerDevice{
|
|
Appcustomerid: customerID,
|
|
Token: token,
|
|
Platform: platform,
|
|
Appversion: strings.TrimSpace(req.AppVersion),
|
|
Lastseenat: utils.DBNow(),
|
|
}
|
|
|
|
// A token can migrate between accounts — a shared handset, or a customer
|
|
// signing out and a second one signing in. Upserting on the token (rather
|
|
// than inserting) reassigns it, which is the only outcome that does not
|
|
// send one person's parcel updates to another person's phone.
|
|
if err := db.DB.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "token"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{
|
|
"appcustomerid", "platform", "appversion", "lastseenat",
|
|
}),
|
|
}).Create(&device).Error; err != nil {
|
|
utils.Error("RegisterCxDevice: upsert failed", "customer_id", customerID, "error", err)
|
|
return utils.CxInternal(c)
|
|
}
|
|
|
|
return utils.CxOK(c, fiber.Map{"registered": true})
|
|
}
|
|
|
|
// UnregisterCxDevice drops a push token. Called on sign-out, so a signed-out
|
|
// phone stops receiving updates about a pickup it can no longer open.
|
|
func UnregisterCxDevice(c *fiber.Ctx) error {
|
|
customerID := c.Locals("userid").(int)
|
|
token := strings.TrimSpace(c.Params("token"))
|
|
if token == "" {
|
|
return utils.CxBadRequest(c, "A device token is required")
|
|
}
|
|
|
|
if err := db.DB.Where("appcustomerid = ? AND token = ?", customerID, token).
|
|
Delete(&models.CustomerDevice{}).Error; err != nil && err != gorm.ErrRecordNotFound {
|
|
utils.Error("UnregisterCxDevice: delete failed", "customer_id", customerID, "error", err)
|
|
return utils.CxInternal(c)
|
|
}
|
|
|
|
return utils.CxOK(c, fiber.Map{"registered": false})
|
|
}
|