Documentation
¶
Overview ¶
Package postgres implements the AuthSome store interface using grove ORM (PostgreSQL).
Index ¶
- Variables
- type APIKeyModel
- type AppClientConfigModel
- type AppModel
- type AppSessionConfigModel
- type BrandingConfigModel
- type DelegationModel
- type DeviceModel
- type EnvironmentModel
- type FormConfigModel
- type InvitationModel
- type KVModel
- type MemberModel
- type NotificationModel
- type OrganizationModel
- type PasswordResetModel
- type RevokedRefreshTokenModel
- type ServiceAccountModel
- type SessionModel
- type SettingModel
- type Store
- func (s *Store) AddUserEmail(ctx context.Context, e *user.UserEmail) error
- func (s *Store) BatchResolve(ctx context.Context, keys []string, opts settings.ResolveOpts) (map[string][]*settings.Setting, error)
- func (s *Store) Close() error
- func (s *Store) ConsumePasswordReset(ctx context.Context, token string) error
- func (s *Store) ConsumeVerification(ctx context.Context, token string) error
- func (s *Store) CreateAPIKey(ctx context.Context, k *apikey.APIKey) error
- func (s *Store) CreateApp(ctx context.Context, a *app.App) error
- func (s *Store) CreateDelegation(ctx context.Context, d *principal.Delegation) error
- func (s *Store) CreateDevice(ctx context.Context, d *device.Device) error
- func (s *Store) CreateEnvironment(ctx context.Context, e *environment.Environment) error
- func (s *Store) CreateFormConfig(ctx context.Context, fc *formconfig.FormConfig) error
- func (s *Store) CreateInvitation(ctx context.Context, inv *organization.Invitation) error
- func (s *Store) CreateMember(ctx context.Context, m *organization.Member) error
- func (s *Store) CreateNotification(ctx context.Context, n *notification.Notification) error
- func (s *Store) CreateOrganization(ctx context.Context, o *organization.Organization) error
- func (s *Store) CreatePasswordReset(ctx context.Context, pr *account.PasswordReset) error
- func (s *Store) CreateServiceAccount(ctx context.Context, svc *serviceaccount.ServiceAccount) error
- func (s *Store) CreateSession(ctx context.Context, sess *session.Session) error
- func (s *Store) CreateTeam(ctx context.Context, t *organization.Team) error
- func (s *Store) CreateUser(ctx context.Context, u *user.User) error
- func (s *Store) CreateUserWithPrimaryEmail(ctx context.Context, u *user.User, primary *user.UserEmail) error
- func (s *Store) CreateVerification(ctx context.Context, v *account.Verification) error
- func (s *Store) CreateWebhook(ctx context.Context, w *webhook.Webhook) error
- func (s *Store) DB() *grove.DB
- func (s *Store) DeleteAPIKey(ctx context.Context, keyID id.APIKeyID) error
- func (s *Store) DeleteApp(ctx context.Context, appID id.AppID) error
- func (s *Store) DeleteAppClientConfig(ctx context.Context, appID id.AppID) error
- func (s *Store) DeleteAppSessionConfig(ctx context.Context, appID id.AppID) error
- func (s *Store) DeleteBranding(ctx context.Context, orgID id.OrgID) error
- func (s *Store) DeleteDevice(ctx context.Context, deviceID id.DeviceID) error
- func (s *Store) DeleteEnvironment(ctx context.Context, envID id.EnvironmentID) error
- func (s *Store) DeleteExpiredPasswordResets(ctx context.Context, before time.Time, batch int) (int64, error)
- func (s *Store) DeleteExpiredRevokedRefreshTokens(ctx context.Context, before time.Time, batch int) (int64, error)
- func (s *Store) DeleteExpiredSessions(ctx context.Context, before time.Time, batch int) (int64, error)
- func (s *Store) DeleteExpiredVerifications(ctx context.Context, before time.Time, batch int) (int64, error)
- func (s *Store) DeleteFormConfig(ctx context.Context, appID id.AppID, formType string) error
- func (s *Store) DeleteInvitation(ctx context.Context, invID id.InvitationID) error
- func (s *Store) DeleteMember(ctx context.Context, memberID id.MemberID) error
- func (s *Store) DeleteOrganization(ctx context.Context, orgID id.OrgID) error
- func (s *Store) DeleteOrganizationCascade(ctx context.Context, orgID id.OrgID) error
- func (s *Store) DeleteServiceAccount(ctx context.Context, svcID id.ServiceAccountID) error
- func (s *Store) DeleteSession(ctx context.Context, sessionID id.SessionID) error
- func (s *Store) DeleteSessionsByGrant(ctx context.Context, grantID id.AgentGrantID) error
- func (s *Store) DeleteSetting(ctx context.Context, key string, scope settings.Scope, scopeID string) error
- func (s *Store) DeleteSettingsByNamespace(ctx context.Context, namespace string) error
- func (s *Store) DeleteTeam(ctx context.Context, teamID id.TeamID) error
- func (s *Store) DeleteUser(ctx context.Context, userID id.UserID) error
- func (s *Store) DeleteUserEmail(ctx context.Context, userID id.UserID, email string) error
- func (s *Store) DeleteUserSessions(ctx context.Context, userID id.UserID) error
- func (s *Store) DeleteWebhook(ctx context.Context, webhookID id.WebhookID) error
- func (s *Store) FindActiveDelegation(ctx context.Context, appID id.AppID, actor, subject principal.Ref, ...) (*principal.Delegation, error)
- func (s *Store) FindByPrefix(ctx context.Context, prefix string) (*apikey.APIKey, error)
- func (s *Store) GetAPIKey(ctx context.Context, keyID id.APIKeyID) (*apikey.APIKey, error)
- func (s *Store) GetAPIKeyByPrefix(ctx context.Context, appID id.AppID, prefix string) (*apikey.APIKey, error)
- func (s *Store) GetAPIKeyByPublicKey(ctx context.Context, appID id.AppID, publicKey string) (*apikey.APIKey, error)
- func (s *Store) GetActiveEmailVerification(ctx context.Context, userID id.UserID) (*account.Verification, error)
- func (s *Store) GetApp(ctx context.Context, appID id.AppID) (*app.App, error)
- func (s *Store) GetAppByPublishableKey(ctx context.Context, key string) (*app.App, error)
- func (s *Store) GetAppBySlug(ctx context.Context, slug string) (*app.App, error)
- func (s *Store) GetAppClientConfig(ctx context.Context, appID id.AppID) (*appclientconfig.Config, error)
- func (s *Store) GetAppSessionConfig(ctx context.Context, appID id.AppID) (*appsessionconfig.Config, error)
- func (s *Store) GetBranding(ctx context.Context, orgID id.OrgID) (*formconfig.BrandingConfig, error)
- func (s *Store) GetDefaultEnvironment(ctx context.Context, appID id.AppID) (*environment.Environment, error)
- func (s *Store) GetDelegation(ctx context.Context, delID id.DelegationID) (*principal.Delegation, error)
- func (s *Store) GetDevice(ctx context.Context, deviceID id.DeviceID) (*device.Device, error)
- func (s *Store) GetDeviceByFingerprint(ctx context.Context, userID id.UserID, fingerprint string) (*device.Device, error)
- func (s *Store) GetEnvironment(ctx context.Context, envID id.EnvironmentID) (*environment.Environment, error)
- func (s *Store) GetEnvironmentBySlug(ctx context.Context, appID id.AppID, slug string) (*environment.Environment, error)
- func (s *Store) GetFormConfig(ctx context.Context, appID id.AppID, formType string) (*formconfig.FormConfig, error)
- func (s *Store) GetInvitation(ctx context.Context, invID id.InvitationID) (*organization.Invitation, error)
- func (s *Store) GetInvitationByToken(ctx context.Context, token string) (*organization.Invitation, error)
- func (s *Store) GetMember(ctx context.Context, memberID id.MemberID) (*organization.Member, error)
- func (s *Store) GetMemberByUserAndOrg(ctx context.Context, userID id.UserID, orgID id.OrgID) (*organization.Member, error)
- func (s *Store) GetNotification(ctx context.Context, notifID id.NotificationID) (*notification.Notification, error)
- func (s *Store) GetOrganization(ctx context.Context, orgID id.OrgID) (*organization.Organization, error)
- func (s *Store) GetOrganizationBySlug(ctx context.Context, appID id.AppID, slug string) (*organization.Organization, error)
- func (s *Store) GetPasswordReset(ctx context.Context, token string) (*account.PasswordReset, error)
- func (s *Store) GetPlatformApp(ctx context.Context) (*app.App, error)
- func (s *Store) GetPrincipal(ctx context.Context, ref principal.Ref) (*principal.Principal, error)
- func (s *Store) GetRevokedRefreshTokenFamily(ctx context.Context, tokenHash string) (id.SessionFamilyID, error)
- func (s *Store) GetServiceAccount(ctx context.Context, svcID id.ServiceAccountID) (*serviceaccount.ServiceAccount, error)
- func (s *Store) GetSession(ctx context.Context, sessionID id.SessionID) (*session.Session, error)
- func (s *Store) GetSessionByRefreshToken(ctx context.Context, refreshToken string) (*session.Session, error)
- func (s *Store) GetSessionByToken(ctx context.Context, token string) (*session.Session, error)
- func (s *Store) GetSetting(ctx context.Context, key string, scope settings.Scope, scopeID string) (*settings.Setting, error)
- func (s *Store) GetTeam(ctx context.Context, teamID id.TeamID) (*organization.Team, error)
- func (s *Store) GetUser(ctx context.Context, userID id.UserID) (*user.User, error)
- func (s *Store) GetUserByAnyEmail(ctx context.Context, appID id.AppID, envID id.EnvironmentID, email string) (*user.User, error)
- func (s *Store) GetUserByEmail(ctx context.Context, appID id.AppID, envID id.EnvironmentID, email string) (*user.User, error)
- func (s *Store) GetUserByPhone(ctx context.Context, appID id.AppID, envID id.EnvironmentID, phone string) (*user.User, error)
- func (s *Store) GetUserByUsername(ctx context.Context, appID id.AppID, envID id.EnvironmentID, username string) (*user.User, error)
- func (s *Store) GetUserEmailRecord(ctx context.Context, appID id.AppID, envID id.EnvironmentID, email string) (*user.UserEmail, error)
- func (s *Store) GetUserEmails(ctx context.Context, userID id.UserID) ([]*user.UserEmail, error)
- func (s *Store) GetVerification(ctx context.Context, token string) (*account.Verification, error)
- func (s *Store) GetWebhook(ctx context.Context, webhookID id.WebhookID) (*webhook.Webhook, error)
- func (s *Store) HashLegacyTokens(ctx context.Context, batch int) (int64, error)
- func (s *Store) IsRefreshTokenRevoked(ctx context.Context, tokenHash string) (bool, error)
- func (s *Store) KVCounter(ctx context.Context, key string) (int64, error)
- func (s *Store) KVDelete(ctx context.Context, key string) error
- func (s *Store) KVDeleteExpired(ctx context.Context, now time.Time) (int64, error)
- func (s *Store) KVGet(ctx context.Context, key string) ([]byte, error)
- func (s *Store) KVIncrement(ctx context.Context, key string, ttl time.Duration) (int64, error)
- func (s *Store) KVSet(ctx context.Context, key string, value []byte, ttl time.Duration) error
- func (s *Store) KVSetNX(ctx context.Context, key string, value []byte, ttl time.Duration) (bool, error)
- func (s *Store) ListAPIKeysByApp(ctx context.Context, appID id.AppID) ([]*apikey.APIKey, error)
- func (s *Store) ListAPIKeysByUser(ctx context.Context, appID id.AppID, userID id.UserID) ([]*apikey.APIKey, error)
- func (s *Store) ListApps(ctx context.Context) ([]*app.App, error)
- func (s *Store) ListDelegations(ctx context.Context, q *principal.DelegationQuery) ([]*principal.Delegation, error)
- func (s *Store) ListDevices(ctx context.Context, limit int) ([]*device.Device, error)
- func (s *Store) ListEnvironments(ctx context.Context, appID id.AppID) ([]*environment.Environment, error)
- func (s *Store) ListFormConfigs(ctx context.Context, appID id.AppID) ([]*formconfig.FormConfig, error)
- func (s *Store) ListInvitations(ctx context.Context, orgID id.OrgID) ([]*organization.Invitation, error)
- func (s *Store) ListInvitationsPage(ctx context.Context, orgID id.OrgID, opts page.Opts) (page.Page[*organization.Invitation], error)
- func (s *Store) ListMembers(ctx context.Context, orgID id.OrgID) ([]*organization.Member, error)
- func (s *Store) ListMembersPage(ctx context.Context, orgID id.OrgID, opts page.Opts) (page.Page[*organization.Member], error)
- func (s *Store) ListOrganizations(ctx context.Context, appID id.AppID) ([]*organization.Organization, error)
- func (s *Store) ListOrganizationsPage(ctx context.Context, appID id.AppID, opts page.Opts) (page.Page[*organization.Organization], error)
- func (s *Store) ListPrincipals(ctx context.Context, q *principal.Query) ([]*principal.Principal, error)
- func (s *Store) ListServiceAccounts(ctx context.Context, q *serviceaccount.Query) (*serviceaccount.List, error)
- func (s *Store) ListSessions(ctx context.Context, limit int) ([]*session.Session, error)
- func (s *Store) ListSettings(ctx context.Context, opts settings.ListOpts) ([]*settings.Setting, error)
- func (s *Store) ListTeams(ctx context.Context, orgID id.OrgID) ([]*organization.Team, error)
- func (s *Store) ListTeamsPage(ctx context.Context, orgID id.OrgID, opts page.Opts) (page.Page[*organization.Team], error)
- func (s *Store) ListUserDevices(ctx context.Context, userID id.UserID) ([]*device.Device, error)
- func (s *Store) ListUserNotifications(ctx context.Context, userID id.UserID) ([]*notification.Notification, error)
- func (s *Store) ListUserOrganizations(ctx context.Context, userID id.UserID) ([]*organization.Organization, error)
- func (s *Store) ListUserOrganizationsPage(ctx context.Context, userID id.UserID, opts page.Opts) (page.Page[*organization.Organization], error)
- func (s *Store) ListUserSessions(ctx context.Context, userID id.UserID) ([]*session.Session, error)
- func (s *Store) ListUserSessionsPage(ctx context.Context, userID id.UserID, opts page.Opts) (page.Page[*session.Session], error)
- func (s *Store) ListUsers(ctx context.Context, q *user.Query) (*user.List, error)
- func (s *Store) ListWebhooks(ctx context.Context, appID id.AppID) ([]*webhook.Webhook, error)
- func (s *Store) MarkRefreshTokenReplayed(ctx context.Context, tokenHash string) (bool, error)
- func (s *Store) MarkRefreshTokenRevoked(ctx context.Context, tokenHash string, familyID id.SessionFamilyID, ...) error
- func (s *Store) MarkSent(ctx context.Context, notifID id.NotificationID) error
- func (s *Store) MarkUserEmailVerified(ctx context.Context, userID id.UserID, email string) error
- func (s *Store) Migrate(ctx context.Context, extraGroups ...*migrate.Group) error
- func (s *Store) Ping(ctx context.Context) error
- func (s *Store) ResolveSettings(ctx context.Context, key string, opts settings.ResolveOpts) ([]*settings.Setting, error)
- func (s *Store) RevokeDelegation(ctx context.Context, delID id.DelegationID, at time.Time) error
- func (s *Store) RevokeRefreshTokenFamily(ctx context.Context, familyID id.SessionFamilyID, reason string) error
- func (s *Store) RotateSession(ctx context.Context, sess *session.Session, expectedTokenHash string) (bool, error)
- func (s *Store) SaveBranding(ctx context.Context, b *formconfig.BrandingConfig) error
- func (s *Store) SeedLegacyInvitation(ctx context.Context, inv *organization.Invitation) error
- func (s *Store) SeedLegacyPasswordReset(ctx context.Context, pr *account.PasswordReset) error
- func (s *Store) SeedLegacySession(ctx context.Context, sess *session.Session) error
- func (s *Store) SeedLegacyVerification(ctx context.Context, v *account.Verification) error
- func (s *Store) SetAppClientConfig(ctx context.Context, cfg *appclientconfig.Config) error
- func (s *Store) SetAppSessionConfig(ctx context.Context, cfg *appsessionconfig.Config) error
- func (s *Store) SetDefaultEnvironment(ctx context.Context, appID id.AppID, envID id.EnvironmentID) error
- func (s *Store) SetPrimaryEmail(ctx context.Context, userID id.UserID, email string) error
- func (s *Store) SetSetting(ctx context.Context, st *settings.Setting) error
- func (s *Store) TouchAPIKey(ctx context.Context, keyID id.APIKeyID, at time.Time) error
- func (s *Store) TouchSession(ctx context.Context, sessionID id.SessionID, ...) error
- func (s *Store) UpdateAPIKey(ctx context.Context, k *apikey.APIKey) error
- func (s *Store) UpdateApp(ctx context.Context, a *app.App) error
- func (s *Store) UpdateDevice(ctx context.Context, d *device.Device) error
- func (s *Store) UpdateEnvironment(ctx context.Context, e *environment.Environment) error
- func (s *Store) UpdateFormConfig(ctx context.Context, fc *formconfig.FormConfig) error
- func (s *Store) UpdateInvitation(ctx context.Context, inv *organization.Invitation) error
- func (s *Store) UpdateMember(ctx context.Context, mem *organization.Member) error
- func (s *Store) UpdateOrganization(ctx context.Context, o *organization.Organization) error
- func (s *Store) UpdateServiceAccount(ctx context.Context, svc *serviceaccount.ServiceAccount) error
- func (s *Store) UpdateSession(ctx context.Context, sess *session.Session) error
- func (s *Store) UpdateTeam(ctx context.Context, t *organization.Team) error
- func (s *Store) UpdateUser(ctx context.Context, u *user.User) error
- func (s *Store) UpdateVerification(ctx context.Context, v *account.Verification) error
- func (s *Store) UpdateWebhook(ctx context.Context, w *webhook.Webhook) error
- func (s *Store) WithTx(_ context.Context, fn func(tx organization.Store) error) error
- type TeamModel
- type UserEmailModel
- type UserModel
- type VerificationModel
- type WebhookModel
Constants ¶
This section is empty.
Variables ¶
var Migrations = migrate.NewGroup("authsome")
Migrations is the grove migration group for the AuthSome store. It can be registered with the grove extension for orchestrated migration management (locking, version tracking, rollback support).
Functions ¶
This section is empty.
Types ¶
type APIKeyModel ¶
type APIKeyModel struct {
grove.BaseModel `grove:"table:authsome_api_keys,alias:ak"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
UserID sql.NullString `grove:"user_id"`
ServiceAccountID sql.NullString `grove:"service_account_id"`
Name string `grove:"name,notnull"`
KeyHash string `grove:"key_hash,notnull"`
KeyPrefix string `grove:"key_prefix,notnull"`
PublicKey string `grove:"public_key,notnull"`
PublicKeyPrefix string `grove:"public_key_prefix,notnull"`
Scopes string `grove:"scopes"` // comma-separated
ExpiresAt sql.NullTime `grove:"expires_at"`
LastUsedAt sql.NullTime `grove:"last_used_at"`
Revoked bool `grove:"revoked"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type AppClientConfigModel ¶
type AppClientConfigModel struct {
grove.BaseModel `grove:"table:authsome_app_client_configs,alias:acc"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
SignupEnabled *bool `grove:"signup_enabled"`
PasswordEnabled *bool `grove:"password_enabled"`
PasskeyEnabled *bool `grove:"passkey_enabled"`
MagicLinkEnabled *bool `grove:"magic_link_enabled"`
MFAEnabled *bool `grove:"mfa_enabled"`
MFARequired *bool `grove:"mfa_required"`
SSOEnabled *bool `grove:"sso_enabled"`
SocialEnabled *bool `grove:"social_enabled"`
WaitlistEnabled *bool `grove:"waitlist_enabled"`
RequireEmailVerification *bool `grove:"require_email_verification"`
SocialProviders json.RawMessage `grove:"social_providers,type:jsonb"`
MFAMethods json.RawMessage `grove:"mfa_methods,type:jsonb"`
AppName *string `grove:"app_name"`
LogoURL *string `grove:"logo_url"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type AppModel ¶
type AppModel struct {
grove.BaseModel `grove:"table:authsome_apps,alias:a"`
ID string `grove:"id,pk"`
Name string `grove:"name,notnull"`
Slug string `grove:"slug,notnull"`
Logo string `grove:"logo"`
PublishableKey string `grove:"publishable_key"`
IsPlatform bool `grove:"is_platform"`
Metadata json.RawMessage `grove:"metadata,type:jsonb"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type AppSessionConfigModel ¶
type AppSessionConfigModel struct {
grove.BaseModel `grove:"table:authsome_app_session_configs,alias:asc"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
TokenTTLSeconds sql.NullInt64 `grove:"token_ttl_seconds"`
RefreshTokenTTLSeconds sql.NullInt64 `grove:"refresh_token_ttl_seconds"`
MaxActiveSessions sql.NullInt64 `grove:"max_active_sessions"`
RotateRefreshToken sql.NullBool `grove:"rotate_refresh_token"`
BindToIP sql.NullBool `grove:"bind_to_ip"`
BindToDevice sql.NullBool `grove:"bind_to_device"`
TokenFormat string `grove:"token_format"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type BrandingConfigModel ¶
type BrandingConfigModel struct {
grove.BaseModel `grove:"table:authsome_branding_configs,alias:bc"`
ID string `grove:"id,pk"`
OrgID string `grove:"org_id,notnull"`
AppID string `grove:"app_id,notnull"`
LogoURL string `grove:"logo_url"`
PrimaryColor string `grove:"primary_color"`
BackgroundColor string `grove:"background_color"`
AccentColor string `grove:"accent_color"`
FontFamily string `grove:"font_family"`
CustomCSS string `grove:"custom_css"`
CompanyName string `grove:"company_name"`
Tagline string `grove:"tagline"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type DelegationModel ¶
type DelegationModel struct {
grove.BaseModel `grove:"table:authsome_delegations,alias:dl"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
OrgID string `grove:"org_id"`
ActorKind string `grove:"actor_kind,notnull"`
ActorID string `grove:"actor_id,notnull"`
SubjectKind string `grove:"subject_kind,notnull"`
SubjectID string `grove:"subject_id,notnull"`
GrantKind string `grove:"grant_kind,notnull"`
Scopes json.RawMessage `grove:"scopes,type:jsonb"`
GrantedByKind string `grove:"granted_by_kind"`
GrantedByID string `grove:"granted_by_id"`
ExpiresAt *time.Time `grove:"expires_at"`
RevokedAt *time.Time `grove:"revoked_at"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type DeviceModel ¶
type DeviceModel struct {
grove.BaseModel `grove:"table:authsome_devices,alias:d"`
ID string `grove:"id,pk"`
UserID string `grove:"user_id,notnull"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
Name string `grove:"name"`
Type string `grove:"type"`
Browser string `grove:"browser"`
OS string `grove:"os"`
IPAddress string `grove:"ip_address"`
Fingerprint string `grove:"fingerprint"`
Trusted bool `grove:"trusted"`
LastSeenAt time.Time `grove:"last_seen_at,notnull,default:now()"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type EnvironmentModel ¶
type EnvironmentModel struct {
grove.BaseModel `grove:"table:authsome_environments,alias:env"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
Name string `grove:"name,notnull"`
Slug string `grove:"slug,notnull"`
Type string `grove:"type,notnull"`
IsDefault bool `grove:"is_default"`
Color string `grove:"color"`
Description string `grove:"description"`
Settings json.RawMessage `grove:"settings,type:jsonb"`
ClonedFrom string `grove:"cloned_from"`
Metadata json.RawMessage `grove:"metadata,type:jsonb"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type FormConfigModel ¶
type FormConfigModel struct {
grove.BaseModel `grove:"table:authsome_form_configs,alias:fc"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
FormType string `grove:"form_type,notnull"`
Fields json.RawMessage `grove:"fields,type:jsonb"`
Active bool `grove:"active"`
Version int `grove:"version,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type InvitationModel ¶
type InvitationModel struct {
grove.BaseModel `grove:"table:authsome_invitations,alias:inv"`
ID string `grove:"id,pk"`
OrgID string `grove:"org_id,notnull"`
Email string `grove:"email,notnull"`
Role string `grove:"role,notnull"`
InviterID string `grove:"inviter_id,notnull"`
Status string `grove:"status,notnull"`
Token string `grove:"token,notnull"`
TokenHash sql.NullString `grove:"token_hash"`
ExpiresAt time.Time `grove:"expires_at,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
}
type KVModel ¶
type KVModel struct {
grove.BaseModel `grove:"table:authsome_kv,alias:kv"`
Key string `grove:"key,pk"`
Value []byte `grove:"value"`
Counter int64 `grove:"counter,notnull"`
ExpiresAt int64 `grove:"expires_at,notnull"`
}
KVModel is one authsome_kv row: a caller-chosen key, an opaque value, a counter for increments, and an expiry in unix milliseconds.
type MemberModel ¶
type MemberModel struct {
grove.BaseModel `grove:"table:authsome_members,alias:m"`
ID string `grove:"id,pk"`
OrgID string `grove:"org_id,notnull"`
UserID string `grove:"user_id,notnull"`
Role string `grove:"role,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type NotificationModel ¶
type NotificationModel struct {
grove.BaseModel `grove:"table:authsome_notifications,alias:n"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
UserID string `grove:"user_id,notnull"`
Type string `grove:"type,notnull"`
Channel string `grove:"channel,notnull"`
Subject string `grove:"subject"`
Body string `grove:"body"`
Sent bool `grove:"sent"`
SentAt sql.NullTime `grove:"sent_at"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
}
type OrganizationModel ¶
type OrganizationModel struct {
grove.BaseModel `grove:"table:authsome_organizations,alias:o"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
Name string `grove:"name,notnull"`
Slug string `grove:"slug,notnull"`
Logo string `grove:"logo"`
Metadata json.RawMessage `grove:"metadata,type:jsonb"`
CreatedBy string `grove:"created_by,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type PasswordResetModel ¶
type PasswordResetModel struct {
grove.BaseModel `grove:"table:authsome_password_resets,alias:pr"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
UserID string `grove:"user_id,notnull"`
Token string `grove:"token,notnull"`
TokenHash sql.NullString `grove:"token_hash"`
ExpiresAt time.Time `grove:"expires_at,notnull"`
Consumed bool `grove:"consumed"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
}
type RevokedRefreshTokenModel ¶
type RevokedRefreshTokenModel struct {
grove.BaseModel `grove:"table:authsome_revoked_refresh_tokens,alias:rrt"`
TokenHash string `grove:"token_hash,pk"`
FamilyID string `grove:"family_id,notnull"`
RevokedAt time.Time `grove:"revoked_at,notnull"`
Reason string `grove:"reason"`
}
RevokedRefreshTokenModel is the on-disk representation used for refresh-token replay detection. token_hash is the SHA-256 hex of a previously-rotated or replay-flagged refresh token.
type ServiceAccountModel ¶
type ServiceAccountModel struct {
grove.BaseModel `grove:"table:authsome_service_accounts,alias:sa"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id"`
OrgID string `grove:"org_id"`
// Kind is empty on no row postgres writes, but stays nullable-tolerant so
// a row inserted by hand without it still reads as a service account.
Kind string `grove:"kind"`
Name string `grove:"name,notnull"`
Description string `grove:"description"`
Scopes json.RawMessage `grove:"scopes,type:jsonb"`
OwnerUserID string `grove:"owner_user_id"`
ParentID string `grove:"parent_id"`
ExpiresAt *time.Time `grove:"expires_at"`
Active bool `grove:"active,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type SessionModel ¶
type SessionModel struct {
grove.BaseModel `grove:"table:authsome_sessions,alias:s"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
// UserID is empty for a service-account session, which has no user behind
// it. That is the same sentinel-empty convention every other optional id
// column here uses (org_id, device_id, family_id, impersonated_by).
UserID string `grove:"user_id,notnull"`
// PrincipalKind and ServiceAccountID carry which kind of principal owns the
// session. Empty PrincipalKind means "user" for rows written before these
// columns existed, so neither direction normalizes it — inventing "user" on
// read would make a legacy row indistinguishable from one deliberately
// stamped, and this value is branched on to make authorization decisions.
PrincipalKind string `grove:"principal_kind"`
ServiceAccountID string `grove:"service_account_id"`
// AgentID and GrantID carry the agent principal and the grant that
// authorized it, mapped the same way as ServiceAccountID above.
AgentID string `grove:"agent_id"`
GrantID string `grove:"grant_id"`
OrgID string `grove:"org_id"`
FamilyID string `grove:"family_id"`
// Token and RefreshToken are empty on every row written since
// hash_session_tokens; they hold plaintext only on rows older than that
// migration, which the first lookup rewrites. TokenHash and
// RefreshTokenHash are NULL on those legacy rows so the unique index
// skips them.
Token string `grove:"token,notnull"`
RefreshToken string `grove:"refresh_token,notnull"`
TokenHash sql.NullString `grove:"token_hash"`
RefreshTokenHash sql.NullString `grove:"refresh_token_hash"`
IPAddress string `grove:"ip_address"`
UserAgent string `grove:"user_agent"`
DeviceID string `grove:"device_id"`
ImpersonatedBy string `grove:"impersonated_by"`
// Roles is JSON rather than a comma-separated list. A slug containing a
// comma would split into two role names nobody was ever granted, and
// these strings are read back as an authorization decision, so the
// encoding must not be able to invent a member.
Roles json.RawMessage `grove:"roles,type:jsonb"`
// Audience is JSON for the same reason Roles is. A resource identifier is
// a URI and may contain a comma, and these strings are compared to decide
// whether a token is allowed to authenticate at all.
Audience json.RawMessage `grove:"audience,type:jsonb"`
// Scopes is JSON for the same reason Roles is: these strings are read back
// as an authorization decision, so the encoding must not be able to invent
// or merge a member.
Scopes json.RawMessage `grove:"scopes,type:jsonb"`
// Actors is JSON for the same reason Roles is: a chain element carries a
// kind and an id, and both are compared to make authorization decisions,
// so the encoding must not be able to invent or merge a member.
Actors json.RawMessage `grove:"actors,type:jsonb"`
ActorGrant string `grove:"actor_grant"`
DelegationID string `grove:"delegation_id"`
LastActivityAt time.Time `grove:"last_activity_at"`
ExpiresAt time.Time `grove:"expires_at,notnull"`
RefreshTokenExpiresAt time.Time `grove:"refresh_token_expires_at,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
DPoPJKT string `grove:"dpop_jkt"`
ClientID string `grove:"client_id"`
}
type SettingModel ¶
type SettingModel struct {
grove.BaseModel `grove:"table:authsome_settings,alias:st"`
ID string `grove:"id,pk"`
Key string `grove:"key,notnull"`
Value json.RawMessage `grove:"value,type:jsonb"`
Scope string `grove:"scope,notnull"`
ScopeID string `grove:"scope_id,notnull"`
AppID string `grove:"app_id"`
OrgID string `grove:"org_id"`
Enforced bool `grove:"enforced"`
Namespace string `grove:"namespace"`
Version int64 `grove:"version"`
UpdatedBy string `grove:"updated_by"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store implements store.Store using grove ORM (PostgreSQL).
func (*Store) AddUserEmail ¶
func (*Store) BatchResolve ¶
func (*Store) ConsumePasswordReset ¶
func (*Store) ConsumeVerification ¶
func (*Store) CreateAPIKey ¶
func (*Store) CreateDelegation ¶
CreateDelegation stores a new grant, refusing one that would duplicate a grant already live for the same (app, actor, subject, kind).
The liveness check runs here, in Go, and not in the index predicate. Live means principal.Delegation.IsActive: not revoked AND not past its expiry. A partial index cannot express the second half, because postgres requires an index predicate to be immutable and every spelling of the current time is not, so the index (see the delegation_live_index_excludes_expired migration) now covers only grants that never expire, and this is where the rest is enforced.
This is a read followed by a write rather than one atomic statement, so two concurrent creates for the same tuple can both land. That is a deliberate trade against the bug it replaces: filtering on revoked_at alone meant an impersonation grant that merely lapsed blocked every later impersonation of that user by that admin forever, because nothing but StopImpersonation ever writes revoked_at.
func (*Store) CreateDevice ¶
func (*Store) CreateEnvironment ¶
func (s *Store) CreateEnvironment(ctx context.Context, e *environment.Environment) error
func (*Store) CreateFormConfig ¶
func (s *Store) CreateFormConfig(ctx context.Context, fc *formconfig.FormConfig) error
func (*Store) CreateInvitation ¶
func (s *Store) CreateInvitation(ctx context.Context, inv *organization.Invitation) error
func (*Store) CreateMember ¶
func (*Store) CreateNotification ¶
func (s *Store) CreateNotification(ctx context.Context, n *notification.Notification) error
func (*Store) CreateOrganization ¶
func (s *Store) CreateOrganization(ctx context.Context, o *organization.Organization) error
func (*Store) CreatePasswordReset ¶
func (*Store) CreateServiceAccount ¶
func (s *Store) CreateServiceAccount(ctx context.Context, svc *serviceaccount.ServiceAccount) error
func (*Store) CreateSession ¶
func (*Store) CreateTeam ¶
func (*Store) CreateUserWithPrimaryEmail ¶
func (*Store) CreateVerification ¶
func (*Store) CreateWebhook ¶
func (*Store) DeleteAPIKey ¶
func (*Store) DeleteApp ¶
DeleteApp removes the app and all of its data. Deleting the app row cascades (ON DELETE CASCADE, see the "cascade_app_id_foreign_keys" migration) to every table whose app_id references authsome_apps(id): users, sessions, environments, organizations, webhooks, oauth2 clients, ... The few app-scoped config tables (branding, session/client configs, settings) carry an app_id column but no foreign key, so they are deleted explicitly. Everything runs in one transaction so the app is never left half-deleted. Global settings (empty app_id) are left untouched.
func (*Store) DeleteAppClientConfig ¶
func (*Store) DeleteAppSessionConfig ¶
func (*Store) DeleteBranding ¶
func (*Store) DeleteDevice ¶
func (*Store) DeleteEnvironment ¶
func (*Store) DeleteExpiredPasswordResets ¶
func (s *Store) DeleteExpiredPasswordResets(ctx context.Context, before time.Time, batch int) (int64, error)
DeleteExpiredPasswordResets implements store.Retention.
func (*Store) DeleteExpiredRevokedRefreshTokens ¶
func (s *Store) DeleteExpiredRevokedRefreshTokens(ctx context.Context, before time.Time, batch int) (int64, error)
DeleteExpiredRevokedRefreshTokens implements store.Retention.
func (*Store) DeleteExpiredSessions ¶
func (s *Store) DeleteExpiredSessions(ctx context.Context, before time.Time, batch int) (int64, error)
DeleteExpiredSessions implements store.Retention.
func (*Store) DeleteExpiredVerifications ¶
func (s *Store) DeleteExpiredVerifications(ctx context.Context, before time.Time, batch int) (int64, error)
DeleteExpiredVerifications implements store.Retention.
func (*Store) DeleteFormConfig ¶
func (*Store) DeleteInvitation ¶
func (*Store) DeleteMember ¶
func (*Store) DeleteOrganization ¶
func (*Store) DeleteOrganizationCascade ¶
DeleteOrganizationCascade deletes the organization and all of its dependent rows (members, teams, invitations) inside a single PgTx. On any error the entire cascade rolls back; the orgs table is the last delete so a failure mid-cascade leaves the org row visible (callers can retry).
func (*Store) DeleteServiceAccount ¶
func (*Store) DeleteSession ¶
func (*Store) DeleteSessionsByGrant ¶
DeleteSessionsByGrant deletes every session issued under grantID, backed by idx_authsome_sessions_grant_id.
func (*Store) DeleteSetting ¶
func (*Store) DeleteSettingsByNamespace ¶
func (*Store) DeleteUserEmail ¶
func (*Store) DeleteUserSessions ¶
func (*Store) DeleteWebhook ¶
func (*Store) FindActiveDelegation ¶
func (s *Store) FindActiveDelegation( ctx context.Context, appID id.AppID, actor, subject principal.Ref, grantKind principal.GrantKind, ) (*principal.Delegation, error)
FindActiveDelegation resolves the live grant letting actor act for subject.
Active is evaluated in SQL rather than by loading and filtering in Go: this runs on the authentication path for every delegated request, and the partial unique index means at most one row can match.
The interface takes no time argument (unlike ListDelegations, which is given q.ActiveAsOf as a bound parameter), so the expiry check has to name a SQL clock rather than pass one in. That has to be clock_timestamp(), not NOW(): NOW() is transaction_timestamp(), frozen for the life of the calling transaction, so inside a long-lived transaction a grant would stay usable past its expires_at for the transaction's whole life. clock_timestamp() reads the wall clock at the moment this statement runs instead.
The comparison is `>=`, not `>`: principal.Delegation.IsActive defines a grant expiring at exactly the query instant as still active (`!at.After(expiresAt)`), and every store must agree with the domain method, not just with each other.
func (*Store) FindByPrefix ¶
func (*Store) GetAPIKeyByPrefix ¶
func (*Store) GetAPIKeyByPublicKey ¶
func (*Store) GetActiveEmailVerification ¶
func (*Store) GetAppByPublishableKey ¶
func (*Store) GetAppBySlug ¶
func (*Store) GetAppClientConfig ¶
func (*Store) GetAppSessionConfig ¶
func (*Store) GetBranding ¶
func (s *Store) GetBranding(ctx context.Context, orgID id.OrgID) (*formconfig.BrandingConfig, error)
func (*Store) GetDefaultEnvironment ¶
func (s *Store) GetDefaultEnvironment(ctx context.Context, appID id.AppID) (*environment.Environment, error)
func (*Store) GetDelegation ¶
func (s *Store) GetDelegation(ctx context.Context, delID id.DelegationID) (*principal.Delegation, error)
func (*Store) GetDeviceByFingerprint ¶
func (*Store) GetEnvironment ¶
func (s *Store) GetEnvironment(ctx context.Context, envID id.EnvironmentID) (*environment.Environment, error)
func (*Store) GetEnvironmentBySlug ¶
func (s *Store) GetEnvironmentBySlug(ctx context.Context, appID id.AppID, slug string) (*environment.Environment, error)
func (*Store) GetFormConfig ¶
func (s *Store) GetFormConfig(ctx context.Context, appID id.AppID, formType string) (*formconfig.FormConfig, error)
func (*Store) GetInvitation ¶
func (s *Store) GetInvitation(ctx context.Context, invID id.InvitationID) (*organization.Invitation, error)
func (*Store) GetInvitationByToken ¶
func (s *Store) GetInvitationByToken(ctx context.Context, token string) (*organization.Invitation, error)
func (*Store) GetMemberByUserAndOrg ¶
func (*Store) GetNotification ¶
func (s *Store) GetNotification(ctx context.Context, notifID id.NotificationID) (*notification.Notification, error)
func (*Store) GetOrganization ¶
func (s *Store) GetOrganization(ctx context.Context, orgID id.OrgID) (*organization.Organization, error)
func (*Store) GetOrganizationBySlug ¶
func (s *Store) GetOrganizationBySlug(ctx context.Context, appID id.AppID, slug string) (*organization.Organization, error)
func (*Store) GetPasswordReset ¶
func (*Store) GetPlatformApp ¶
func (*Store) GetPrincipal ¶
GetPrincipal resolves any principal by ref. A user ref is assembled from authsome_users; every other kind comes from authsome_service_accounts, looked up by ID alone: the ref's Kind only routes which table to read, matching how the memory backend resolves a principal.
func (*Store) GetRevokedRefreshTokenFamily ¶
func (s *Store) GetRevokedRefreshTokenFamily(ctx context.Context, tokenHash string) (id.SessionFamilyID, error)
GetRevokedRefreshTokenFamily returns the family bound to a previously- revoked token, or store.ErrNotFound if the hash is unknown.
func (*Store) GetServiceAccount ¶
func (s *Store) GetServiceAccount(ctx context.Context, svcID id.ServiceAccountID) (*serviceaccount.ServiceAccount, error)
func (*Store) GetSession ¶
func (*Store) GetSessionByRefreshToken ¶
func (*Store) GetSessionByToken ¶
func (*Store) GetSetting ¶
func (*Store) GetUserByAnyEmail ¶
func (*Store) GetUserByEmail ¶
func (*Store) GetUserByPhone ¶
func (*Store) GetUserByUsername ¶
func (*Store) GetUserEmailRecord ¶
func (*Store) GetUserEmails ¶
func (*Store) GetVerification ¶
func (*Store) GetWebhook ¶
func (*Store) HashLegacyTokens ¶
HashLegacyTokens implements store.LegacyTokenHasher. Each table is swept with a bounded select of rows whose hash is NULL and whose plaintext is present, then rewritten row by row: the digest is computed here, not in SQL, so the two SQL backends and mongo convert identically. A row with neither plaintext nor hash is unusable and left alone.
func (*Store) IsRefreshTokenRevoked ¶
IsRefreshTokenRevoked reports whether tokenHash has been recorded as revoked. A miss returns (false, nil); other DB errors propagate.
func (*Store) KVDeleteExpired ¶
KVDeleteExpired implements store.KV.
func (*Store) KVIncrement ¶
KVIncrement implements store.KV.
func (*Store) KVSetNX ¶
func (s *Store) KVSetNX(ctx context.Context, key string, value []byte, ttl time.Duration) (bool, error)
KVSetNX implements store.KV.
func (*Store) ListAPIKeysByApp ¶
func (*Store) ListAPIKeysByUser ¶
func (*Store) ListDelegations ¶
func (s *Store) ListDelegations(ctx context.Context, q *principal.DelegationQuery) ([]*principal.Delegation, error)
func (*Store) ListDevices ¶
func (*Store) ListEnvironments ¶
func (s *Store) ListEnvironments(ctx context.Context, appID id.AppID) ([]*environment.Environment, error)
func (*Store) ListFormConfigs ¶
func (s *Store) ListFormConfigs(ctx context.Context, appID id.AppID) ([]*formconfig.FormConfig, error)
func (*Store) ListInvitations ¶
func (s *Store) ListInvitations(ctx context.Context, orgID id.OrgID) ([]*organization.Invitation, error)
func (*Store) ListInvitationsPage ¶
func (*Store) ListMembers ¶
func (*Store) ListMembersPage ¶
func (*Store) ListOrganizations ¶
func (s *Store) ListOrganizations(ctx context.Context, appID id.AppID) ([]*organization.Organization, error)
func (*Store) ListOrganizationsPage ¶
func (*Store) ListPrincipals ¶
func (s *Store) ListPrincipals(ctx context.Context, q *principal.Query) ([]*principal.Principal, error)
ListPrincipals returns principals matching q. Only non-human principals are stored in authsome_service_accounts, so this never returns users.
func (*Store) ListServiceAccounts ¶
func (s *Store) ListServiceAccounts(ctx context.Context, q *serviceaccount.Query) (*serviceaccount.List, error)
func (*Store) ListSessions ¶
func (*Store) ListSettings ¶
func (*Store) ListTeamsPage ¶
func (*Store) ListUserDevices ¶
func (*Store) ListUserNotifications ¶
func (s *Store) ListUserNotifications(ctx context.Context, userID id.UserID) ([]*notification.Notification, error)
func (*Store) ListUserOrganizations ¶
func (s *Store) ListUserOrganizations(ctx context.Context, userID id.UserID) ([]*organization.Organization, error)
func (*Store) ListUserOrganizationsPage ¶
func (*Store) ListUserSessions ¶
func (*Store) ListUserSessionsPage ¶
func (*Store) ListWebhooks ¶
func (*Store) MarkRefreshTokenReplayed ¶
MarkRefreshTokenReplayed flips an already-revoked token's reason to "replay_detected" and reports whether this call made the change. The conditional UPDATE (reason <> replay_detected) is atomic, so concurrent double-submits and repeated presentations resolve to exactly one firstReplay=true — the engine's storm guard.
func (*Store) MarkRefreshTokenRevoked ¶
func (s *Store) MarkRefreshTokenRevoked(ctx context.Context, tokenHash string, familyID id.SessionFamilyID, reason string) error
MarkRefreshTokenRevoked records tokenHash as revoked. Idempotent: a duplicate insert silently succeeds (the original record wins).
func (*Store) MarkUserEmailVerified ¶
func (*Store) ResolveSettings ¶
func (*Store) RevokeDelegation ¶
RevokeDelegation marks a grant revoked. The revoked_at guard makes a repeat call a no-op rather than moving the timestamp, so a retried revocation cannot rewrite when the revocation actually happened.
func (*Store) RevokeRefreshTokenFamily ¶
func (s *Store) RevokeRefreshTokenFamily(ctx context.Context, familyID id.SessionFamilyID, reason string) error
RevokeRefreshTokenFamily revokes every active session sharing familyID. Each surviving refresh-token hash is also recorded as revoked with reason so later replays of any sibling token are detected. The whole cascade runs inside a single PgTx — on any error it rolls back.
func (*Store) RotateSession ¶
func (*Store) SaveBranding ¶
func (s *Store) SaveBranding(ctx context.Context, b *formconfig.BrandingConfig) error
func (*Store) SeedLegacyInvitation ¶
func (s *Store) SeedLegacyInvitation(ctx context.Context, inv *organization.Invitation) error
func (*Store) SeedLegacyPasswordReset ¶
func (*Store) SeedLegacySession ¶
SeedLegacySession writes sess exactly as a release before token hashing did: plaintext tokens and NULL hashes. It exists so the conformance suite can prove the upgrade path and is refused outside `go test`.
func (*Store) SeedLegacyVerification ¶
SeedLegacyVerification, SeedLegacyPasswordReset and SeedLegacyInvitation write rows the way releases before token hashing did: plaintext and a NULL hash. They exist for the conformance suite and are refused outside `go test`.
func (*Store) SetAppClientConfig ¶
func (*Store) SetAppSessionConfig ¶
func (*Store) SetDefaultEnvironment ¶
func (*Store) SetPrimaryEmail ¶
func (*Store) SetSetting ¶
func (*Store) TouchAPIKey ¶
TouchAPIKey writes last_used_at alone.
func (*Store) TouchSession ¶
func (*Store) UpdateAPIKey ¶
func (*Store) UpdateDevice ¶
func (*Store) UpdateEnvironment ¶
func (s *Store) UpdateEnvironment(ctx context.Context, e *environment.Environment) error
func (*Store) UpdateFormConfig ¶
func (s *Store) UpdateFormConfig(ctx context.Context, fc *formconfig.FormConfig) error
func (*Store) UpdateInvitation ¶
func (s *Store) UpdateInvitation(ctx context.Context, inv *organization.Invitation) error
func (*Store) UpdateMember ¶
func (*Store) UpdateOrganization ¶
func (s *Store) UpdateOrganization(ctx context.Context, o *organization.Organization) error
func (*Store) UpdateServiceAccount ¶
func (s *Store) UpdateServiceAccount(ctx context.Context, svc *serviceaccount.ServiceAccount) error
func (*Store) UpdateSession ¶
func (*Store) UpdateTeam ¶
func (*Store) UpdateVerification ¶
func (*Store) UpdateWebhook ¶
func (*Store) WithTx ¶
WithTx is a best-effort no-op wrapper for now. Real backend transactions require plumbing driver.Tx through every Store method, which is a multi- day refactor deferred to a follow-up PR. Callers that need true atomic cascade semantics should use the dedicated DeleteOrganizationCascade method below — it uses PgTx natively without requiring the full every-method-takes-a-tx refactor.
type TeamModel ¶
type TeamModel struct {
grove.BaseModel `grove:"table:authsome_teams,alias:t"`
ID string `grove:"id,pk"`
OrgID string `grove:"org_id,notnull"`
Name string `grove:"name,notnull"`
Slug string `grove:"slug,notnull"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}
type UserEmailModel ¶
type UserEmailModel struct {
grove.BaseModel `grove:"table:authsome_user_emails,alias:ue"`
ID string `grove:"id,pk"`
UserID string `grove:"user_id,notnull"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
Email string `grove:"email,notnull"`
Verified bool `grove:"verified"`
IsPrimary bool `grove:"is_primary"`
Source string `grove:"source"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
DeletedAt sql.NullTime `grove:"deleted_at"`
}
type UserModel ¶
type UserModel struct {
grove.BaseModel `grove:"table:authsome_users,alias:u"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
Email string `grove:"email,notnull"`
EmailVerified bool `grove:"email_verified"`
FirstName string `grove:"first_name"`
LastName string `grove:"last_name"`
Image string `grove:"image"`
Username string `grove:"username"`
DisplayUsername string `grove:"display_username"`
Phone string `grove:"phone"`
PhoneVerified bool `grove:"phone_verified"`
PasswordHash string `grove:"password_hash"`
Banned bool `grove:"banned"`
BanReason string `grove:"ban_reason"`
BanExpires sql.NullTime `grove:"ban_expires"`
Metadata json.RawMessage `grove:"metadata,type:jsonb"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
DeletedAt sql.NullTime `grove:"deleted_at"`
}
type VerificationModel ¶
type VerificationModel struct {
grove.BaseModel `grove:"table:authsome_verifications,alias:v"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
UserID string `grove:"user_id,notnull"`
Token string `grove:"token,notnull"`
// TokenHash is store.HashToken of the code; Token is empty on rows
// written since hash_credential_tokens and NULL here marks a legacy row.
TokenHash sql.NullString `grove:"token_hash"`
Type string `grove:"type,notnull"`
Attempts int `grove:"attempts,notnull,default:0"`
ExpiresAt time.Time `grove:"expires_at,notnull"`
Consumed bool `grove:"consumed"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
}
type WebhookModel ¶
type WebhookModel struct {
grove.BaseModel `grove:"table:authsome_webhooks,alias:wh"`
ID string `grove:"id,pk"`
AppID string `grove:"app_id,notnull"`
EnvID string `grove:"env_id,notnull"`
URL string `grove:"url,notnull"`
Events json.RawMessage `grove:"events,type:jsonb"`
// Secret is empty once the row has a relay endpoint; see webhook.Webhook.
Secret string `grove:"secret"`
SecretHash string `grove:"secret_hash"`
RelayEndpointID string `grove:"relay_endpoint_id"`
Active bool `grove:"active"`
CreatedAt time.Time `grove:"created_at,notnull,default:now()"`
UpdatedAt time.Time `grove:"updated_at,notnull,default:now()"`
}