Help us shape the future of Go! Take the 2026 Go Developer Survey

contract

package
v1.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 32 Imported by: 0

Documentation

Overview

Package contract wires authsome into the Forge dashboard's contract path. It registers the `auth` contributor with the dashboard's contract registry, and declares the auth.* intents the React plugin calls, including the auth.login + auth.logout commands behind its login gate.

This is authsome's only dashboard surface. The extension's RegisterDashboardAuth installs the AuthChecker that /principal answers from; auth.login here writes the auth_token cookie that checker reads.

handlers_apps.go: Phase C.2 — Apps dashboard.

Wraps engine.{List,Get,Create,Update,Delete}App. Apps are the top-level multi-tenancy unit in authsome; the dashboard surfaces them so platform admins can manage tenants without dropping into SQL. Pattern mirrors handlers_users.go.

handlers_auth_pages.go: Phase C.14 — anonymous auth pages.

Six intents the dashboard's AuthGate dispatches before a session exists:

  • auth.signup public registration via engine.SignUp
  • auth.forgotPassword request a reset link (always returns OK)
  • auth.resetPassword consume a reset token + set new password
  • auth.setupStatus query: does any admin user exist yet?
  • auth.setup first-run bootstrap: create the first user
  • auth.dynamicConfig query: per-app dynamic signup form
  • auth.dynamicRegister signup with form-config-driven metadata

On success, auth.signup / auth.setup / auth.dynamicRegister write the new session cookie via the same helper as auth.login so the principal endpoint reflects the new session on the next call. auth.forgotPassword always succeeds at the wire level even when the email doesn't exist (account enumeration prevention).

handlers_context.go: Phase C.17 — App + environment switcher.

