Documentation
¶
Overview ¶
Package apiclient is how the frontend process talks to the backend process. The backend owns the database, the keys and every security decision; the frontend renders pages from what this client returns. The package must not import the store or the web package.
The wire protocol is the backend's internal API under /internal/v1. It is not a public API and may change between versions: deploy the frontend and the backend from the same release.
Index ¶
- Constants
- Variables
- func DefaultHTTPClient() *http.Client
- func HTTPClient(tlsConfig *tls.Config) *http.Client
- func InProcess(h http.Handler) http.RoundTripper
- func IsCode(err error, code string) bool
- func StatusOf(err error) int
- func WithRequest(ctx context.Context, rq Request) context.Context
- type AdminPage
- type AdminProvider
- type AdminResult
- type AdminStatus
- type AdminUser
- type AdminWithings
- type Analytics
- type AuditLine
- type Client
- func (c *Client) AdminAddUser(ctx context.Context, name, email, password string) (AdminResult, error)
- func (c *Client) AdminCancelJob(ctx context.Context, id string) (AdminResult, error)
- func (c *Client) AdminDeleteProvider(ctx context.Context, slug string) (AdminResult, error)
- func (c *Client) AdminDeleteUser(ctx context.Context, id int64) (AdminResult, error)
- func (c *Client) AdminPage(ctx context.Context, edit string) (AdminPage, error)
- func (c *Client) AdminPasswordLogin(ctx context.Context, on bool) (AdminResult, error)
- func (c *Client) AdminRemoveTwoFactor(ctx context.Context, id int64) (AdminResult, error)
- func (c *Client) AdminResetLink(ctx context.Context, id int64, email bool) (AdminResult, error)
- func (c *Client) AdminResumeSchedule(ctx context.Context, userID int64, kind string) (AdminResult, error)
- func (c *Client) AdminResumeWorkerKind(ctx context.Context, kind string) (AdminResult, error)
- func (c *Client) AdminSaveAnalytics(ctx context.Context, a Analytics) (AdminResult, error)
- func (c *Client) AdminSaveProvider(ctx context.Context, f ProviderForm) (AdminResult, error)
- func (c *Client) AdminSaveSMTP(ctx context.Context, f SMTPForm) (AdminResult, error)
- func (c *Client) AdminSaveServer(ctx context.Context, f ServerForm) (AdminResult, error)
- func (c *Client) AdminSaveTLS(ctx context.Context, f TLSForm) (AdminResult, error)
- func (c *Client) AdminSaveWithings(ctx context.Context, f WithingsForm) (AdminResult, error)
- func (c *Client) AdminSaveWorkerKind(ctx context.Context, kind string, f WorkerKindForm) (AdminResult, error)
- func (c *Client) AdminSaveWorkersGlobal(ctx context.Context, f WorkersGlobalForm) (AdminResult, error)
- func (c *Client) AdminSetJobPriority(ctx context.Context, userID int64, priority int) (AdminResult, error)
- func (c *Client) AdminSetPassword(ctx context.Context, id int64, password string) (AdminResult, error)
- func (c *Client) AdminSetRole(ctx context.Context, id int64, role string) (AdminResult, error)
- func (c *Client) AdminSetStrengthLevel(ctx context.Context, id int64, on bool) (AdminResult, error)
- func (c *Client) AdminSetStrengthLevelBulk(ctx context.Context, id int64, on bool) (AdminResult, error)
- func (c *Client) AdminSignup(ctx context.Context, open bool) (AdminResult, error)
- func (c *Client) AdminStatus(ctx context.Context) (*StatusDetail, error)
- func (c *Client) AdminStepUp(ctx context.Context) (bool, error)
- func (c *Client) AdminTestSMTP(ctx context.Context) (AdminResult, error)
- func (c *Client) AdminTwoFactorPolicy(ctx context.Context, require string) (AdminResult, error)
- func (c *Client) AdminVerify(ctx context.Context, code string) (SecondStep, error)
- func (c *Client) AdminWorkers(ctx context.Context) (*WorkersPage, error)
- func (c *Client) ChangePassword(ctx context.Context, userID int64, p PasswordChange) (SettingsPage, error)
- func (c *Client) ConnectIntegration(ctx context.Context, userID int64, provider string) (string, error)
- func (c *Client) CreateDexaScan(ctx context.Context, userID int64, sc models.DexaScan) error
- func (c *Client) CreateScaleReading(ctx context.Context, userID int64, rd models.ScaleReading) error
- func (c *Client) CreateToken(ctx context.Context, userID int64, rq NewTokenRequest) (string, error)
- func (c *Client) Delete(ctx context.Context, path string) error
- func (c *Client) DeleteDexaScan(ctx context.Context, userID, id int64) error
- func (c *Client) DeletePasskey(ctx context.Context, userID int64, cred, current string) (string, error)
- func (c *Client) DeleteScaleReading(ctx context.Context, userID, id int64) error
- func (c *Client) DeleteStrengthLevelLogin(ctx context.Context, userID int64) (Flash, error)
- func (c *Client) DeleteToken(ctx context.Context, userID, id int64) error
- func (c *Client) DexaScans(ctx context.Context, userID int64) ([]models.DexaScan, error)
- func (c *Client) DisconnectIntegration(ctx context.Context, userID int64, provider string) (Flash, error)
- func (c *Client) Do(ctx context.Context, method, path string, in, out any) (*Result, error)
- func (c *Client) EstimatesPage(ctx context.Context, userID int64, days int) (EstimatesPage, error)
- func (c *Client) FrontendConfig(ctx context.Context, etag string) (*FrontendConfig, string, error)
- func (c *Client) Get(ctx context.Context, path string, out any) error
- func (c *Client) Health(ctx context.Context) error
- func (c *Client) Import(ctx context.Context, userID int64, provider, day string) (Flash, error)
- func (c *Client) IntegrationCallback(ctx context.Context, provider, state, code, providerError string) (Flash, error)
- func (c *Client) Login(ctx context.Context, email, password string) (SignInOutcome, error)
- func (c *Client) LoginPage(ctx context.Context) (LoginPage, error)
- func (c *Client) LoginSecondStep(ctx context.Context, code string) (SecondStep, error)
- func (c *Client) LoginSecondStepPage(ctx context.Context) (SecondStep, error)
- func (c *Client) LoginSetup(ctx context.Context, code string) (SecondStep, error)
- func (c *Client) LoginSetupPage(ctx context.Context) (SecondStep, error)
- func (c *Client) Logout(ctx context.Context) error
- func (c *Client) PasskeyLoginBegin(ctx context.Context) (json.RawMessage, error)
- func (c *Client) PasskeyLoginFinish(ctx context.Context, body io.Reader) (SignInOutcome, error)
- func (c *Client) PasskeyRegisterBegin(ctx context.Context, userID int64, name, current string) (json.RawMessage, error)
- func (c *Client) PasskeyRegisterFinish(ctx context.Context, userID int64, body io.Reader) (SignInOutcome, error)
- func (c *Client) Post(ctx context.Context, path string, in, out any) error
- func (c *Client) ProviderCallback(ctx context.Context, slug string, params map[string]string) (SignInOutcome, error)
- func (c *Client) ProviderStart(ctx context.Context, slug string, link bool, current string) (SignInOutcome, error)
- func (c *Client) Raw(ctx context.Context, method, path string, body io.Reader, header http.Header) (*http.Response, error)
- func (c *Client) RenamePasskey(ctx context.Context, userID int64, cred, name string) error
- func (c *Client) Reset(ctx context.Context, token, password, confirm, code string) (ResetStep, error)
- func (c *Client) ResetForgot(ctx context.Context, email string) (ResetStep, error)
- func (c *Client) ResetForgotPage(ctx context.Context) (ResetStep, error)
- func (c *Client) ResetFormPage(ctx context.Context, token string) (ResetStep, error)
- func (c *Client) SaveHiddenColumns(ctx context.Context, userID int64, hidden []string) error
- func (c *Client) SaveProfile(ctx context.Context, userID int64, p Profile) error
- func (c *Client) SaveSettings(ctx context.Context, userID int64, s Settings) error
- func (c *Client) SaveStrengthLevelLogin(ctx context.Context, userID int64, email, password string) (Flash, error)
- func (c *Client) ScalePage(ctx context.Context, userID int64, before string) (ScalePage, error)
- func (c *Client) SendStrengthLevelDay(ctx context.Context, userID int64, day string) (Flash, error)
- func (c *Client) Session(ctx context.Context) (*models.User, error)
- func (c *Client) SettingsPage(ctx context.Context, userID int64, msg string) (SettingsPage, error)
- func (c *Client) Signup(ctx context.Context, name, email, password, confirm string) (SignInOutcome, error)
- func (c *Client) StartStrengthLevelSync(ctx context.Context, userID int64, days string, update bool) (Flash, error)
- func (c *Client) Status(ctx context.Context) (*Status, error)
- func (c *Client) StrengthLevelStatus(ctx context.Context, userID int64) (*SLJobView, error)
- func (c *Client) TwoFactorBegin(ctx context.Context, userID int64, current string) (TwoFactorChange, error)
- func (c *Client) TwoFactorConfirm(ctx context.Context, userID int64, code string) (TwoFactorChange, error)
- func (c *Client) TwoFactorDisable(ctx context.Context, userID int64, current, code string) error
- func (c *Client) TwoFactorRecovery(ctx context.Context, userID int64, current, code string) (TwoFactorChange, error)
- func (c *Client) UnlinkIdentity(ctx context.Context, userID int64, provider string) (string, error)
- type Error
- type EstimatesPage
- type Flash
- type FrontendConfig
- type IntegrationView
- type KeyView
- type LinkedProvider
- type LoginPage
- type LoginProvider
- type NewTokenRequest
- type PasskeyItem
- type PasskeysView
- type PasswordChange
- type Profile
- type ProviderForm
- type Request
- type ResetLink
- type ResetStep
- type Result
- type SLJobView
- type SLView
- type SMTPForm
- type SMTPView
- type ScalePage
- type SecondStep
- type SecurityView
- type ServerForm
- type ServerSettingsView
- type SessionUser
- type Settings
- type SettingsPage
- type SignInOutcome
- type Status
- type StatusComponent
- type StatusDetail
- type StatusWorker
- type TLSForm
- type TLSView
- type TokenView
- type TwoFactorChange
- type TwoFactorSettings
- type TwoFactorSetup
- type WithingsForm
- type WorkerInstanceView
- type WorkerJobView
- type WorkerKindForm
- type WorkerKindView
- type WorkerOptionView
- type WorkerProviderView
- type WorkersGlobalForm
- type WorkersPage
Constants ¶
const ( // HeaderService carries the shared secret that proves the caller is the frontend. HeaderService = "X-Dexafix-Service" // HeaderClientIP, HeaderSecure and HeaderHost describe the visitor's own request, after the // frontend settled the proxy headers. The backend believes them only after the service secret // checked out. HeaderClientIP = "X-Dexafix-Client-IP" HeaderSecure = "X-Dexafix-Secure" HeaderHost = "X-Dexafix-Host" // HeaderCookie carries the visitor's Cookie header. The backend reads its session and sealed // state cookies from it and answers with Set-Cookie headers, which the frontend relays. The // sealing keys stay in the backend: the frontend only stores and returns the opaque values. HeaderCookie = "X-Dexafix-Cookie" )
Header names of the internal API.
const ( CodeNotFound = "not_found" CodeInvalid = "invalid" CodeExists = "exists" CodeThrottled = "throttled" CodeForbidden = "forbidden" CodeReauth = "reauth_required" CodeStepUp = "step_up_required" CodeInternal = "internal" )
Codes in Error.Code.
const ( TLSOff = "off" TLSUpload = "upload" TLSSelfSigned = "selfsigned" )
The values of FrontendConfig.TLSMode.
const ( StateUp = "up" // works StateDegraded = "degraded" // works, but something is wrong; no component reports it yet, the page and Overall handle it StateDown = "down" // does not work StateOff = "off" // not in use (for example no worker has ever registered): not a fault )
Component states.
const HeaderResetToken = "X-Dexafix-Reset-Token"
HeaderResetToken carries a password reset token. It travels in a header, never in a URL, so it does not end up in access logs.
const Prefix = "/internal/v1"
Prefix of every internal API path.
const SessionCookie = "dexafix_session"
SessionCookie is the name of the cookie that holds the session. The browser sends it to the frontend, which passes it on to the backend (HeaderCookie).
Variables ¶
ErrUnavailable is returned when the backend cannot be reached or answers with a server error. Pages render a "temporarily unavailable" notice for it.
Functions ¶
func DefaultHTTPClient ¶
DefaultHTTPClient is a client with timeouts and connection limits suited to the internal link.
func HTTPClient ¶
HTTPClient is DefaultHTTPClient with a TLS configuration for the link, such as the mutual TLS configuration of package mtls. nil means plain HTTP.
func InProcess ¶
func InProcess(h http.Handler) http.RoundTripper
InProcess returns a transport that runs requests against h in the same process, on a goroutine of its own, so the combined `serve` mode goes through exactly the same middleware as two processes do. The body of the answer is streamed, not buffered.
Types ¶
type AdminPage ¶
type AdminPage struct {
Status AdminStatus
Users []AdminUser
PasswordEnabled bool
PasswordForced bool
SignupOpen bool
Providers []AdminProvider
Form AdminProvider // the add or edit form
Editing bool
Withings AdminWithings
Audit []AuditLine
Key KeyView
Require2FA string // off, admins or everyone
Server ServerSettingsView
Analytics Analytics
SMTP SMTPView
ResetByEmail bool // users can ask for a reset e-mail
TLS TLSView
}
AdminPage is the data of the Admin page.
type AdminProvider ¶
type AdminProvider struct {
models.AuthProvider
CallbackURL string
HasSecret bool
}
AdminProvider is a sign-in provider as the Admin page shows it. The secret is never sent.
type AdminResult ¶
type AdminResult struct {
Message string `json:"message,omitempty"`
ConfigChanged bool `json:"config_changed,omitempty"`
ListenCheck bool `json:"listen_check,omitempty"`
ResetLink *ResetLink `json:"reset_link,omitempty"`
}
AdminResult is the outcome of a change. Message is the flash text for the Admin page (refusals the administrator can fix are messages too, not errors). ConfigChanged is true when the change touched the settings the frontend acts on (base URL, proxies, TLS): the frontend fetches them again before it answers. ListenCheck is true when the frontend's own listener state decides the message (HTTPS was turned on). ResetLink is set instead of a Message when a link was made.
type AdminStatus ¶
type AdminStatus struct {
Driver string
Encrypted bool
SchemaVersion int64
Users int
Admins int
DexaScans int
ScaleReadings int
// BodyUnavailable is set when the service that holds the scans and readings did not answer, so
// the two counts above are unknown and not zero.
Sessions int
AccessTokens int
TwoFactorUsers int
}
AdminStatus is the database and usage figures of the Admin page.
type AdminUser ¶
type AdminUser struct {
ID int64
Name string
Email string
Admin bool
Self bool
Created string
SignIn string
// StrengthLevel is whether the user may sync to Strength Level automatically.
StrengthLevel bool
// StrengthLevelBulk is whether the user may also run the multi-day sync from Settings.
StrengthLevelBulk bool
TwoFactor bool // two-step verification is on
// JobPriority (1-100) orders the user's worker jobs among other users'; a higher number goes
// first, and administrators always go before everyone.
JobPriority int
}
type AdminWithings ¶
type Analytics ¶
type Analytics struct {
ScarfPixelID string `json:"scarf_pixel_id,omitempty"` // a UUID
GoogleAnalyticsID string `json:"google_analytics_id,omitempty"` // G-XXXXXXXXXX
AdSensePublisher string `json:"adsense_publisher,omitempty"` // ca-pub-0000000000000000
}
Analytics holds the identifiers of the optional services. An empty one is off.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client calls the backend. It is safe for concurrent use.
func New ¶
New returns a client for the backend at base (for example http://api:8081). hc may be nil.
func (*Client) AdminAddUser ¶
func (c *Client) AdminAddUser(ctx context.Context, name, email, password string) (AdminResult, error)
AdminAddUser creates an account with a password.
func (*Client) AdminCancelJob ¶
func (*Client) AdminDeleteProvider ¶
func (*Client) AdminDeleteUser ¶
func (*Client) AdminPage ¶
AdminPage fetches the page; edit is the slug of the provider to edit, or empty.
func (*Client) AdminPasswordLogin ¶
func (*Client) AdminRemoveTwoFactor ¶
AdminRemoveTwoFactor removes a user's second step.
func (*Client) AdminResetLink ¶
AdminResetLink makes a one-time reset link, and e-mails it too when email is set and possible.
func (*Client) AdminResumeSchedule ¶
func (c *Client) AdminResumeSchedule(ctx context.Context, userID int64, kind string) (AdminResult, error)
AdminResumeSchedule lets the scheduler run a kind for a user again after it paused their runs.
func (*Client) AdminResumeWorkerKind ¶
AdminResumeWorkerKind turns a paused kind back on, and starts counting failures afresh.
func (*Client) AdminSaveAnalytics ¶
AdminSaveAnalytics stores the identifiers of the optional analytics and ad services; an empty one turns that service off.
func (*Client) AdminSaveProvider ¶
func (c *Client) AdminSaveProvider(ctx context.Context, f ProviderForm) (AdminResult, error)
func (*Client) AdminSaveSMTP ¶
func (*Client) AdminSaveServer ¶
func (c *Client) AdminSaveServer(ctx context.Context, f ServerForm) (AdminResult, error)
func (*Client) AdminSaveTLS ¶
func (*Client) AdminSaveWithings ¶
func (c *Client) AdminSaveWithings(ctx context.Context, f WithingsForm) (AdminResult, error)
func (*Client) AdminSaveWorkerKind ¶
func (c *Client) AdminSaveWorkerKind(ctx context.Context, kind string, f WorkerKindForm) (AdminResult, error)
func (*Client) AdminSaveWorkersGlobal ¶
func (c *Client) AdminSaveWorkersGlobal(ctx context.Context, f WorkersGlobalForm) (AdminResult, error)
func (*Client) AdminSetJobPriority ¶
func (c *Client) AdminSetJobPriority(ctx context.Context, userID int64, priority int) (AdminResult, error)
AdminSetJobPriority sets a user's job priority, 1 to 100.
func (*Client) AdminSetPassword ¶
func (*Client) AdminSetRole ¶
func (*Client) AdminSetStrengthLevel ¶
func (*Client) AdminSetStrengthLevelBulk ¶
func (*Client) AdminSignup ¶
func (*Client) AdminStatus ¶
func (c *Client) AdminStatus(ctx context.Context) (*StatusDetail, error)
AdminStatus returns the detail. It needs an administrator who passed the step-up check.
func (*Client) AdminStepUp ¶
AdminStepUp reports whether the signed-in administrator has to enter a code before the Admin pages. It fails with CodeUnauthorized or CodeForbidden for anyone who is not an administrator.
func (*Client) AdminTestSMTP ¶
func (c *Client) AdminTestSMTP(ctx context.Context) (AdminResult, error)
func (*Client) AdminTwoFactorPolicy ¶
AdminTwoFactorPolicy sets who must use two-step verification: off, admins or everyone.
func (*Client) AdminVerify ¶
AdminVerify checks a code for the Admin pages. On success the proof cookie is relayed and the answer redirects to /admin.
func (*Client) AdminWorkers ¶
func (c *Client) AdminWorkers(ctx context.Context) (*WorkersPage, error)
func (*Client) ChangePassword ¶
func (c *Client) ChangePassword(ctx context.Context, userID int64, p PasswordChange) (SettingsPage, error)
ChangePassword sets a new password. The backend signs the user in again with a new session (the Set-Cookie is relayed) and answers with the settings page data, since the old session is gone.
func (*Client) ConnectIntegration ¶
func (c *Client) ConnectIntegration(ctx context.Context, userID int64, provider string) (string, error)
ConnectIntegration starts the OAuth flow. The backend sets the state cookie (relayed); the result is the provider's authorize URL.
func (*Client) CreateDexaScan ¶
func (*Client) CreateScaleReading ¶
func (c *Client) CreateScaleReading(ctx context.Context, userID int64, rd models.ScaleReading) error
CreateScaleReading stores a manual reading. The backend checks the values again.
func (*Client) CreateToken ¶
CreateToken creates an access token and returns it. It is shown once and never stored in clear.
func (*Client) DeleteDexaScan ¶
func (*Client) DeletePasskey ¶
func (c *Client) DeletePasskey(ctx context.Context, userID int64, cred, current string) (string, error)
DeletePasskey removes a passkey. The answer is the message to show, whether it was removed or not.
func (*Client) DeleteScaleReading ¶
func (*Client) DeleteStrengthLevelLogin ¶
DeleteStrengthLevelLogin removes the stored login and stops a running sync.
func (*Client) DeleteToken ¶
DeleteToken revokes one of the user's access tokens.
func (*Client) DisconnectIntegration ¶
func (c *Client) DisconnectIntegration(ctx context.Context, userID int64, provider string) (Flash, error)
DisconnectIntegration removes the user's link to the provider.
func (*Client) Do ¶
Do sends in (JSON-encoded unless nil) and decodes the answer into out (unless nil). An error status from the backend is returned as *Error; a failure to reach it as ErrUnavailable.
func (*Client) EstimatesPage ¶
EstimatesPage returns the data of the estimates page. With days > 0 the result holds only the days within that many days of the newest one (estimate.WithinDays) and all the calibrations; 0 means every day.
func (*Client) FrontendConfig ¶
FrontendConfig fetches the configuration. If etag is the tag of the answer last seen and nothing changed, it returns (nil, etag, nil).
func (*Client) Import ¶
Import fetches the provider's measurements now. day (YYYY-MM-DD) limits it to one day. The message summarises the result or the failure.
func (*Client) IntegrationCallback ¶
func (c *Client) IntegrationCallback(ctx context.Context, provider, state, code, providerError string) (Flash, error)
IntegrationCallback completes the OAuth flow with what the provider sent back.
func (*Client) LoginSecondStep ¶
LoginSecondStep checks the code of a sign-in.
func (*Client) LoginSecondStepPage ¶
func (c *Client) LoginSecondStepPage(ctx context.Context) (SecondStep, error)
LoginSecondStepPage asks what the verification page shows. The sealed state cookie comes from the visitor's request.
func (*Client) LoginSetup ¶
LoginSetup confirms the required setup of two-step verification with a first code.
func (*Client) LoginSetupPage ¶
func (c *Client) LoginSetupPage(ctx context.Context) (SecondStep, error)
LoginSetupPage asks what the required setup page shows.
func (*Client) PasskeyLoginBegin ¶
PasskeyLoginBegin starts a passkey sign-in and returns the WebAuthn options for the browser.
func (*Client) PasskeyLoginFinish ¶
PasskeyLoginFinish forwards the browser's assertion unchanged. The session cookies are relayed.
func (*Client) PasskeyRegisterBegin ¶
func (c *Client) PasskeyRegisterBegin(ctx context.Context, userID int64, name, current string) (json.RawMessage, error)
PasskeyRegisterBegin starts adding a passkey and returns the WebAuthn options. current is the password, when the account has one.
func (*Client) PasskeyRegisterFinish ¶
func (c *Client) PasskeyRegisterFinish(ctx context.Context, userID int64, body io.Reader) (SignInOutcome, error)
PasskeyRegisterFinish forwards the browser's attestation unchanged and returns where to go.
func (*Client) ProviderCallback ¶
func (c *Client) ProviderCallback(ctx context.Context, slug string, params map[string]string) (SignInOutcome, error)
ProviderCallback finishes a sign-in or a linking with every query and form parameter the provider sent back (Apple answers with a cross-site form post).
func (*Client) ProviderStart ¶
func (c *Client) ProviderStart(ctx context.Context, slug string, link bool, current string) (SignInOutcome, error)
ProviderStart begins a sign-in with an external provider, or (link set, for a signed-in visitor) linking it to the account, which needs the current password. The outcome's Redirect is the provider's address; the sealed state cookie travels in the relayed Set-Cookie headers.
func (*Client) Raw ¶
func (c *Client) Raw(ctx context.Context, method, path string, body io.Reader, header http.Header) (*http.Response, error)
Raw sends a request and returns the response unread, for streamed bodies such as exports. Status codes of 400 and above are not turned into errors; the caller owns resp.Body. Set-Cookie headers are relayed.
func (*Client) RenamePasskey ¶
RenamePasskey renames one of the user's passkeys.
func (*Client) Reset ¶
func (c *Client) Reset(ctx context.Context, token, password, confirm, code string) (ResetStep, error)
Reset sets a new password with a reset token (and a code when the account has two-step verification).
func (*Client) ResetForgot ¶
ResetForgot asks for a reset e-mail. It answers the same whoever the address belongs to.
func (*Client) ResetForgotPage ¶
ResetForgotPage reports whether people can ask for a reset e-mail (else it is a not found error).
func (*Client) ResetFormPage ¶
ResetFormPage checks a reset token and tells which form to show.
func (*Client) SaveHiddenColumns ¶
SaveHiddenColumns stores which columns of the daily table are hidden.
func (*Client) SaveProfile ¶
SaveProfile stores the profile.
func (*Client) SaveSettings ¶
SaveSettings stores the estimation settings.
func (*Client) SaveStrengthLevelLogin ¶
func (c *Client) SaveStrengthLevelLogin(ctx context.Context, userID int64, email, password string) (Flash, error)
SaveStrengthLevelLogin checks and stores the user's Strength Level login.
func (*Client) ScalePage ¶
ScalePage returns the page of readings before the cursor (empty: the newest).
func (*Client) SendStrengthLevelDay ¶
SendStrengthLevelDay sends one day's estimate to Strength Level.
func (*Client) Session ¶
Session returns the user behind the visitor's session cookie, or nil if nobody is signed in.
func (*Client) SettingsPage ¶
SettingsPage returns the data of the settings page. msg is the flash message of the request; the Strength Level card shows it.
func (*Client) Signup ¶
func (c *Client) Signup(ctx context.Context, name, email, password, confirm string) (SignInOutcome, error)
Signup creates an account with a password.
func (*Client) StartStrengthLevelSync ¶
func (c *Client) StartStrengthLevelSync(ctx context.Context, userID int64, days string, update bool) (Flash, error)
StartStrengthLevelSync starts the multi-day sync. days is the raw form value.
func (*Client) StrengthLevelStatus ¶
StrengthLevelStatus returns the latest sync job, or nil when there has been none.
func (*Client) TwoFactorBegin ¶
func (c *Client) TwoFactorBegin(ctx context.Context, userID int64, current string) (TwoFactorChange, error)
TwoFactorBegin starts the setup and returns the secret to show. current is the password.
func (*Client) TwoFactorConfirm ¶
func (c *Client) TwoFactorConfirm(ctx context.Context, userID int64, code string) (TwoFactorChange, error)
TwoFactorConfirm checks the first code and turns two-step verification on.
func (*Client) TwoFactorDisable ¶
TwoFactorDisable turns two-step verification off.
func (*Client) TwoFactorRecovery ¶
func (c *Client) TwoFactorRecovery(ctx context.Context, userID int64, current, code string) (TwoFactorChange, error)
TwoFactorRecovery replaces the recovery codes and returns the new ones.
type Error ¶
type Error struct {
Status int `json:"status"`
Code string `json:"code"`
Message string `json:"message"`
}
Error is an error answered by the backend. Message is fit to show to the person.
type EstimatesPage ¶
type EstimatesPage struct {
Result estimate.Result `json:"result"`
Withings *IntegrationView `json:"withings"`
SLReady bool `json:"sl_ready"`
}
EstimatesPage is the data the estimates page needs besides the user: the estimates, the state of the Withings integration and whether the single-day Strength Level button is shown.
type Flash ¶
Flash is the outcome of an action that ends with a message on a page. UserID is set where the backend, not the request path, says whose page it is (the OAuth callback).
type FrontendConfig ¶
type FrontendConfig struct {
// Generation changes with every change to the settings.
Generation int64 `json:"generation"`
Version string `json:"version"`
BaseURL string `json:"base_url,omitempty"`
TrustedProxies []string `json:"trusted_proxies,omitempty"` // prefixes in CIDR form
ProxyProtocol bool `json:"proxy_protocol"`
TLSMode string `json:"tls_mode"` // off, upload or selfsigned
CertPEM string `json:"cert_pem,omitempty"`
KeyPEM string `json:"key_pem,omitempty"` // only over the authenticated internal link
HTTPSPort string `json:"https_port,omitempty"`
HTTP3 bool `json:"http3"`
// Analytics are the optional measuring and ad services an administrator turned on. The frontend
// loads them, after a visitor agrees, on the public pages only.
Analytics Analytics `json:"analytics"`
}
FrontendConfig is what the frontend process needs from the administrator settings to serve visitors: who its trusted proxies are, its public address, and the TLS material for the HTTPS and HTTP/3 listeners it owns.
type IntegrationView ¶
type IntegrationView struct {
Configured bool // the server has the provider's credentials
Connected bool // the user has linked their account
// AutoPaused is why automatic runs for the user were paused after repeated failures; empty when they are not.
AutoPaused string
}
IntegrationView is the state of an OAuth integration for the current user.
type KeyView ¶
type KeyView struct {
Shown bool
ID string
Since string // date the key was introduced, at least; empty when unknown
AgeDays int
Due bool // older than the reminder
Rekey bool // the database still belongs to a previous key
}
KeyView describes the encryption key on the Admin page.
type LinkedProvider ¶
type LoginPage ¶
type LoginPage struct {
PasswordEnabled bool
SignupOpen bool
FirstUser bool
Providers []LoginProvider
CanReset bool // people can ask for a reset e-mail
Passkeys bool // the browser can use passkeys here
}
LoginPage is what the sign-in page shows.
type LoginProvider ¶
type LoginProvider struct{ Slug, Label string }
LoginProvider is a way of signing in through an external provider.
type NewTokenRequest ¶
type NewTokenRequest struct {
Name string `json:"name"`
Expires string `json:"expires"` // days, "never" or empty
Current string `json:"current"`
}
NewTokenRequest is the create-token form.
type PasskeyItem ¶
type PasskeyItem struct {
ID, Name, Created, LastUsed string
}
type PasskeysView ¶
type PasskeysView struct {
Ready bool // the browser can use passkeys here: HTTPS or localhost
Items []PasskeyItem
}
PasskeysView is the passkey section of the settings page.
type PasswordChange ¶
type PasswordChange struct {
Current string `json:"current"`
Password string `json:"password"`
Confirm string `json:"confirm"`
}
PasswordChange is the change-password form.
type Profile ¶
type Profile struct {
Name string `json:"name"`
Email string `json:"email"`
Timezone string `json:"timezone"`
HeightCm string `json:"height_cm"`
Current string `json:"current"`
}
Profile is the profile form of the settings page, as typed. The backend validates every field again; Current is the current password, asked for when the e-mail address changes.
type ProviderForm ¶
type ProviderForm struct {
Slug, Label, Kind, Issuer, AuthURL, TokenURL, UserinfoURL, ClientID, ClientSecret string
AppleTeamID, AppleKeyID, Scopes, SubjectClaim, NameClaim string
AllowSignup bool
}
ProviderForm is the text of the provider form, as typed.
type Request ¶
type Request struct {
Cookie string
ClientIP string
Host string
Secure bool
// Relay receives the Set-Cookie headers the backend answers with. May be nil.
Relay http.ResponseWriter
}
Request describes the visitor's request for one call. Build it with FromRequest.
type ResetLink ¶
type ResetLink struct {
For string
URL string
Expires string
Emailed bool
Warning bool // made from the request's host, which the request controls
}
ResetLink is the one-time link shown to the administrator who made it.
type ResetStep ¶
type ResetStep struct {
Redirect string `json:"redirect,omitempty"`
Mode string `json:"mode,omitempty"` // "forgot", "sent", "form" or "invalid"
Error string `json:"error,omitempty"`
NeedsCode bool `json:"needs_code,omitempty"` // the account has two-step verification
Status int `json:"status,omitempty"` // HTTP status of the page; 200 when zero
}
ResetStep is what a reset page shows, or where to go on.
type SLView ¶
type SLView struct {
UserID int64
Saved bool
Email string // the saved login's e-mail address; the password is never sent back
Msg string
Bulk bool // the multi-day sync is allowed
// AutoPaused is why automatic syncs for the user were paused after repeated failures; empty when they are not.
AutoPaused string
Job *SLJobView // the latest multi-day sync, if any
}
SLView is the Strength Level card of the settings page.
type ScalePage ¶
type ScalePage struct {
Readings []models.ScaleReading `json:"readings"`
// Next is the cursor of the next (older) page; empty on the last page.
Next string `json:"next,omitempty"`
}
ScalePage is one page of a user's scale readings, newest first.
type SecondStep ¶
type SecondStep struct {
Redirect string `json:"redirect,omitempty"`
Status int `json:"status,omitempty"` // HTTP status of the page; 200 when zero
Mode string `json:"mode,omitempty"`
Error string `json:"error,omitempty"`
QR string `json:"qr,omitempty"` // SVG made by the backend
Secret string `json:"secret,omitempty"`
Codes []string `json:"codes,omitempty"` // recovery codes, shown once
Continue string `json:"continue,omitempty"`
}
SecondStep is the answer to a request of the second step of signing in. Either Redirect is set, or the page described by Mode ("verify", "setup" or "codes") is to be shown with Status. When a step finished a sign-in the backend already set the session cookies; the frontend relays them.
type SecurityView ¶
type SecurityView struct {
Activity []AuditLine // the latest events about this account
PasswordEnabled bool
HasPassword bool
ConfirmPassword bool // sensitive changes ask for the current password
Tokens []TokenView
NewToken string // shown once, right after it was created
Linked []LinkedProvider
TwoFactor TwoFactorSettings
Passkeys PasskeysView
}
SecurityView is the settings page's sign-in section.
type ServerForm ¶
type ServerForm struct {
BaseURL, TrustedProxies, AuditDays, KeyReminderDays string
ProxyProtocol bool
}
ServerForm is the text of the server settings form, as typed.
type ServerSettingsView ¶
type ServerSettingsView struct {
BaseURL string
TrustedProxies string
ProxyProtocol bool
AuditDays string
KeyReminderDays string
}
ServerSettingsView is the stored text of the network and retention settings.
type SessionUser ¶
type SessionUser struct {
models.User
HiddenColumns []string `json:"hidden_columns"`
StrengthLevelAuto bool `json:"strength_level_auto"`
StrengthLevelBulk bool `json:"strength_level_bulk"`
DataVersion int64 `json:"data_version"`
}
SessionUser is the signed-in user as the frontend needs it. models.User leaves some fields out of its JSON form on purpose (they are not part of the public API), so the internal API carries them here.
func NewSessionUser ¶
func NewSessionUser(u models.User) SessionUser
NewSessionUser copies a user for the wire.
func (SessionUser) Model ¶
func (s SessionUser) Model() models.User
Model returns the user with every field filled in again.
type Settings ¶
type Settings struct {
AthleteDefault bool `json:"athlete_default"`
MethodRanking []string `json:"method_ranking"`
}
Settings is the estimation settings a user can save: whether new readings default to athlete mode and the method ranking, best first.
type SettingsPage ¶
type SettingsPage struct {
Withings *IntegrationView
StrengthLevel *SLView
Security *SecurityView
}
SettingsPage is the data the settings page needs besides the user.
type SignInOutcome ¶
type SignInOutcome struct {
Redirect string `json:"redirect,omitempty"`
Error string `json:"error,omitempty"` // fit to show on the sign-in page
Status int `json:"status,omitempty"` // HTTP status to show it with
}
SignInOutcome is the answer to a step of signing in. Exactly one of Redirect and Error is set. When the step succeeded the backend already set the session (or second-step) cookies, and the frontend relays them with the redirect.
type Status ¶
type Status struct {
CheckedAt string // UTC, when the backend last checked (it keeps an answer for a few seconds)
Components []StatusComponent
}
Status is the summary everybody may see.
type StatusComponent ¶
type StatusComponent struct {
Name string // a stable key: web, api, database, body, valkey, workers.<provider>
Label string
State string
}
StatusComponent is one part of the deployment.
type StatusDetail ¶
type StatusDetail struct {
Status
Notes map[string]string // component name to the reason it is not up
Workers []StatusWorker
}
StatusDetail is the summary plus what only administrators see.
type StatusWorker ¶
type StatusWorker struct {
ID string
Version string
Kinds []string
LastSeen string
Live bool // asked for work recently enough to count as running
}
StatusWorker is a worker process, for administrators.
type TLSView ¶
type TLSView struct {
Mode string // off, upload or selfsigned
Names string // names for a self-signed certificate, as typed
Active bool // a certificate is in force
Subject string
CertNames string
NotAfter string
Fingerprint string
HTTP3 bool
HTTP3Active bool
Port string
}
TLSView is the secure connections section, without what only the frontend knows (whether its listener could bind).
type TwoFactorChange ¶
type TwoFactorChange struct {
Error string `json:"error,omitempty"`
Status int `json:"status,omitempty"`
Setup *TwoFactorSetup `json:"setup,omitempty"`
Codes []string `json:"codes,omitempty"`
}
TwoFactorChange is the answer to a change of two-step verification on the settings page. A refusal that needs the setup shown again (a wrong first code) is Error with Status and Setup; other refusals are errors. Codes are the recovery codes, shown once.
type TwoFactorSettings ¶
type TwoFactorSettings struct {
Available bool // the user signs in with a password, so there is something to protect
Enabled bool
Required bool // an administrator requires it for this user
RecoveryLeft int
Setup *TwoFactorSetup
NewCodes []string // shown once
}
TwoFactorSettings is the two-step part of the settings page.
type TwoFactorSetup ¶
TwoFactorSetup is a secret waiting to be confirmed.
type WithingsForm ¶
WithingsForm is the text of the Withings credentials form.
type WorkerInstanceView ¶
WorkerInstanceView is a worker process that asked for work recently.
type WorkerJobView ¶
type WorkerJobView struct {
ID string
Kind string
User string
UserID int64
Priority int
UserIsAdmin bool
State string
Origin string
Attempts int
MaxAttempts int
Error string
Created string
Updated string
Active bool // can still be canceled
}
WorkerJobView is a job in the list on the Admin page.
type WorkerKindForm ¶
type WorkerKindForm struct {
Enabled bool
MaxRunning int
MaxAttempts int
RetryBaseSeconds int
TimeoutSeconds int
ScheduleHours int
PauseAfter int
Breaker int
Options map[string]int
}
WorkerKindForm is what an administrator saves for a kind.
type WorkerKindView ¶
type WorkerKindView struct {
Kind string
Label string
// Enabled is false when an administrator (or the circuit breaker, see PausedReason) paused it.
Enabled bool
PausedReason string
MaxRunning int // at once in all workers together; 0 is no limit
MaxAttempts int
RetryBaseSeconds int
TimeoutSeconds int
ScheduleHours int // 0: no automatic runs
PauseAfter int
Breaker int
Schedulable bool
Options []WorkerOptionView
Queued int
Running int
Failed24h int
WorkersOnline int
PausedSchedules int // users whose automatic runs are paused
}
WorkerKindView is one kind of job: its settings and what is going on.
type WorkerOptionView ¶
type WorkerOptionView struct {
Name string
Label string
Value int
Min, Max int
Millis bool // shown in milliseconds
}
WorkerOptionView is a whole-number option of a kind that is sent to its workers.
type WorkerProviderView ¶
type WorkerProviderView struct {
Name string
Label string
Kinds []WorkerKindView
}
WorkerProviderView groups the kinds of one provider.
type WorkersGlobalForm ¶
WorkersGlobalForm is what an administrator saves for all workers.
type WorkersPage ¶
type WorkersPage struct {
Providers []WorkerProviderView
Workers []WorkerInstanceView
Jobs []WorkerJobView
DefaultPriority int
KeepHistoryDays int
}
WorkersPage is everything the workers section of the Admin page shows.