b114251f45
Users get a notification_channels table (replacing users.ntfy_topic); pages fan
out to every enabled channel through a notify.Provider registry, with ntfy as
the first provider. Fallbacks are typed {type, address}. Schema edited in place:
existing databases must be recreated.
Claude-Session: https://claude.ai/code/session_016mBLURvJoMuUEr9cB2RpUN
64 lines
2.5 KiB
Go
64 lines
2.5 KiB
Go
package models
|
|
|
|
import "time"
|
|
|
|
type User struct {
|
|
ID int64 `json:"id"`
|
|
Username string `json:"username"`
|
|
Email string `json:"email"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
|
|
// Channels are where this user's notifications go. Empty means they get none
|
|
// of their own; incidents assigned to them fall back to the configured
|
|
// fallback target instead. Only filled in for the user themselves and for an
|
|
// administrator, and the address only for the user themselves.
|
|
Channels []NotificationChannel `json:"channels,omitempty"`
|
|
|
|
// DisabledAt is when the account was taken out of use, or nil. A disabled
|
|
// user cannot authenticate by either credential, and keeps their name on
|
|
// every acknowledgement and timeline entry they made.
|
|
DisabledAt *time.Time `json:"disabled_at,omitempty"`
|
|
|
|
// IsAdmin is the system administrator flag: managing users and API keys.
|
|
// Not omitempty — a client has to be able to tell "false" from "this server
|
|
// is too old to have the field", and the web UI decides what to show from
|
|
// it.
|
|
IsAdmin bool `json:"is_admin"`
|
|
|
|
// AdminSource is who granted the flag: "manual" or "oidc". An "oidc"
|
|
// administrator follows the identity provider's groups, so the UI shows it as
|
|
// managed there and the API refuses to revoke it by hand. Only set on the
|
|
// user endpoints that show it.
|
|
AdminSource string `json:"admin_source,omitempty"`
|
|
}
|
|
|
|
// NotificationChannel is one way of reaching a user: a provider type and an
|
|
// address that provider understands.
|
|
type NotificationChannel struct {
|
|
ID int64 `json:"id"`
|
|
Type string `json:"type"`
|
|
|
|
// Address is an ntfy topic, later an email address. Blank unless the caller is
|
|
// the owner: it can be a secret, and an administrator has no need of it.
|
|
Address string `json:"address,omitempty"`
|
|
Enabled bool `json:"enabled"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
type APIKey struct {
|
|
ID int64 `json:"id"`
|
|
UserID int64 `json:"user_id"`
|
|
Name string `json:"name"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
|
|
|
|
// ExpiresAt is nil for a key that never expires, which is every key
|
|
// created before this field existed and still the default for a new one
|
|
// unless its creator asks otherwise (see handleCreateAPIKey's
|
|
// expires_in_days). AuthMiddleware stops accepting a key once this
|
|
// passes; nothing deletes the row for it.
|
|
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
|
|
|
Key string `json:"key,omitempty"` // populated only on creation, never stored
|
|
}
|