Files
sm-user-plugin/models/backend_link_request.go
Jakub Zych 7ac80c9aea feat: verified frontend account link for administrators
- golem15_user_backend_links (1:1, both sides unique) and one-shot hashed
  golem15_user_backend_link_requests (golem15.user.backend_links.request_ttl, 10m)
- classes.BackendLinks: CreateLinkRequest, ConfirmLinkRequest (row lock,
  JWT iat not before the request), SetLink, RemoveLink, LinkedBackendUser;
  published as *classes.BackendLinks and pact.MCPLinkedBackendResolver
- GET /_user/api/v1/backend-link/{code} and POST /backend-link/confirm (jwt.auth)
- My account section frontend_account with link and unlink
- BackendLinkedEvent, BackendUnlinkedEvent and pact.MCPSubjectChanged after commit;
  deleting or deactivating a frontend user removes its link
- golem15.user.frontend_url (falls back to app.url)
2026-10-23 12:03:26 +02:00

32 lines
1.2 KiB
Go

package models
import "time"
// BackendLinkRequest is a one-shot request an administrator starts to link
// their account to a frontend user (golem15_user_backend_link_requests).
// Only the SHA-256 of the code is stored; the plain code travels once, in
// the site URL the administrator opens.
type BackendLinkRequest struct {
ID uint `gorm:"column:id;primaryKey"`
CodeHash string `gorm:"column:code_hash" json:"-"`
BackendUserID uint `gorm:"column:backend_user_id"`
ExpiresAt time.Time `gorm:"column:expires_at"`
UsedAt *time.Time `gorm:"column:used_at"`
CreatedAt time.Time `gorm:"column:created_at"`
}
func (BackendLinkRequest) TableName() string { return "golem15_user_backend_link_requests" }
func (BackendLinkRequest) Fillable() []string {
return []string{"code_hash", "backend_user_id", "expires_at", "used_at"}
}
func (BackendLinkRequest) Hidden() []string { return []string{"code_hash"} }
// IsUsableAt is false once the request was used or has expired.
func (r BackendLinkRequest) IsUsableAt(now time.Time) bool {
return r.UsedAt == nil && r.ExpiresAt.After(now)
}
func init() { Register(BackendLinkRequest{}) }