Three intents back the dashboard's switcher chrome:

  • apps.context (query): returns the active app + environment plus the lists of available choices. The shell renders the switcher dropdowns from this single query and re-fetches after a successful switch command.
  • apps.switch (command): persists the active app by writing an `authsome_app` cookie. Subsequent requests carry the cookie; AppIDFromPrincipal reads it via the principal claims (set server-side by the dashboard's auth resolver).
  • environments.switch (command): same shape, writes `authsome_env` with the environment ID.

Switch commands deliberately do NOT validate that the user has access to the chosen app/env. Access control runs at intent dispatch time (each handler uses AppIDFromPrincipal which short- circuits to the platform app when the claim is invalid), so an attacker setting an arbitrary cookie sees an empty result set rather than data they shouldn't have.

handlers_credentials.go: Phase C.13 — Credentials dashboard.

The credentials page surfaces the SDK-facing identifiers for the platform app: publishable key (safe client-side), app metadata (name/slug/ID), and the active environment. There's no rotate-secret command yet — App rows don't carry a client secret on the authsome.App struct itself; secret-key issuance lives on the apikeys surface. When the engine grows a publishable-key rotation method, add credentials.rotatePublishableKey here and bind to a confirm dialog in the manifest.

handlers_devices.go: Phase C.6 — Devices dashboard.

handlers_environments.go: Phase C.7 — Environments dashboard.

handlers_features.go: app-level feature toggles backed by appclientconfig.Config.

The templui dashboard surfaced a "Sign-in Methods" panel with toggles for password / social / passkey / magiclink / mfa / sso / signup / waitlist / require-email-verification. This is the contract equivalent: a single query + command pair that lets the dashboard render switches for every feature the engine supports without having to special-case each one.

Toggles are app-scoped — they write the per-app appclientconfig.Config overrides, falling back to "enabled if the underlying plugin is installed" (password is always available; the rest depend on a plugin being registered).

handlers_formconfigs.go: Phase C.9 — Form Configs dashboard.

Surfaces signup-form customization to the dashboard. Today the engine only ships SignupFormConfig methods; other form types can layer on later.

handlers_overview.go: Phase C.12 — Overview dashboard.

overview.stats returns the four counters the dashboard.grid widgets surface (users, active sessions, devices, plugins) in a single payload so the React shell makes one request rather than four. overview.recentSignups returns the top-N most recently created users for the dashboard.recentlist widget.

handlers_roles.go: Phase C.4 — Roles & RBAC dashboard.

handlers_sessions.go: Phase C.3 — Sessions dashboard.

sessions.list takes a userID (typically supplied by the parent users row when the page is rendered as a drill-down). For the standalone /sessions index page, callers pass the userID explicitly or leave blank to receive an empty list — the engine doesn't expose a global session listing.

handlers_settings.go: Phase C.10 + D.2.5 — Settings dashboard.

The settings.* surface is what the dashboard's settings.tabs and settings.panel renderers consume. Three queries return progressively richer projections of the settings system:

  • settings.namespaces: the list of plugin namespaces with display names and counts. Drives the top-level tab strip.
  • settings.namespace: the full grouped tree for one namespace, including Definition metadata, the effective value at the selected scope, override / enforced flags, and UIMetadata. Drives the per-tab settings.panel.
  • settings.list: (deprecated) flat list of definitions, kept for one release for any callers still bound to it.
  • settings.detail: (deprecated) raw resolved value for one key. Replaced by the richer settings.namespace projection.

Three commands cover writes:

  • settings.update: scope-aware write of a single setting.
  • settings.enforce: lock a setting value at a scope so lower scopes cannot override.
  • settings.unenforce: release a previously-enforced setting.

handlers_users.go: Phase C.1 of the authsome dashboard port.

Implements the users.* intent surface the React shell binds in its /users page (list + detail drawer + row actions) and /users/:id + /users/create routes. Engine calls run against the platform app: admin operations are scoped to whichever app authsome considers "platform" at handler time (PlatformAppID, with a fallback to the engine config's AppID). The principal's subject becomes the admin actor recorded by the engine's hooks + audit emitter.

handlers_webhooks.go: Phase C.8 — Webhooks dashboard.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppIDFromPrincipal

func AppIDFromPrincipal(p contract.Principal, eng *authsome.Engine) id.AppID

AppIDFromPrincipal resolves the active app ID a plugin handler should scope its query to, given the request principal. Plugins reuse this helper instead of reimplementing the app-resolution lookup so that templui's dashboard.AppIDFromContext semantics carry over to the contract path: prefer an explicit app claim on the principal (when the dashboard's app switcher has set one), falling back to the engine's platform app.

Exported so plugin contract packages can call it. Plugins should receive the engine via their own Deps struct rather than referencing the auth contributor's deps directly.

func Register

func Register(
	d *dispatcher.Dispatcher,
	reg contract.Registry,
	wreg contract.WardenRegistry,
	deps Deps,
) error

Register loads the embedded manifest, validates it, registers the `auth` contributor with reg, and binds the contract handlers against d. The dashboard's auto-discovery calls this via Extension.RegisterContractContributor.

Types

type AckResponse

type AckResponse struct {
	OK bool   `json:"ok"`
	ID string `json:"id,omitempty"`
}

AckResponse is the canonical reply for mutating commands that don't project a payload of their own — the shell's react-query invalidator flips the list query stale and the table refetches automatically.

type AppContextResponse

type AppContextResponse struct {
	// CurrentApp is the active app the principal is scoped to. May be
	// nil for unauthenticated requests or when no platform app exists.
	CurrentApp *SwitcherApp `json:"currentApp,omitempty"`
	// CurrentEnv is the active environment (when set via cookie).
	CurrentEnv *SwitcherEnv `json:"currentEnv,omitempty"`
	// AvailableApps is the global list of apps the switcher renders.
	// Filtering by user permissions can land in a later iteration.
	AvailableApps []SwitcherApp `json:"availableApps"`
	// AvailableEnvs is the list of environments for the current app.
	AvailableEnvs []SwitcherEnv `json:"availableEnvs"`
}

AppContextResponse is the apps.context query shape. Field names match the React shell's switcher hook bindings — renames are wire breaks.

type AppDetail

type AppDetail struct {
	AppSummary
	PublishableKey string            `json:"publishableKey,omitempty"`
	Metadata       map[string]string `json:"metadata,omitempty"`
	UpdatedAt      string            `json:"updatedAt"`
}

type AppListResponse

type AppListResponse struct {
	Apps []AppSummary `json:"apps"`
}

type AppSummary

type AppSummary struct {
	ID         string `json:"id"`
	Name       string `json:"name"`
	Slug       string `json:"slug"`
	IsPlatform bool   `json:"isPlatform"`
	CreatedAt  string `json:"createdAt"`
}

type AppSwitchInput

type AppSwitchInput struct {
	AppID string `json:"appId,omitempty"`
}

AppSwitchInput / EnvSwitchInput are the wire shapes for the switch commands. The empty-string sentinel clears the cookie (resets to the default app/env).

type AssignRoleInput

type AssignRoleInput struct {
	UserID string `json:"userId"`
	RoleID string `json:"roleId"`
}

type AuthConfigResponse

type AuthConfigResponse struct {
	Brand           string                 `json:"brand,omitempty"`
	BrandLogoURL    string                 `json:"brandLogoURL,omitempty"`
	PasswordEnabled bool                   `json:"passwordEnabled"`
	SignupURL       string                 `json:"signupURL,omitempty"`
	SignupLabel     string                 `json:"signupLabel,omitempty"`
	TermsURL        string                 `json:"termsURL,omitempty"`
	PrivacyURL      string                 `json:"privacyURL,omitempty"`
	SocialProviders []SocialProviderConfig `json:"socialProviders,omitempty"`
}

AuthConfigResponse is what the React shell's AuthLoginForm reads to build the login UI. The shape mirrors shadcn's login-04 block: brand lockup, signup link, terms/privacy footer, password block (toggled by PasswordEnabled), and a list of social provider buttons. The shell renders the buttons in source order.

type BanUserInput

type BanUserInput struct {
	ID        string `json:"id"`
	Reason    string `json:"reason,omitempty"`
	ExpiresAt string `json:"expiresAt,omitempty"`
}

BanUserInput is the wire shape for users.ban. ExpiresAt is RFC3339; empty means an indefinite ban.

type BulkRevokeResponse

type BulkRevokeResponse struct {
	OK    bool `json:"ok"`
	Count int  `json:"count"`
}

type BulkRevokeSessionsInput

type BulkRevokeSessionsInput struct {
	UserID string `json:"userId"`
}

type CloneEnvInput

type CloneEnvInput struct {
	SourceID string `json:"sourceId"`
	Name     string `json:"name"`
	Slug     string `json:"slug"`
	Type     string `json:"type,omitempty"`
}

type CreateAppInput

type CreateAppInput struct {
	Name string `json:"name"`
	Slug string `json:"slug"`
}

type CreateEnvInput

type CreateEnvInput struct {
	Name        string `json:"name"`
	Slug        string `json:"slug"`
	Type        string `json:"type,omitempty"`
	Description string `json:"description,omitempty"`
	Color       string `json:"color,omitempty"`
}

type CreateRoleInput

type CreateRoleInput struct {
	Name        string `json:"name"`
	Slug        string `json:"slug"`
	Description string `json:"description,omitempty"`
}

type CreateUserInput

type CreateUserInput struct {
	Email     string `json:"email"`
	Password  string `json:"password"`
	FirstName string `json:"firstName,omitempty"`
	LastName  string `json:"lastName,omitempty"`
	Username  string `json:"username,omitempty"`
}

CreateUserInput is the wire shape for users.create. Username is optional; FirstName/LastName are recommended but not required by the engine. Password is validated against the engine's password policy.

type CreateWebhookInput

type CreateWebhookInput struct {
	URL    string   `json:"url"`
	Events []string `json:"events"`
}

type CredentialsDetail

type CredentialsDetail struct {
	AppID          string `json:"appId"`
	AppName        string `json:"appName"`
	AppSlug        string `json:"appSlug"`
	PublishableKey string `json:"publishableKey,omitempty"`
	EnvID          string `json:"envId,omitempty"`
	EnvName        string `json:"envName,omitempty"`
	EnvSlug        string `json:"envSlug,omitempty"`
	IsPlatform     bool   `json:"isPlatform"`
}

CredentialsDetail is the credentials.detail response. Field names are the React shell's resource.detail bindings — renames are wire breaks.

type DeleteAppInput

type DeleteAppInput struct {
	ID string `json:"id"`
}

type DeleteDeviceInput

type DeleteDeviceInput struct {
	ID string `json:"id"`
}

type DeleteEnvInput

type DeleteEnvInput struct {
	ID string `json:"id"`
}

type DeleteRoleInput

type DeleteRoleInput struct {
	ID string `json:"id"`
}

type DeleteSignupFormInput

type DeleteSignupFormInput struct{}

type DeleteUserInput

type DeleteUserInput struct {
	ID string `json:"id"`
}

type DeleteWebhookInput

type DeleteWebhookInput struct {
	ID string `json:"id"`
}

type Deps

type Deps struct {
	// Engine is the live authsome engine. Required.
	Engine *authsome.Engine

	// CookieSecure overrides the auto-detected request scheme when an
	// upstream proxy strips it (rare — leave zero in production behind a
	// TLS-aware reverse proxy).
	CookieSecure *bool

	// SocialBasePath overrides the URL prefix for social OAuth start
	// endpoints. Defaults to "/v1/social" matching the social plugin's
	// default route registration.
	SocialBasePath string

	// Brand / BrandLogoURL override the platform app's name + logo on the
	// /login page. When empty the values fall back to App.Name / App.Logo
	// resolved at handler time.
	Brand        string
	BrandLogoURL string

	// SignupURL is the public-facing /signup link rendered above the login
	// form. Empty hides the "Don't have an account? Sign up" line.
	SignupURL   string
	SignupLabel string

	// TermsURL / PrivacyURL feed the legal footer beneath the form.
	// Both empty hides the footer entirely.
	TermsURL   string
	PrivacyURL string

	// RequiredRoles, if non-empty, gates dashboard access to users carrying
	// at least one matching role. Authsome calls Extension.SetRequiredRoles
	// with these values in RegisterDashboardAuth so the principal endpoint
	// returns 403 PERMISSION_DENIED to anyone without them.
	RequiredRoles []string
}

Deps bundles what the contract handlers need at registration time. Engine is required; everything else is optional UI/operational tuning.

type DeviceListInput

type DeviceListInput struct {
	UserID string `json:"userId,omitempty"`
	Limit  int    `json:"limit,omitempty"`
}

DeviceListInput optionally narrows the list to a single user; this is how the rich user-detail page's embedded devices table binds (params: { userId: { from: route.id } }). When unset the handler returns the global recent-devices window.

type DeviceListResponse

type DeviceListResponse struct {
	Devices []DeviceSummary `json:"devices"`
}

type DeviceSummary

type DeviceSummary struct {
	ID         string `json:"id"`
	UserID     string `json:"userId"`
	Name       string `json:"name,omitempty"`
	Type       string `json:"type,omitempty"`
	Browser    string `json:"browser,omitempty"`
	OS         string `json:"os,omitempty"`
	IPAddress  string `json:"ipAddress,omitempty"`
	Trusted    bool   `json:"trusted"`
	LastSeenAt string `json:"lastSeenAt"`
	CreatedAt  string `json:"createdAt"`
}

type DynamicConfigResponse

type DynamicConfigResponse struct {
	Title       string                 `json:"title,omitempty"`
	Description string                 `json:"description,omitempty"`
	Fields      []formconfig.FormField `json:"fields,omitempty"`
	Active      bool                   `json:"active"`
}

DynamicConfigResponse is returned by auth.dynamicConfig. Fields are the FieldSpec list the auth.dynamic-signup-form renderer feeds into organism.dynamic-form.

type DynamicRegisterInput

type DynamicRegisterInput struct {
	Email    string            `json:"email"`
	Password string            `json:"password"`
	Name     string            `json:"name,omitempty"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

DynamicRegisterInput is the wire shape for auth.dynamicRegister. Standard fields go in the top-level slots; everything else flows through Metadata so the engine writes it onto User.Metadata.

type EnforceSettingInput

type EnforceSettingInput struct {
	Key    string          `json:"key"`
	Value  json.RawMessage `json:"value"`
	Scope  string          `json:"scope"`
	AppID  string          `json:"appId,omitempty"`
	OrgID  string          `json:"orgId,omitempty"`
	UserID string          `json:"userId,omitempty"`
}

EnforceSettingInput targets a specific (scope, scopeID) and locks the setting there so lower scopes cannot override.

type EnvDetail

type EnvDetail struct {
	EnvSummary
	AppID       string            `json:"appId,omitempty"`
	Color       string            `json:"color,omitempty"`
	Description string            `json:"description,omitempty"`
	ClonedFrom  string            `json:"clonedFrom,omitempty"`
	Metadata    map[string]string `json:"metadata,omitempty"`
	UpdatedAt   string            `json:"updatedAt"`
}

type EnvListResponse

type EnvListResponse struct {
	Environments []EnvSummary `json:"environments"`
}

type EnvSummary

type EnvSummary struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Slug      string `json:"slug"`
	Type      string `json:"type"`
	IsDefault bool   `json:"isDefault"`
	CreatedAt string `json:"createdAt"`
}

type EnvSwitchInput

type EnvSwitchInput struct {
	EnvID string `json:"envId,omitempty"`
}

type FeatureToggle

type FeatureToggle struct {
	Key         string `json:"key"`
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
	Enabled     bool   `json:"enabled"`
	// Available reports whether the underlying plugin is registered
	// (password is always available regardless). The renderer should
	// disable / dim the row when Available is false so admins
	// understand why the toggle won't take effect.
	Available bool `json:"available"`
}

FeatureToggle is the wire shape for a single row in the auth.featureToggles response.

type FeatureTogglesResponse

type FeatureTogglesResponse struct {
	Toggles []FeatureToggle `json:"toggles"`
}

type ForgotPasswordInput

type ForgotPasswordInput struct {
	Email string `json:"email"`
}

ForgotPasswordInput is the wire shape for auth.forgotPassword.

type ForgotPasswordResponse

type ForgotPasswordResponse struct {
	OK bool `json:"ok"`
}

ForgotPasswordResponse always returns ok:true to avoid leaking whether the email belongs to a real account.

type FormConfigDetail

type FormConfigDetail struct {
	FormConfigSummary
	AppID     string                 `json:"appId,omitempty"`
	Fields    []formconfig.FormField `json:"fields,omitempty"`
	UpdatedAt string                 `json:"updatedAt"`
}

type FormConfigListResponse

type FormConfigListResponse struct {
	FormConfigs []FormConfigSummary `json:"formConfigs"`
}

type FormConfigSummary

type FormConfigSummary struct {
	ID        string `json:"id"`
	FormType  string `json:"formType"`
	Version   int    `json:"version"`
	Active    bool   `json:"active"`
	CreatedAt string `json:"createdAt"`
}

type GetAppInput

type GetAppInput struct {
	ID string `json:"id"`
}

type GetDeviceInput

type GetDeviceInput struct {
	ID string `json:"id"`
}

type GetEnvInput

type GetEnvInput struct {
	ID string `json:"id"`
}

type GetRoleInput

type GetRoleInput struct {
	ID string `json:"id"`
}

type GetSessionInput

type GetSessionInput struct {
	ID string `json:"id"`
}

type GetSettingInput

type GetSettingInput struct {
	Key string `json:"key"`
}

type GetSettingResponse

type GetSettingResponse struct {
	Key   string          `json:"key"`
	Value json.RawMessage `json:"value"`
}

type GetUserInput

type GetUserInput struct {
	ID string `json:"id"`
}

GetUserInput is the wire shape for users.detail.

type GetWebhookInput

type GetWebhookInput struct {
	ID string `json:"id"`
}

type ListUsersInput

type ListUsersInput struct {
	Email  string `json:"email,omitempty"`
	Cursor string `json:"cursor,omitempty"`
	Limit  int    `json:"limit,omitempty"`
}

ListUsersInput is the wire shape for the users.list query. The React shell sends nothing today; the fields exist so the upcoming search box / pagination controls don't need a schema change.

type LoginInput

type LoginInput struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

LoginInput is the wire shape for the auth.login command. The React shell's form.edit at /login submits {email, password}; password is never echoed back, only consumed.

type LoginResponse

type LoginResponse struct {
	OK      bool   `json:"ok"`
	Subject string `json:"subject"`
}

LoginResponse is what the shell receives on success. The principal endpoint will reflect the new session on the next call so this is intentionally lean — the cookie is the load-bearing artifact.

type LogoutResponse

type LogoutResponse struct {
	OK bool `json:"ok"`
}

LogoutResponse mirrors LoginResponse.

type NamespaceInput

type NamespaceInput struct {
	Namespace string `json:"namespace"`
	Scope     string `json:"scope"`
	AppID     string `json:"appId,omitempty"`
	OrgID     string `json:"orgId,omitempty"`
	UserID    string `json:"userId,omitempty"`
}

NamespaceInput is the param shape for settings.namespace. Scope is required; the *ID fields are conditional on the scope.

type NamespaceSummary

type NamespaceSummary struct {
	Name         string `json:"name"`
	DisplayName  string `json:"displayName,omitempty"`
	Description  string `json:"description,omitempty"`
	SettingCount int    `json:"settingCount"`
}

NamespaceSummary is the row shape returned by settings.namespaces. Field names match the React shell's settings.tabs renderer — renames are wire breaks.

type NamespacesContext

type NamespacesContext struct {
	AppID  string `json:"appId,omitempty"`
	OrgID  string `json:"orgId,omitempty"`
	UserID string `json:"userId,omitempty"`
}

NamespacesContext echoes the scope IDs the caller's principal has available, letting the React shell disable scope-picker choices that can't resolve to a concrete ID.

type OverviewStats

type OverviewStats struct {
	Users    int `json:"users"`
	Sessions int `json:"sessions"`
	Devices  int `json:"devices"`
	Plugins  int `json:"plugins"`
}

OverviewStats is the overview.stats response shape. Field names match the React shell's dashboard.stat valueField bindings exactly; renames are wire breaks.

type PermissionRecord

type PermissionRecord struct {
	ID       string `json:"id"`
	Action   string `json:"action"`
	Resource string `json:"resource"`
}

type PluginSummary

type PluginSummary struct {
	Name         string `json:"name"`
	SettingCount int    `json:"settingCount"`
}

PluginSummary describes an installed Authsome plugin. Settings counts are taken from the live settings registry, not the dashboard contributors.

type PluginsListResponse

type PluginsListResponse struct {
	Plugins []PluginSummary `json:"plugins"`
}

type RecentSignupsInput

type RecentSignupsInput struct {
	Limit int `json:"limit,omitempty"`
}

RecentSignupsInput is the optional input for overview.recentSignups. Limit caps the returned slice; defaults to 10 when unset / non-positive.

type RecentSignupsResponse

type RecentSignupsResponse struct {
	Users []UserSummary `json:"users"`
}

RecentSignupsResponse is the overview.recentSignups reply. The dashboard.recentlist widget's extractor picks the first array-valued field, which is `users` — the same UserSummary shape the /users page uses, kept consistent so the recent-signups row click can deep-link to the user-detail page without a separate fetch.

type ResetPasswordInput

type ResetPasswordInput struct {
	Token    string `json:"token"`
	Password string `json:"password"`
}

ResetPasswordInput is the wire shape for auth.resetPassword. Token comes from the reset-link URL (the renderer parses it from the query string and submits it alongside the new password).

type ResetPasswordResponse

type ResetPasswordResponse struct {
	OK bool `json:"ok"`
}

ResetPasswordResponse is the auth.resetPassword reply.

type RevokeSessionInput

type RevokeSessionInput struct {
	ID string `json:"id"`
}

type RoleDetail

type RoleDetail struct {
	RoleSummary
	AppID       string             `json:"appId,omitempty"`
	EnvID       string             `json:"envId,omitempty"`
	ParentID    string             `json:"parentId,omitempty"`
	Permissions []PermissionRecord `json:"permissions,omitempty"`
	UpdatedAt   string             `json:"updatedAt"`
}

type RoleListResponse

type RoleListResponse struct {
	Roles []RoleSummary `json:"roles"`
}

type RoleSummary

type RoleSummary struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Slug        string `json:"slug"`
	Description string `json:"description,omitempty"`
	CreatedAt   string `json:"createdAt"`
}

type RotateWebhookSecretInput

type RotateWebhookSecretInput struct {
	ID string `json:"id"`
}

type SaveSignupFormInput

type SaveSignupFormInput struct {
	Fields []formconfig.FormField `json:"fields"`
	Active bool                   `json:"active"`
}

type SessionDetail

type SessionDetail struct {
	SessionSummary
	AppID                 string `json:"appId,omitempty"`
	EnvID                 string `json:"envId,omitempty"`
	OrgID                 string `json:"orgId,omitempty"`
	DeviceID              string `json:"deviceId,omitempty"`
	ImpersonatedBy        string `json:"impersonatedBy,omitempty"`
	RefreshTokenExpiresAt string `json:"refreshTokenExpiresAt,omitempty"`
	PrincipalKind         string `json:"principalKind,omitempty"`
	UpdatedAt             string `json:"updatedAt,omitempty"`
}

type SessionSummary

type SessionSummary struct {
	ID             string `json:"id"`
	UserID         string `json:"userId"`
	IPAddress      string `json:"ipAddress,omitempty"`
	UserAgent      string `json:"userAgent,omitempty"`
	LastActivityAt string `json:"lastActivityAt,omitempty"`
	ExpiresAt      string `json:"expiresAt"`
	CreatedAt      string `json:"createdAt"`
}

type SessionsListInput

type SessionsListInput struct {
	UserID string `json:"userId,omitempty"`
	Limit  int    `json:"limit,omitempty"`
}

type SessionsListResponse

type SessionsListResponse struct {
	Sessions []SessionSummary `json:"sessions"`
}

type SetDefaultEnvInput

type SetDefaultEnvInput struct {
	ID string `json:"id"`
}

type SettingCategory

type SettingCategory struct {
	Name     string         `json:"name"`
	Settings []SettingField `json:"settings"`
}

SettingCategory groups SettingFields by their Definition.Category.

type SettingDefinition

type SettingDefinition struct {
	Key         string          `json:"key"`
	Namespace   string          `json:"namespace,omitempty"`
	Type        string          `json:"type,omitempty"`
	Description string          `json:"description,omitempty"`
	Default     json.RawMessage `json:"default,omitempty"`
}

type SettingField

type SettingField struct {
	Key            string             `json:"key"`
	DisplayName    string             `json:"displayName"`
	Description    string             `json:"description,omitempty"`
	Type           string             `json:"type"`
	InputType      string             `json:"inputType,omitempty"`
	Default        json.RawMessage    `json:"default,omitempty"`
	EffectiveValue json.RawMessage    `json:"effectiveValue,omitempty"`
	IsOverridden   bool               `json:"isOverridden"`
	IsEnforced     bool               `json:"isEnforced"`
	CanOverride    bool               `json:"canOverride"`
	ReadOnly       bool               `json:"readOnly,omitempty"`
	Sensitive      bool               `json:"sensitive,omitempty"`
	Placeholder    string             `json:"placeholder,omitempty"`
	HelpText       string             `json:"helpText,omitempty"`
	Options        []SettingOption    `json:"options,omitempty"`
	Validation     *SettingValidation `json:"validation,omitempty"`
	Order          int                `json:"order"`
	Section        string             `json:"section,omitempty"`
	Scopes         []string           `json:"scopes,omitempty"`
}

SettingField is the per-field projection used inside SettingCategory. Mirrors the React shell's SettingField interface in settings.panel.tsx.

type SettingOption

type SettingOption struct {
	Label string `json:"label"`
	Value string `json:"value"`
}

type SettingValidation

type SettingValidation struct {
	Required bool   `json:"required,omitempty"`
	Min      *int   `json:"min,omitempty"`
	Max      *int   `json:"max,omitempty"`
	MinLen   int    `json:"minLen,omitempty"`
	MaxLen   int    `json:"maxLen,omitempty"`
	Pattern  string `json:"pattern,omitempty"`
}

type SettingsListResponse

type SettingsListResponse struct {
	Settings []SettingDefinition `json:"settings"`
}

type SettingsNamespaceResponse

type SettingsNamespaceResponse struct {
	Namespace   string            `json:"namespace"`
	DisplayName string            `json:"displayName,omitempty"`
	Scope       string            `json:"scope"`
	Categories  []SettingCategory `json:"categories"`
}

SettingsNamespaceResponse is the grouped tree settings.panel reads.

type SettingsNamespacesResponse

type SettingsNamespacesResponse struct {
	Namespaces []NamespaceSummary `json:"namespaces"`
	Context    NamespacesContext  `json:"context"`
}

SettingsNamespacesResponse is the top-level shape settings.tabs reads.

type SetupEnvironmentDefaults

type SetupEnvironmentDefaults struct {
	Name        string `json:"name"`
	Slug        string `json:"slug"`
	Type        string `json:"type"`
	IsDefault   bool   `json:"isDefault"`
	Color       string `json:"color,omitempty"`
	Description string `json:"description,omitempty"`
}

SetupEnvironmentDefaults contains only the public default-environment fields needed to initialize first-run setup.

type SetupEnvironmentInput

type SetupEnvironmentInput struct {
	Name        string            `json:"name"`
	Slug        string            `json:"slug"`
	Type        string            `json:"type"`
	Color       string            `json:"color,omitempty"`
	Description string            `json:"description,omitempty"`
	Metadata    map[string]string `json:"metadata,omitempty"`
}

type SetupInput

type SetupInput struct {
	Email            string                 `json:"email"`
	Password         string                 `json:"password"`
	Name             string                 `json:"name,omitempty"`
	OrganizationName string                 `json:"organizationName,omitempty"`
	Platform         *SetupPlatformInput    `json:"platform,omitempty"`
	Environment      *SetupEnvironmentInput `json:"environment,omitempty"`
}

SetupInput is the wire shape for auth.setup. Mirrors the auth.setup-form renderer's fields.

type SetupPlatformDefaults

type SetupPlatformDefaults struct {
	Name string `json:"name"`
	Slug string `json:"slug"`
}

SetupPlatformDefaults contains the public platform fields the anonymous setup form may edit. Keep this deliberately smaller than AppDetail: stored metadata and the publishable key must never cross this public boundary.

type SetupPlatformInput

type SetupPlatformInput struct {
	Name     string            `json:"name"`
	Slug     string            `json:"slug"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

type SetupResponse

type SetupResponse struct {
	OK      bool   `json:"ok"`
	Subject string `json:"subject"`
	// VerificationRequired is true while the new account's email is
	// unverified. The account becomes platform-owner when that email is
	// verified, not at sign-up: setup runs unauthenticated on a fresh
	// install, so granting it here would hand the deployment to whoever
	// reached setup first. A dashboard reads this to tell you why you
	// can't administer anything yet.
	VerificationRequired bool `json:"verification_required"`
}

SetupResponse is the auth.setup reply.

type SetupStatusResponse

type SetupStatusResponse struct {
	Pending     bool                      `json:"pending"`
	Platform    *SetupPlatformDefaults    `json:"platform,omitempty"`
	Environment *SetupEnvironmentDefaults `json:"environment,omitempty"`
}

SetupStatusResponse is returned by auth.setupStatus. Pending is true when no users exist yet — the dashboard's AuthGate uses this to redirect to /setup before /login.

type SignupInput

type SignupInput struct {
	Email    string `json:"email"`
	Password string `json:"password"`
	Name     string `json:"name,omitempty"`
}

SignupInput is the wire shape for auth.signup. Matches the auth.signup-form renderer's form fields. Name is optional in v1 — the renderer can toggle the field via `nameField: false`.

type SignupResponse

type SignupResponse struct {
	OK      bool   `json:"ok"`
	Subject string `json:"subject"`
}

SignupResponse mirrors LoginResponse — slim by design because the session cookie is the load-bearing artifact.

type SocialProviderConfig

type SocialProviderConfig struct {
	ID           string `json:"id"`
	Label        string `json:"label"`
	AuthStartURL string `json:"authStartURL"`
}

SocialProviderConfig is a single button on the login form. AuthStartURL is the absolute URL the shell POSTs to begin the OAuth flow; the upstream endpoint replies with `{auth_url}` and the shell navigates the browser there. Authsome's social plugin already exposes a compatible endpoint at /v1/social/<provider>.

type SwitchResponse

type SwitchResponse struct {
	OK bool `json:"ok"`
}

type SwitcherApp

type SwitcherApp struct {
	ID         string `json:"id"`
	Name       string `json:"name"`
	Slug       string `json:"slug"`
	IsPlatform bool   `json:"isPlatform"`
}

type SwitcherEnv

type SwitcherEnv struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Slug      string `json:"slug"`
	Type      string `json:"type,omitempty"`
	IsDefault bool   `json:"isDefault"`
}

type ToggleFeatureInput

type ToggleFeatureInput struct {
	Key     string `json:"key"`
	Enabled bool   `json:"enabled"`
}

ToggleFeatureInput is the wire shape for auth.toggleFeature. Each command flips a single key — the renderer dispatches one command per changed toggle rather than sending the whole bag.

type TrustDeviceInput

type TrustDeviceInput struct {
	ID string `json:"id"`
}

type UnassignRoleInput

type UnassignRoleInput struct {
	UserID string `json:"userId"`
	RoleID string `json:"roleId"`
}

type UnbanUserInput

type UnbanUserInput struct {
	ID string `json:"id"`
}

UnbanUserInput / DeleteUserInput share the same id-only shape.

type UnenforceSettingInput

type UnenforceSettingInput struct {
	Key    string `json:"key"`
	Scope  string `json:"scope"`
	AppID  string `json:"appId,omitempty"`
	OrgID  string `json:"orgId,omitempty"`
	UserID string `json:"userId,omitempty"`
}

UnenforceSettingInput releases an enforced setting at a scope.

type UpdateAppInput

type UpdateAppInput struct {
	ID   string  `json:"id"`
	Name *string `json:"name,omitempty"`
	Slug *string `json:"slug,omitempty"`
}

type UpdateEnvInput

type UpdateEnvInput struct {
	ID          string  `json:"id"`
	Name        *string `json:"name,omitempty"`
	Description *string `json:"description,omitempty"`
	Color       *string `json:"color,omitempty"`
}

type UpdateRoleInput

type UpdateRoleInput struct {
	ID          string  `json:"id"`
	Name        *string `json:"name,omitempty"`
	Description *string `json:"description,omitempty"`
}

type UpdateSettingInput

type UpdateSettingInput struct {
	Key    string          `json:"key"`
	Value  json.RawMessage `json:"value"`
	Scope  string          `json:"scope,omitempty"`
	AppID  string          `json:"appId,omitempty"`
	OrgID  string          `json:"orgId,omitempty"`
	UserID string          `json:"userId,omitempty"`
}

UpdateSettingInput extends the deprecated v1 shape with scope-aware fields. Scope is optional for back-compat — empty defaults to ScopeApp at the principal's app, matching the old behaviour. New callers (settings.panel) always pass an explicit scope.

type UpdateUserInput

type UpdateUserInput struct {
	ID            string  `json:"id"`
	FirstName     *string `json:"firstName,omitempty"`
	LastName      *string `json:"lastName,omitempty"`
	Username      *string `json:"username,omitempty"`
	EmailVerified *bool   `json:"emailVerified,omitempty"`
}

UpdateUserInput is the wire shape for users.update. Only fields the caller actually wants to change need to be set — pointer-typed so we can distinguish "leave unchanged" from "set to empty/false".

type UpdateWebhookInput

type UpdateWebhookInput struct {
	ID     string    `json:"id"`
	URL    *string   `json:"url,omitempty"`
	Events *[]string `json:"events,omitempty"`
	Active *bool     `json:"active,omitempty"`
}

type UserDetail

type UserDetail struct {
	UserSummary
	DisplayName       string `json:"displayName,omitempty"`
	Phone             string `json:"phone,omitempty"`
	PhoneVerified     bool   `json:"phoneVerified,omitempty"`
	Image             string `json:"image,omitempty"`
	BanReason         string `json:"banReason,omitempty"`
	BanExpiresAt      string `json:"banExpiresAt,omitempty"`
	PasswordChangedAt string `json:"passwordChangedAt,omitempty"`
	UpdatedAt         string `json:"updatedAt"`
	AppID             string `json:"appId,omitempty"`
	EnvID             string `json:"envId,omitempty"`
}

UserDetail extends UserSummary with the fields the detail drawer and the /users/:id route render. Splitting summary vs detail keeps the list payload small when there are thousands of users.

type UserSummary

type UserSummary struct {
	ID            string `json:"id"`
	Email         string `json:"email"`
	EmailVerified bool   `json:"emailVerified"`
	FirstName     string `json:"firstName,omitempty"`
	LastName      string `json:"lastName,omitempty"`
	Username      string `json:"username,omitempty"`
	Banned        bool   `json:"banned"`
	CreatedAt     string `json:"createdAt"`
}

UserSummary is the table-row projection of a user.User. Lean by design: passwords, ban metadata, timestamps stay on the detail surface. The React shell's resource.list reads field names verbatim from the JSON, so renames here are wire-level breaking changes.

type UsersListResponse

type UsersListResponse struct {
	Users      []UserSummary `json:"users"`
	NextCursor string        `json:"nextCursor,omitempty"`
	Total      int           `json:"total,omitempty"`
}

UsersListResponse is the users.list reply. The shell's resource.list extractor picks the first array-valued field, which is `users` — next_cursor and total ride alongside for upcoming paging UI.

type WebhookCreatedResponse

type WebhookCreatedResponse struct {
	OK     bool   `json:"ok"`
	ID     string `json:"id"`
	Secret string `json:"secret"`
}

WebhookCreatedResponse acknowledges a new webhook and carries its signing secret, shown this once and never again.

type WebhookDetail

type WebhookDetail struct {
	WebhookSummary
	AppID     string `json:"appId,omitempty"`
	EnvID     string `json:"envId,omitempty"`
	UpdatedAt string `json:"updatedAt"`
}

type WebhookListResponse

type WebhookListResponse struct {
	Webhooks []WebhookSummary `json:"webhooks"`
}

type WebhookSecretResponse

type WebhookSecretResponse struct {
	OK     bool   `json:"ok"`
	ID     string `json:"id"`
	Secret string `json:"secret"`
}

WebhookSecretResponse carries a rotated signing secret, shown once.

type WebhookSummary

type WebhookSummary struct {
	ID        string   `json:"id"`
	URL       string   `json:"url"`
	Events    []string `json:"events"`
	Active    bool     `json:"active"`
	CreatedAt string   `json:"createdAt"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL