- 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)
32 lines
1.2 KiB
Go
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{}) }
|