Documentation
¶
Index ¶
- Constants
- Variables
- func FedProviderKey(workspaceID string) string
- func GenerateTOTPSecret() ([]byte, error)
- func HashPassword(password string) (string, error)
- func OTPAuthURI(issuer, account, secretB32 string) string
- func ParseTOTPBase32(encoded string) ([]byte, error)
- func TOTPAt(secret []byte, at time.Time) string
- func TOTPBase32(secret []byte) string
- func VerifyPassword(password, phc string) bool
- func VerifyTOTP(secret []byte, code string, now time.Time) bool
- type AccountConfig
- type AccountService
- func (s *AccountService) AdminCreateUser(ctx context.Context, actor *webx.Principal, ...) (User, error)
- func (s *AccountService) AdminSetPassword(ctx context.Context, actor *webx.Principal, targetUserID, newPassword string) error
- func (s *AccountService) DeleteAccount(ctx context.Context, p *webx.Principal) error
- func (s *AccountService) DeleteAccountFor(ctx context.Context, actor *webx.Principal, targetUserID string) error
- func (s *AccountService) ListUsersByIDs(ctx context.Context, ids []string) ([]User, error)
- func (s *AccountService) MarkVerified(ctx context.Context, targetUserID string) error
- func (s *AccountService) RequestPasswordReset(ctx context.Context, rawEmail string) error
- func (s *AccountService) ResendVerificationFor(ctx context.Context, email string) error
- func (s *AccountService) ResetPassword(ctx context.Context, rawEmail, token, newPassword string) error
- func (s *AccountService) ResetPasswordFor(ctx context.Context, targetUserID string) error
- func (s *AccountService) SendVerification(ctx context.Context, p *webx.Principal) error
- func (s *AccountService) VerifyEmail(ctx context.Context, rawEmail, token string) error
- func (s *AccountService) WithAuditor(a Auditor) *AccountService
- func (s *AccountService) WithIdentityHooks(h identity.IdentityHooks) *AccountService
- type Auditor
- type Challenge
- type Clock
- type EmailSender
- type Enrollment
- type FedOIDCProvider
- type FedOption
- type FedProviderRow
- type FedResolver
- type FedService
- func (s *FedService) Callback(ctx context.Context, r *http.Request, code, state string, gate SignupGateCheck) (ThirdPartyLinkResult, error)
- func (s *FedService) DeleteProvider(ctx context.Context, workspaceID string) error
- func (s *FedService) GetProvider(ctx context.Context, workspaceID string) (*FedProviderRow, bool, error)
- func (s *FedService) Start(w http.ResponseWriter, r *http.Request, slug string) error
- func (s *FedService) UpsertProvider(ctx context.Context, ...) (*FedProviderRow, error)
- func (s *FedService) WithSecureCookie(secure bool) *FedService
- type LoginResult
- type MFARepo
- type MFAService
- func (s *MFAService) Disable(ctx context.Context, p *webx.Principal) error
- func (s *MFAService) Enable(ctx context.Context, ipHash string, p *webx.Principal, code string) ([]string, error)
- func (s *MFAService) Enabled(ctx context.Context, userID string) (bool, error)
- func (s *MFAService) RegenerateBackupCodes(ctx context.Context, p *webx.Principal) ([]string, error)
- func (s *MFAService) StartEnrollment(ctx context.Context, p *webx.Principal, accountEmail string) (Enrollment, error)
- func (s *MFAService) Status(ctx context.Context, userID string) (enabled, pending bool, err error)
- func (s *MFAService) VerifyMFA(ctx context.Context, ipHash string, p *webx.Principal, code string) (time.Time, error)
- type NoopEmailSender
- func (NoopEmailSender) SendEmailVerification(ctx context.Context, to, link string) error
- func (NoopEmailSender) SendInvite(ctx context.Context, to, workspaceName, invitationID string) error
- func (NoopEmailSender) SendLoginCode(ctx context.Context, to, code string) error
- func (NoopEmailSender) SendPasswordReset(ctx context.Context, to, link string) error
- type OAuthIdentity
- type OAuthProvider
- type OAuthService
- func (s *OAuthService) Callback(ctx context.Context, r *http.Request, providerName, code, state string, ...) (ThirdPartyLinkResult, error)
- func (s *OAuthService) Names() []string
- func (s *OAuthService) Start(w http.ResponseWriter, r *http.Request, providerName string) error
- func (s *OAuthService) WithSecureCookie(secure bool) *OAuthService
- type PAT
- type Repo
- type Secrets
- type SessionConfig
- type SessionInfo
- type SessionService
- func (s *SessionService) ChangePassword(ctx context.Context, p *webx.Principal, oldPassword, newPassword string) (*LoginResult, error)
- func (s *SessionService) CompleteThirdPartyLogin(ctx context.Context, userID string, jitNew bool, ipHash, userAgent string) (*LoginResult, error)
- func (s *SessionService) ConfirmPassword(ctx context.Context, ipHash string, p *webx.Principal, password string) (time.Time, error)
- func (s *SessionService) FireOnLoginFailed(ctx context.Context, email, ipHash string)
- func (s *SessionService) ListSessions(ctx context.Context, p *webx.Principal) ([]SessionInfo, error)
- func (s *SessionService) ListSessionsFor(ctx context.Context, targetUserID string) ([]SessionInfo, error)
- func (s *SessionService) LoginWithPassword(ctx context.Context, ipHash, userAgent, rawEmail, password string) (*LoginResult, error)
- func (s *SessionService) Logout(ctx context.Context, token string) error
- func (s *SessionService) Me(ctx context.Context, p *webx.Principal) (User, error)
- func (s *SessionService) Register(ctx context.Context, ipHash, userAgent, rawEmail, password, displayName string) (*LoginResult, error)
- func (s *SessionService) RevokeAllSessions(ctx context.Context, p *webx.Principal) error
- func (s *SessionService) RevokeAllSessionsFor(ctx context.Context, targetUserID string) error
- func (s *SessionService) RevokeSessionByID(ctx context.Context, p *webx.Principal, sessionID string) error
- func (s *SessionService) RevokeSessionByIDFor(ctx context.Context, targetUserID, sessionID string) error
- func (s *SessionService) SendCode(ctx context.Context, ipHash, rawEmail string) error
- func (s *SessionService) SignupBlocked(email string) bool
- func (s *SessionService) UpdateProfile(ctx context.Context, p *webx.Principal, displayName, avatarURL string) (User, error)
- func (s *SessionService) VerifyCode(ctx context.Context, ipHash, userAgent, rawEmail, code string) (*LoginResult, error)
- func (s *SessionService) WithHooks(h identity.IdentityHooks) *SessionService
- func (s *SessionService) WithSignupGate(gate SignupGate) *SessionService
- type SignupGate
- type SignupGateCheck
- type ThirdPartyLinkResult
- type TokenService
- func (s *TokenService) CreatePAT(ctx context.Context, p *webx.Principal, name string, ttl time.Duration, ...) (PAT, string, error)
- func (s *TokenService) ListPATs(ctx context.Context, p *webx.Principal) ([]PAT, error)
- func (s *TokenService) ListPATsFor(ctx context.Context, targetUserID string) ([]PAT, error)
- func (s *TokenService) RevokePAT(ctx context.Context, p *webx.Principal, patID string) error
- func (s *TokenService) RevokePATFor(ctx context.Context, targetUserID, patID string) error
- func (s *TokenService) WithPATPrefix(prefix string) *TokenService
- type User
- type WorkspaceSlugLookup
Constants ¶
const ( CodeSealKeyMissing = "E_SEAL_KEY_MISSING" CodeSealFailed = "E_SEAL_FAILED" )
const FedLoginCookie = "tk_fed_oauth"
const FedProviderPrefix = "oidc_fed:"
const FedSecretMask = "***"
const OAuthStateCookie = "tk_oauth_state"
Variables ¶
var ( ErrMFANotEnrolled = errors.New("identity: mfa not enrolled") ErrMFAAlreadyEnabled = errors.New("identity: mfa already enabled") ErrMFAPendingNotReady = errors.New("identity: mfa enrollment pending confirmation") )
ErrMFANotEnrolled and ErrMFAAlreadyConfirmed are the flow-level MFA states handlers translate into webx error envelopes.
var ErrDuplicate = errors.New("duplicate")
var ErrNotFound = errors.New("not found")
Functions ¶
func FedProviderKey ¶
func GenerateTOTPSecret ¶ added in v0.5.0
GenerateTOTPSecret returns 160 bits of fresh TOTP key material (RFC 4226 §4 recommends ≥160 bits; all mainstream authenticator apps accept it).
func HashPassword ¶
func OTPAuthURI ¶ added in v0.5.0
OTPAuthURI builds the otpauth:// enrollment URI (the QR payload the client renders): otpauth://totp/<issuer>:<account>?secret=…&issuer=…&algorithm=SHA1&digits=6&period=30
func ParseTOTPBase32 ¶ added in v0.5.0
ParseTOTPBase32 decodes the unpadded base32 form back to key material.
func TOTPAt ¶ added in v0.5.0
TOTPAt computes the code a legitimate authenticator would display for the secret at the given instant. Servers never generate user-facing codes in production paths — this is the reference computation for tests, seeding, and cross-checks.
func TOTPBase32 ¶ added in v0.5.0
TOTPBase32 renders a secret in the unpadded base32 form every authenticator app's manual-entry field expects.
func VerifyPassword ¶
Types ¶
type AccountConfig ¶
type AccountService ¶
type AccountService struct {
// contains filtered or unexported fields
}
func NewAccountService ¶
func NewAccountService(repo Repo, mail EmailSender, cfg AccountConfig, now Clock) *AccountService
func (*AccountService) AdminCreateUser ¶ added in v0.5.0
func (s *AccountService) AdminCreateUser(ctx context.Context, actor *webx.Principal, rawEmail, displayName, initialPassword string) (User, error)
AdminCreateUser provisions a user from the admin surface (aifengkong #1): no email is sent, no session is established, and the signup gate does not apply — this is the no-SMTP / invite-only provisioning path self-service Register cannot express. The initial password is chosen by the caller (typically generated, shown to the admin exactly once); the framework only hashes and stores it. Fires AfterRegister transactionally so products can bind roles inside the same tx.
func (*AccountService) AdminSetPassword ¶ added in v0.5.0
func (s *AccountService) AdminSetPassword(ctx context.Context, actor *webx.Principal, targetUserID, newPassword string) error
AdminSetPassword sets a target user's password directly from the admin surface (aifengkong #2): hash + store + revoke every session of that user + audit. No email is involved (the enterprise intranet path); the new password is caller-generated and shown to the admin exactly once. Whether a platform-admin target may be reset is the caller's policy decision.
func (*AccountService) DeleteAccount ¶
func (*AccountService) DeleteAccountFor ¶
func (*AccountService) ListUsersByIDs ¶ added in v0.5.0
ListUsersByIDs batch-resolves users for display echo (aifengkong #7): the created_by audit-trail rendering every admin surface needs. Missing ids are skipped (a stale reference renders as absent, not as an error).
func (*AccountService) MarkVerified ¶
func (s *AccountService) MarkVerified(ctx context.Context, targetUserID string) error
func (*AccountService) RequestPasswordReset ¶
func (s *AccountService) RequestPasswordReset(ctx context.Context, rawEmail string) error
func (*AccountService) ResendVerificationFor ¶
func (s *AccountService) ResendVerificationFor(ctx context.Context, email string) error
func (*AccountService) ResetPassword ¶
func (s *AccountService) ResetPassword(ctx context.Context, rawEmail, token, newPassword string) error
func (*AccountService) ResetPasswordFor ¶
func (s *AccountService) ResetPasswordFor(ctx context.Context, targetUserID string) error
func (*AccountService) SendVerification ¶
func (*AccountService) VerifyEmail ¶
func (s *AccountService) VerifyEmail(ctx context.Context, rawEmail, token string) error
func (*AccountService) WithAuditor ¶
func (s *AccountService) WithAuditor(a Auditor) *AccountService
func (*AccountService) WithIdentityHooks ¶ added in v0.5.0
func (s *AccountService) WithIdentityHooks(h identity.IdentityHooks) *AccountService
WithIdentityHooks attaches the identity hook surface (AfterRegister etc.) for the admin provisioning paths.
type EmailSender ¶
type Enrollment ¶ added in v0.5.0
type Enrollment struct {
OTPAuthURI string `json:"otpauth_uri"`
Secret string `json:"secret"`
Issuer string `json:"issuer"`
}
Enrollment is the enroll-start payload: the otpauth:// URI (the QR payload) plus the base32 secret for manual entry. The secret is returned exactly once — only the sealed form is stored.
type FedOIDCProvider ¶
type FedProviderRow ¶
type FedResolver ¶
type FedResolver interface {
Resolve(ctx context.Context, issuerURL, clientID, clientSecret, scopes string) (FedOIDCProvider, error)
}
type FedService ¶
type FedService struct {
// contains filtered or unexported fields
}
func NewFedService ¶
func NewFedService(repo Repo, slugLookup WorkspaceSlugLookup, resolver FedResolver, now Clock, opts ...FedOption) *FedService
func (*FedService) Callback ¶
func (s *FedService) Callback(ctx context.Context, r *http.Request, code, state string, gate SignupGateCheck) (ThirdPartyLinkResult, error)
func (*FedService) DeleteProvider ¶
func (s *FedService) DeleteProvider(ctx context.Context, workspaceID string) error
func (*FedService) GetProvider ¶
func (s *FedService) GetProvider(ctx context.Context, workspaceID string) (*FedProviderRow, bool, error)
func (*FedService) Start ¶
func (s *FedService) Start(w http.ResponseWriter, r *http.Request, slug string) error
func (*FedService) UpsertProvider ¶
func (s *FedService) UpsertProvider(ctx context.Context, workspaceID, issuerURL, clientID, clientSecret, scopes string) (*FedProviderRow, error)
func (*FedService) WithSecureCookie ¶
func (s *FedService) WithSecureCookie(secure bool) *FedService
type LoginResult ¶
type MFARepo ¶ added in v0.5.0
type MFARepo interface {
// UpsertPendingMFA stores a freshly generated (sealed) secret for the
// user, replacing any previous enrollment — pending or confirmed. Callers
// must refuse to overwrite a confirmed enrollment (re-enrollment goes
// through disable first).
UpsertPendingMFA(ctx context.Context, userID, secretSealed string, now time.Time) error
// GetMFA returns the sealed secret and the confirmation stamp;
// ok=false when the user has no enrollment row.
GetMFA(ctx context.Context, userID string) (secretSealed string, confirmedAt *time.Time, ok bool, err error)
// ConfirmMFA stamps confirmed_at (the enroll→enable transition).
ConfirmMFA(ctx context.Context, userID string, now time.Time) error
// DeleteMFA removes the enrollment and all backup codes (disable).
DeleteMFA(ctx context.Context, userID string) error
// ReplaceBackupCodes swaps the pending backup-code set (regenerate, and
// the initial set at enable time).
ReplaceBackupCodes(ctx context.Context, userID string, codeHashes []string, now time.Time) error
// ConsumeBackupCode marks one pending code consumed; ok=false when no
// pending code matches the hash. Single UPDATE — consume-once is atomic.
ConsumeBackupCode(ctx context.Context, userID, codeHash string, now time.Time) (ok bool, err error)
// ConfirmSessionMFA stamps mfa_confirmed_at on a live session (the
// step-up / born-confirmed stamp对称列 of ConfirmSessionPassword).
ConfirmSessionMFA(ctx context.Context, sessionID string, now time.Time) error
}
MFARepo is the persistence seam of the TOTP + backup-code flows (ADR 0013 batch 2). Deliberately separate from Repo: identity consumers that never mount MFA keep their existing fakes intact.
type MFAService ¶ added in v0.5.0
type MFAService struct {
// contains filtered or unexported fields
}
MFAService implements the TOTP + backup-code flows: enroll (start) / enable (verify first code) / disable (step-up guarded at the mount site) / regenerate backup codes (ditto) / verify-mfa (the AAL2 step-up stamping endpoint). Secrets are sealed through the same Secrets seam as every other stored credential — with no seal key configured enrollment is refused (E_SEAL_KEY_MISSING), per the framework's tenant-credential constraint.
Scope discipline (ADR 0013): strictly TOTP + backup codes — WebAuthn, recovery flows, and SMS are not here; login-integrated MFA (a challenge inside the login flow) is the next consumer's step.
func NewMFAService ¶ added in v0.5.0
func NewMFAService(repo MFARepo, sessions *SessionService, secrets Secrets, issuer string, now Clock) *MFAService
func (*MFAService) Disable ¶ added in v0.5.0
Disable removes the enrollment and every backup code. It is mount-site step-up guarded (MFAChangeGuard in identityhttp.Deps) — mirroring GitHub's sudo-guarded 2FA settings — and it revokes all the user's sessions so a device holding a stolen MFA-proofed session keeps nothing.
func (*MFAService) Enable ¶ added in v0.5.0
func (s *MFAService) Enable(ctx context.Context, ipHash string, p *webx.Principal, code string) ([]string, error)
Enable verifies the first code against the pending secret, confirms the enrollment, issues the initial backup-code set (returned once), and stamps the current session — completing the proof this very code constitutes.
func (*MFAService) Enabled ¶ added in v0.5.0
Enabled reports whether the user has a confirmed enrollment.
func (*MFAService) RegenerateBackupCodes ¶ added in v0.5.0
func (s *MFAService) RegenerateBackupCodes(ctx context.Context, p *webx.Principal) ([]string, error)
RegenerateBackupCodes swaps in a fresh backup-code set, returning the plaintext codes exactly once.
func (*MFAService) StartEnrollment ¶ added in v0.5.0
func (s *MFAService) StartEnrollment(ctx context.Context, p *webx.Principal, accountEmail string) (Enrollment, error)
StartEnrollment generates and stores a pending (unconfirmed) TOTP secret. Re-enrollment while an enrollment is already confirmed is refused — disable first (the GitHub-shaped flow; keeps a hijacked session from silently swapping a victim's factor).
func (*MFAService) Status ¶ added in v0.5.0
Status is the settings-page view: enabled (confirmed enrollment) and pending (enrollment started, first code not yet verified).
func (*MFAService) VerifyMFA ¶ added in v0.5.0
func (s *MFAService) VerifyMFA(ctx context.Context, ipHash string, p *webx.Principal, code string) (time.Time, error)
VerifyMFA is the AAL2 step-up stamp: verify a TOTP or a backup code, then stamp mfa_confirmed_at on the caller's session. Failed attempts go through the same attempt limiter as login and confirm-password, so a hijacked session cannot brute-force codes. Returns the stamp time.
type NoopEmailSender ¶ added in v0.4.1
type NoopEmailSender struct{}
NoopEmailSender satisfies EmailSender with every send as a no-op (orkome F12): products that only use code login embed it and override exactly the sends they need, instead of hand-writing no-op stubs for SendInvite / SendPasswordReset / SendEmailVerification on every adapter.
type DevMailer struct {
app.NoopEmailSender // invites/resets/verifications silently dropped
}
func (DevMailer) SendLoginCode(ctx context.Context, to, code string) error { ... }
func (NoopEmailSender) SendEmailVerification ¶ added in v0.4.1
func (NoopEmailSender) SendEmailVerification(ctx context.Context, to, link string) error
func (NoopEmailSender) SendInvite ¶ added in v0.4.1
func (NoopEmailSender) SendInvite(ctx context.Context, to, workspaceName, invitationID string) error
func (NoopEmailSender) SendLoginCode ¶ added in v0.4.1
func (NoopEmailSender) SendLoginCode(ctx context.Context, to, code string) error
func (NoopEmailSender) SendPasswordReset ¶ added in v0.4.1
func (NoopEmailSender) SendPasswordReset(ctx context.Context, to, link string) error
type OAuthIdentity ¶
type OAuthProvider ¶
type OAuthService ¶
type OAuthService struct {
// contains filtered or unexported fields
}
func NewOAuthService ¶
func NewOAuthService(repo Repo, providers []OAuthProvider, now Clock) *OAuthService
func (*OAuthService) Callback ¶
func (s *OAuthService) Callback(ctx context.Context, r *http.Request, providerName, code, state string, gate SignupGateCheck) (ThirdPartyLinkResult, error)
func (*OAuthService) Names ¶
func (s *OAuthService) Names() []string
func (*OAuthService) Start ¶
func (s *OAuthService) Start(w http.ResponseWriter, r *http.Request, providerName string) error
func (*OAuthService) WithSecureCookie ¶
func (s *OAuthService) WithSecureCookie(secure bool) *OAuthService
type Repo ¶
type Repo interface {
UpsertUserByEmail(ctx context.Context, email string, now time.Time) (User, error)
GetUser(ctx context.Context, id string) (User, error)
GetUserByEmail(ctx context.Context, email string) (User, bool, error)
// ListUsersByIDs batch-resolves users by id (missing ids skipped) — the
// display echo for created_by audit trails on admin surfaces.
ListUsersByIDs(ctx context.Context, ids []string) ([]User, error)
UpdateProfile(ctx context.Context, id, displayName, avatarURL string) (User, error)
CreateUserWithPassword(ctx context.Context, email, passwordHash, displayName string) (User, error)
SetPasswordHash(ctx context.Context, userID, passwordHash string, now time.Time) error
SetEmailVerified(ctx context.Context, userID string, at time.Time) error
FindOAuthAccount(ctx context.Context, provider, subject string) (userID string, ok bool, err error)
LinkOAuthAccount(ctx context.Context, provider, subject, userID, emailAtLink string, now time.Time) error
GetFedProvider(ctx context.Context, workspaceID string) (*FedProviderRow, bool, error)
UpsertFedProvider(ctx context.Context, row *FedProviderRow, now time.Time) error
DeleteFedProvider(ctx context.Context, workspaceID string) error
CreateChallenge(ctx context.Context, email, kind, secretHash string, expiresAt time.Time) error
LatestPendingChallenge(ctx context.Context, email, kind string) (*Challenge, error)
IncChallengeAttempts(ctx context.Context, id string) error
ConsumeChallenge(ctx context.Context, id string) error
CreateSession(ctx context.Context, in webx.SessionCreate) (token string, exp time.Time, err error)
VerifySession(ctx context.Context, token string, now time.Time) (*webx.Principal, error)
// ConfirmSessionPassword stamps password_confirmed_at on a live session
// (step-up): POST /auth/confirm-password → RequireRecentAuth unblocks.
ConfirmSessionPassword(ctx context.Context, sessionID string, now time.Time) error
RenewSession(ctx context.Context, token string, now time.Time) (exp time.Time, renewed bool, err error)
RevokeSession(ctx context.Context, token string) error
RevokeAllUserSessions(ctx context.Context, userID string) error
ListUserSessions(ctx context.Context, userID string) ([]SessionInfo, error)
RevokeUserSessionByID(ctx context.Context, userID, sessionID string, now time.Time) error
CreatePAT(ctx context.Context, userID, name, tokenHash, prefix string, expiresAt *time.Time, scope *webx.CredentialScope) (PAT, error)
ResolvePAT(ctx context.Context, token string, now time.Time) (*webx.Principal, error)
ListPATs(ctx context.Context, userID string) ([]PAT, error)
RevokePAT(ctx context.Context, userID, patID string, now time.Time) error
CountRecentAttempts(ctx context.Context, ipHash, identity string, since time.Time) (int, error)
RecordAttempt(ctx context.Context, ipHash, identity string, success bool, at time.Time) error
CleanupAttempts(ctx context.Context, before time.Time) error
RunInTx(ctx context.Context, fn func(ctx context.Context, tx pgx.Tx) error) error
CreateUserWithPasswordTx(ctx context.Context, tx pgx.Tx, email, passwordHash, displayName string) (User, error)
SoftDeleteUserTx(ctx context.Context, tx pgx.Tx, userID string, now time.Time) error
}
type SessionConfig ¶
type SessionInfo ¶
type SessionInfo struct {
ID string `json:"id"`
IPHash string `json:"ip_hash"`
UserAgent string `json:"user_agent"`
LastSeenAt time.Time `json:"last_seen_at"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
Current bool `json:"current"`
ImpersonatedBy string `json:"impersonated_by,omitempty"`
}
type SessionService ¶
type SessionService struct {
// contains filtered or unexported fields
}
func NewSessionService ¶
func NewSessionService(repo Repo, mail EmailSender, cfg SessionConfig, sessionTTL, _ time.Duration, now Clock) *SessionService
func (*SessionService) ChangePassword ¶
func (s *SessionService) ChangePassword(ctx context.Context, p *webx.Principal, oldPassword, newPassword string) (*LoginResult, error)
func (*SessionService) CompleteThirdPartyLogin ¶
func (s *SessionService) CompleteThirdPartyLogin(ctx context.Context, userID string, jitNew bool, ipHash, userAgent string) (*LoginResult, error)
func (*SessionService) ConfirmPassword ¶ added in v0.4.0
func (s *SessionService) ConfirmPassword(ctx context.Context, ipHash string, p *webx.Principal, password string) (time.Time, error)
ConfirmPassword re-verifies the caller's password and stamps the current session (step-up). It backs the two-phase protocol of webx.RequireRecentAuth: 403 E_REAUTH_REQUIRED → confirm here → retry the original request. Failed confirmations go through the same attempt limiter as login (a hijacked session must not brute-force the password).
func (*SessionService) FireOnLoginFailed ¶
func (s *SessionService) FireOnLoginFailed(ctx context.Context, email, ipHash string)
func (*SessionService) ListSessions ¶
func (s *SessionService) ListSessions(ctx context.Context, p *webx.Principal) ([]SessionInfo, error)
func (*SessionService) ListSessionsFor ¶
func (s *SessionService) ListSessionsFor(ctx context.Context, targetUserID string) ([]SessionInfo, error)
func (*SessionService) LoginWithPassword ¶
func (s *SessionService) LoginWithPassword(ctx context.Context, ipHash, userAgent, rawEmail, password string) (*LoginResult, error)
func (*SessionService) Logout ¶
func (s *SessionService) Logout(ctx context.Context, token string) error
func (*SessionService) Register ¶
func (s *SessionService) Register(ctx context.Context, ipHash, userAgent, rawEmail, password, displayName string) (*LoginResult, error)
func (*SessionService) RevokeAllSessions ¶
func (*SessionService) RevokeAllSessionsFor ¶
func (s *SessionService) RevokeAllSessionsFor(ctx context.Context, targetUserID string) error
func (*SessionService) RevokeSessionByID ¶
func (*SessionService) RevokeSessionByIDFor ¶
func (s *SessionService) RevokeSessionByIDFor(ctx context.Context, targetUserID, sessionID string) error
func (*SessionService) SendCode ¶
func (s *SessionService) SendCode(ctx context.Context, ipHash, rawEmail string) error
func (*SessionService) SignupBlocked ¶
func (s *SessionService) SignupBlocked(email string) bool
func (*SessionService) UpdateProfile ¶
func (*SessionService) VerifyCode ¶
func (s *SessionService) VerifyCode(ctx context.Context, ipHash, userAgent, rawEmail, code string) (*LoginResult, error)
func (*SessionService) WithHooks ¶
func (s *SessionService) WithHooks(h identity.IdentityHooks) *SessionService
func (*SessionService) WithSignupGate ¶
func (s *SessionService) WithSignupGate(gate SignupGate) *SessionService
type SignupGate ¶
type SignupGateCheck ¶
type ThirdPartyLinkResult ¶
type TokenService ¶
type TokenService struct {
// contains filtered or unexported fields
}
func NewTokenService ¶
func NewTokenService(repo Repo, auditor Auditor, now Clock) *TokenService
func (*TokenService) ListPATsFor ¶
func (*TokenService) RevokePATFor ¶
func (s *TokenService) RevokePATFor(ctx context.Context, targetUserID, patID string) error
func (*TokenService) WithPATPrefix ¶
func (s *TokenService) WithPATPrefix(prefix string) *TokenService
type User ¶
type User struct {
ID string `json:"id"`
Email string `json:"email"`
DisplayName string `json:"display_name"`
AvatarURL string `json:"avatar_url,omitempty"`
Status string `json:"status"`
IsPlatformAdmin bool `json:"is_platform_admin"`
EmailVerified bool `json:"email_verified"`
PasswordHash string `json:"-"`
CreatedAt time.Time `json:"created_at"`
// UpdatedBy is the last human modifier (self-edit = the user themself;
// nil for system paths). The audit-trail echo for profile changes.
UpdatedBy string `json:"updated_by,omitempty"`
}