webapp

package
v0.0.0-...-cde6bcd Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2025 License: Apache-2.0 Imports: 57 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AuthflowRouteLogin   = "/login"
	AuthflowRouteSignup  = "/signup"
	AuthflowRoutePromote = "/flows/promote_user"
	AuthflowRouteReauth  = "/reauth"
	// AuthflowRouteSignupLogin is login because login page has passkey.
	AuthflowRouteSignupLogin = AuthflowRouteLogin

	AuthflowRouteTerminateOtherSessions = "/authflow/terminate_other_sessions"
	// nolint: gosec
	AuthflowRoutePromptCreatePasskey = "/authflow/prompt_create_passkey"
	AuthflowRouteViewRecoveryCode    = "/authflow/view_recovery_code"
	// nolint: gosec
	AuthflowRouteCreatePassword = "/authflow/create_password"
	// nolint: gosec
	AuthflowRouteChangePassword = "/authflow/change_password"
	// nolint: gosec
	AuthflowRouteEnterPassword     = "/authflow/enter_password"
	AuthflowRouteEnterRecoveryCode = "/authflow/enter_recovery_code"
	AuthflowRouteEnterOOBOTP       = "/authflow/enter_oob_otp"
	AuthflowRouteWhatsappOTP       = "/authflow/whatsapp_otp"
	AuthflowRouteOOBOTPLink        = "/authflow/oob_otp_link"
	AuthflowRouteEnterTOTP         = "/authflow/enter_totp"
	AuthflowRouteSetupTOTP         = "/authflow/setup_totp"
	AuthflowRouteSetupOOBOTP       = "/authflow/setup_oob_otp"
	// nolint: gosec
	AuthflowRouteUsePasskey = "/authflow/use_passkey"
	// nolint: gosec
	AuthflowRouteForgotPassword = "/authflow/forgot_password"
	// nolint: gosec
	AuthflowRouteForgotPasswordOTP = "/authflow/forgot_password/otp"
	// nolint: gosec
	AuthflowRouteForgotPasswordSuccess = "/authflow/forgot_password/success"
	// nolint: gosec
	AuthflowRouteResetPassword = "/authflow/reset_password"
	// nolint: gosec
	AuthflowRouteResetPasswordSuccess = "/authflow/reset_password/success"
	AuthflowRouteWechat               = "/authflow/wechat"

	// The following routes are dead ends.
	AuthflowRouteAccountStatus   = "/authflow/account_status"
	AuthflowRouteNoAuthenticator = "/authflow/no_authenticator"

	AuthflowRouteFinishFlow = "/authflow/finish"
)
View Source
const AuthflowQueryKey = "x_step"
View Source
const CSRFFieldName = "gorilla.csrf.Token"

CSRFFieldName is the same as the default, but public.

View Source
const InlinePreviewPathPrefix = "/preview/"
View Source
const (
	QueryBackURL = "q_back_url"
)
View Source
const SessionExpiryDuration = interaction.GraphLifetime

Variables

View Source
var CSRFCookieDef = &httputil.CookieDef{
	NameSuffix:        "csrf_token",
	Path:              "/",
	AllowScriptAccess: false,
	SameSite:          http.SameSiteNoneMode,
	MaxAge:            &CSRFCookieMaxAge,
}
View Source
var CSRFCookieMaxAge = int(duration.UserInteraction.Seconds())
View Source
var CSRFDebugCookieSameSiteLaxDef = &httputil.CookieDef{
	NameSuffix:        "debug_csrf_same_site_lax",
	Path:              "/",
	AllowScriptAccess: false,
	SameSite:          http.SameSiteLaxMode,
	MaxAge:            &CSRFCookieMaxAge,
}
View Source
var CSRFDebugCookieSameSiteNoneDef = &httputil.CookieDef{
	NameSuffix:        "debug_csrf_same_site_none",
	Path:              "/",
	AllowScriptAccess: false,
	SameSite:          http.SameSiteNoneMode,
	MaxAge:            &CSRFCookieMaxAge,
}
View Source
var CSRFDebugCookieSameSiteOmitDef = &httputil.CookieDef{
	NameSuffix:        "debug_csrf_same_site_omit",
	Path:              "/",
	AllowScriptAccess: false,
	SameSite:          http.SameSiteDefaultMode,
	MaxAge:            &CSRFCookieMaxAge,
}
View Source
var CSRFDebugCookieSameSiteStrictDef = &httputil.CookieDef{
	NameSuffix:        "debug_csrf_same_site_strict",
	Path:              "/",
	AllowScriptAccess: false,
	SameSite:          http.SameSiteStrictMode,
	MaxAge:            &CSRFCookieMaxAge,
}
View Source
var ColorSchemeCookieDef = &httputil.CookieDef{
	NameSuffix: "x_color_scheme",
	Path:       "/",
	SameSite:   http.SameSiteNoneMode,
}

ColorSchemeCookieDef is a HTTP session cookie.

View Source
var ErrInvalidSession = WebUIInvalidSession.New("session expired or invalid")
View Source
var ErrSessionCompleted = WebUISessionCompleted.New("session completed")
View Source
var ErrSessionNotFound = WebUIInvalidSession.New("session not found")
View Source
var ErrSessionStepMismatch = WebUIInvalidSession.New("session step does match request path")
View Source
var PlatformCookieDef = &httputil.CookieDef{
	NameSuffix: "platform",
	Path:       "/",
	SameSite:   http.SameSiteNoneMode,
}

PlatformCookieDef is a HTTP session cookie.

View Source
var UILocalesCookieDef = &httputil.CookieDef{
	NameSuffix: "ui_locales",
	Path:       "/",
	SameSite:   http.SameSiteNoneMode,
}

UILocalesCookieDef is a HTTP session cookie.

View Source
var VisitorIDCookieDef = &httputil.CookieDef{
	NameSuffix:        "visitor_id",
	Path:              "/",
	AllowScriptAccess: false,
	SameSite:          http.SameSiteNoneMode,
	MaxAge:            &visitorIDCookieMaxAge,
}
View Source
var WeChatRedirectURICookieDef = &httputil.CookieDef{
	NameSuffix: "wechat_redirect_uri",
	Path:       "/",
	SameSite:   http.SameSiteNoneMode,
}

WeChatRedirectURICookieDef is a HTTP session cookie.

View Source
var WebUIInvalidSession = apierrors.Invalid.WithReason("WebUIInvalidSession")
View Source
var WebUISessionCompleted = apierrors.Invalid.WithReason("WebUISessionCompleted").SkipLoggingToExternalService()

Functions

func DerivePostLoginRedirectURIFromRequest

func DerivePostLoginRedirectURIFromRequest(r *http.Request, clientResolver OAuthClientResolver, uiConfig *config.UIConfig) string

func GetAccountRecoveryIdentificationOptions

func GetAccountRecoveryIdentificationOptions(f *authflow.FlowResponse) []declarative.AccountRecoveryIdentificationOption

As IntentAccountRecoveryFlowStepIdentify has it's own IdentificationData type to narrow down Identification as {"email", "phone"}, we imitate the same logic in GetIdentificationOptions here

func GetColorScheme

func GetColorScheme(ctx context.Context) string

func GetMostAppropriateIdentification

func GetMostAppropriateIdentification(ctx context.Context, f *authflow.FlowResponse, loginID string, loginIDInputType string) config.AuthenticationFlowIdentification

func GetRedirectURI

func GetRedirectURI(r *http.Request, trustProxy bool, defaultURI string) string

func GetVisitorID

func GetVisitorID(ctx context.Context) string

func IntlMiddleware

func IntlMiddleware(next http.Handler) http.Handler

func IsAccountRecoveryIdentifyStepBotProtectionRequired

func IsAccountRecoveryIdentifyStepBotProtectionRequired(identificationType config.AuthenticationFlowAccountRecoveryIdentification, f *authflow.FlowResponse) (bool, error)

func IsAuthenticateStepBotProtectionRequired

func IsAuthenticateStepBotProtectionRequired(authenticationType config.AuthenticationFlowAuthentication, f *authflow.FlowResponse) (bool, error)

func IsCreateAuthenticatorStepBotProtectionRequired

func IsCreateAuthenticatorStepBotProtectionRequired(authenticationType config.AuthenticationFlowAuthentication, f *authflow.FlowResponse) (bool, error)

func IsIdentifyStepBotProtectionRequired

func IsIdentifyStepBotProtectionRequired(identificationType config.AuthenticationFlowIdentification, f *authflow.FlowResponse) (bool, error)

func IsInlinePreviewPageRequest

func IsInlinePreviewPageRequest(r *http.Request) bool

func MakeRelativeURL

func MakeRelativeURL(path string, inQuery url.Values) *url.URL

func MakeURL

func MakeURL(u *url.URL, path string, inQuery url.Values) *url.URL

func PreferredLanguageTagsFromRequest

func PreferredLanguageTagsFromRequest(r *http.Request) (out []string)

func PreserveQuery

func PreserveQuery(q url.Values) url.Values

func ResolveClientURI

func ResolveClientURI(client *config.OAuthClientConfig, uiConfig *config.UIConfig) string

func ResolvePostLogoutRedirectURI

func ResolvePostLogoutRedirectURI(client *config.OAuthClientConfig, givenPostLogoutRedirectURI string, uiConfig *config.UIConfig) string

func WithColorScheme

func WithColorScheme(ctx context.Context, colorScheme string) context.Context

func WithSession

func WithSession(ctx context.Context, session *Session) context.Context

func WithVisitorID

func WithVisitorID(ctx context.Context, visitorID string) context.Context

Types

type AllowFrameAncestorsFromCustomUI

type AllowFrameAncestorsFromCustomUI bool

type AllowFrameAncestorsFromEnv

type AllowFrameAncestorsFromEnv bool

type AnonymousIdentityProvider

type AnonymousIdentityProvider interface {
	ParseRequestUnverified(requestJWT string) (r *anonymous.Request, err error)
}

type AnonymousTokenInput

type AnonymousTokenInput struct {
	JWT           string
	PromotionCode string
}

func (*AnonymousTokenInput) GetAnonymousRequestToken

func (i *AnonymousTokenInput) GetAnonymousRequestToken() string

func (*AnonymousTokenInput) GetPromotionCode

func (i *AnonymousTokenInput) GetPromotionCode() string

func (*AnonymousTokenInput) SignUpAnonymousUserWithoutKey

func (i *AnonymousTokenInput) SignUpAnonymousUserWithoutKey() bool

type AnonymousUserPromotionService

type AnonymousUserPromotionService struct {
	Anonymous AnonymousIdentityProvider
	Clock     clock.Clock
}

func (*AnonymousUserPromotionService) ConvertLoginHintToInput

func (r *AnonymousUserPromotionService) ConvertLoginHintToInput(loginHintString string) (*AnonymousTokenInput, error)

type Authflow

type Authflow struct {
	// AllScreens is x_step => screen.
	AllScreens map[string]*AuthflowScreen `json:"all_screens,omitempty"`
}

Authflow remembers all seen screens. The screens could come from more than 1 flow. We intentionally DO NOT clear screens when a different flow is created. As long as the browser has a reference to x_step, a screen can be retrieved. This design is important to ensure traversing browser history will not cause flow not found error. See https://github.com/authgear/authgear-server/issues/3452

type AuthflowDelayedUIScreenData

type AuthflowDelayedUIScreenData struct {
	TargetResult *Result `json:"target_result,omitempty"`
}

type AuthflowFinishedUIScreenData

type AuthflowFinishedUIScreenData struct {
	FlowType          authflow.FlowType `json:"flow_type,omitempty"`
	FinishRedirectURI string            `json:"finish_redirect_uri,omitempty"`
}

type AuthflowNavigator

type AuthflowNavigator struct {
	Endpoints       AuthflowNavigatorEndpointsProvider
	OAuthStateStore AuthflowNavigatorOAuthStateStore
}

func (*AuthflowNavigator) Navigate

func (n *AuthflowNavigator) Navigate(ctx context.Context, s *AuthflowScreenWithFlowResponse, r *http.Request, webSessionID string, result *Result)

func (*AuthflowNavigator) NavigateChangePasswordSuccessPage

func (n *AuthflowNavigator) NavigateChangePasswordSuccessPage(s *AuthflowScreen, r *http.Request, webSessionID string) (result *Result)

func (*AuthflowNavigator) NavigateNonRecoverableError

func (n *AuthflowNavigator) NavigateNonRecoverableError(r *http.Request, u *url.URL, e error)

func (*AuthflowNavigator) NavigateResetPasswordSuccessPage

func (n *AuthflowNavigator) NavigateResetPasswordSuccessPage() string

func (*AuthflowNavigator) NavigateSelectAccount

func (n *AuthflowNavigator) NavigateSelectAccount(result *Result)

func (*AuthflowNavigator) NavigateVerifyBotProtection

func (n *AuthflowNavigator) NavigateVerifyBotProtection(result *Result)

type AuthflowNavigatorEndpointsProvider

type AuthflowNavigatorEndpointsProvider interface {
	ErrorEndpointURL() *url.URL
	SelectAccountEndpointURL() *url.URL
	VerifyBotProtectionEndpointURL() *url.URL
}

type AuthflowNavigatorOAuthStateStore

type AuthflowNavigatorOAuthStateStore interface {
	GenerateState(ctx context.Context, state *webappoauth.WebappOAuthState) (stateToken string, err error)
}

type AuthflowScreen

type AuthflowScreen struct {
	// Store FinishedUIScreenData when the flow is finish
	FinishedUIScreenData *AuthflowFinishedUIScreenData `json:"finished_ui_screen_data,omitempty"`
	// Store DelayedUIScreenData when injecting screen between two steps
	DelayedUIScreenData *AuthflowDelayedUIScreenData `json:"delayed_ui_screen_data,omitempty"`
	// PreviousXStep is the x_step of the screen that leads to this screen.
	PreviousXStep string `json:"previous_x_step,omitempty"`
	// PreviousInput is the input that leads to this screen.
	// It can be nil.
	PreviousInput map[string]interface{} `json:"previous_input,omitempty"`
	// StateToken is always present.
	StateToken *AuthflowStateToken `json:"state_token,omitempty"`
	// BranchStateToken is only present when the underlying authflow step has branches.
	BranchStateToken *AuthflowStateToken `json:"branch_state_token,omitempty"`
	// TakenBranchIndex tracks the taken branch.
	TakenBranchIndex *int `json:"taken_branch_index,omitempty"`
	// TakenChannel tracks the taken channel.
	TakenChannel model.AuthenticatorOOBChannel `json:"taken_channel,omitempty"`
	// WechatCallbackData is only relevant for wechat login.
	WechatCallbackData *AuthflowWechatCallbackData `json:"wechat_callback_data,omitempty"`
	// IsBotProtectionRequired will be used to determine whether to navigate to bot protection verification screen.
	IsBotProtectionRequired bool `json:"is_bot_protection_required,omitempty"`
}

AuthflowScreen represents a screen in the webapp. A screen typically corresponds to a step in an authflow. Some steps in an authflow can have branches. In order to be able to switch between branches, we need to remember the state that has branches.

func NewAuthflowScreenWithResult

func NewAuthflowScreenWithResult(previousXStep string, targetResult *Result) *AuthflowScreen

type AuthflowScreenWithFlowResponse

type AuthflowScreenWithFlowResponse struct {
	Screen                       *AuthflowScreen
	StateTokenFlowResponse       *authflow.FlowResponse
	BranchStateTokenFlowResponse *authflow.FlowResponse
}

func NewAuthflowScreenWithFlowResponse

func NewAuthflowScreenWithFlowResponse(flowResponse *authflow.FlowResponse, previousXStep string, previousInput map[string]interface{}) *AuthflowScreenWithFlowResponse

func UpdateAuthflowScreenWithFlowResponse

func UpdateAuthflowScreenWithFlowResponse(screen *AuthflowScreenWithFlowResponse, flowResponse *authflow.FlowResponse) *AuthflowScreenWithFlowResponse

func (*AuthflowScreenWithFlowResponse) Advance

func (s *AuthflowScreenWithFlowResponse) Advance(route string, result *Result)

Advance is for advancing to another page to drive the authflow.

func (*AuthflowScreenWithFlowResponse) AdvanceWithQuery

func (s *AuthflowScreenWithFlowResponse) AdvanceWithQuery(route string, result *Result, query url.Values)

func (*AuthflowScreenWithFlowResponse) HasBranchToTake

func (s *AuthflowScreenWithFlowResponse) HasBranchToTake() bool

func (*AuthflowScreenWithFlowResponse) InheritTakenBranchState

func (s *AuthflowScreenWithFlowResponse) InheritTakenBranchState(from *AuthflowScreenWithFlowResponse)

func (*AuthflowScreenWithFlowResponse) Navigate

func (s *AuthflowScreenWithFlowResponse) Navigate(ctx context.Context, navigator Navigator, r *http.Request, webSessionID string, result *Result)

func (*AuthflowScreenWithFlowResponse) RedirectToFinish

func (s *AuthflowScreenWithFlowResponse) RedirectToFinish(route string, result *Result)

RedirectToFinish is a fix for https://linear.app/authgear/issue/DEV-1793/investigate-sign-in-directly-with-httpsaccountsportalauthgearcom-crash We need Turbo to visit /finish with a full browser redirect, so CSP and connect-src will not kick in.

func (*AuthflowScreenWithFlowResponse) TakeBranch

type AuthflowStateToken

type AuthflowStateToken struct {
	XStep      string `json:"x_step"`
	StateToken string `json:"state_token"`
}

AuthflowStateToken pairs x_step with its underlying state_token.

func NewAuthflowStateToken

func NewAuthflowStateToken(flowResponse *authflow.FlowResponse) *AuthflowStateToken

type AuthflowWechatCallbackData

type AuthflowWechatCallbackData struct {
	State            string `json:"state"`
	Code             string `json:"code,omitempty"`
	Error            string `json:"error,omitempty"`
	ErrorDescription string `json:"error_description,omitempty"`
}

type CSRFDebugMiddleware

type CSRFDebugMiddleware struct {
	Cookies CookieManager
}

func (*CSRFDebugMiddleware) Handle

func (m *CSRFDebugMiddleware) Handle(next http.Handler) http.Handler

type ColorSchemeMiddleware

type ColorSchemeMiddleware struct {
	Cookies CookieManager
}

func (*ColorSchemeMiddleware) Handle

func (m *ColorSchemeMiddleware) Handle(next http.Handler) http.Handler

type ContextHolderMiddleware

type ContextHolderMiddleware struct {
	Logger ContextHolderMiddlewareLogger
}

func (*ContextHolderMiddleware) Handle

type ContextHolderMiddlewareLogger

type ContextHolderMiddlewareLogger struct{ *log.Logger }

func NewContextHolderMiddlewareLogger

func NewContextHolderMiddlewareLogger(lf *log.Factory) ContextHolderMiddlewareLogger

type CookieManager

type CookieManager interface {
	GetCookie(r *http.Request, def *httputil.CookieDef) (*http.Cookie, error)
	ValueCookie(def *httputil.CookieDef, value string) *http.Cookie
	ClearCookie(def *httputil.CookieDef) *http.Cookie
}

type CookiesGetter

type CookiesGetter interface {
	GetCookies() []*http.Cookie
}

type DynamicCSPMiddleware

type DynamicCSPMiddleware struct {
	Cookies                         CookieManager
	OAuthConfig                     *config.OAuthConfig
	AllowedFrameAncestorsFromEnv    config.AllowedFrameAncestors
	AllowFrameAncestorsFromEnv      AllowFrameAncestorsFromEnv
	AllowFrameAncestorsFromCustomUI AllowFrameAncestorsFromCustomUI
}

func (*DynamicCSPMiddleware) Handle

func (m *DynamicCSPMiddleware) Handle(next http.Handler) http.Handler

type ErrorService

type ErrorService struct {
	AppID       config.AppID
	Cookie      ErrorTokenCookieDef
	RedisHandle *appredis.Handle
	Cookies     CookieManager
}

func (*ErrorService) GetDelRecoverableError

func (c *ErrorService) GetDelRecoverableError(ctx context.Context, w http.ResponseWriter, r *http.Request) (*ErrorState, bool)

func (*ErrorService) GetNonRecoverableError

func (c *ErrorService) GetNonRecoverableError(r *http.Request) (*ErrorState, bool)

func (*ErrorService) GetRecoverableError

func (c *ErrorService) GetRecoverableError(ctx context.Context, r *http.Request) (*ErrorState, bool)

func (*ErrorService) HasError

func (c *ErrorService) HasError(ctx context.Context, r *http.Request) bool

func (*ErrorService) PopError

func (*ErrorService) SetNonRecoverableError

func (c *ErrorService) SetNonRecoverableError(result *Result, value *apierrors.APIError) error

SetNonRecoverableError does NOT retain form.

func (*ErrorService) SetRecoverableError

func (c *ErrorService) SetRecoverableError(ctx context.Context, r *http.Request, value *apierrors.APIError) (*http.Cookie, error)

SetRecoverableError stores the error in cookie and retains the form.

type ErrorState

type ErrorState struct {
	Form  url.Values
	Error *apierrors.APIError
}

type ErrorTokenCookieDef

type ErrorTokenCookieDef struct {
	Def *httputil.CookieDef
}

func NewErrorTokenCookieDef

func NewErrorTokenCookieDef() ErrorTokenCookieDef

type FlashMessageType

type FlashMessageType string
const (
	FlashMessageTypeResendCodeSuccess      FlashMessageType = "resend_code_success"
	FlashMessageTypeResendLoginLinkSuccess FlashMessageType = "resend_login_link_success"
)

type GraphService

type GraphService interface {
	NewGraph(ctx context.Context, interactionCtx *interaction.Context, intent interaction.Intent) (*interaction.Graph, error)
	Get(ctx context.Context, instanceID string) (*interaction.Graph, error)
	DryRun(ctx context.Context, contextValues interaction.ContextValues, fn func(ctx context.Context, interactionCtx *interaction.Context) (*interaction.Graph, error)) error
	Run(ctx context.Context, contextValues interaction.ContextValues, graph *interaction.Graph) error
	Accept(ctx context.Context, interactionCtx *interaction.Context, graph *interaction.Graph, input interface{}) (*interaction.Graph, []interaction.Edge, error)
}
type NavigationAction string
const (
	NavigationActionAdvance  NavigationAction = "advance"
	NavigationActionReplace  NavigationAction = "replace"
	NavigationActionRedirect NavigationAction = "redirect"
)
type Navigator interface {
	Navigate(ctx context.Context, screen *AuthflowScreenWithFlowResponse, r *http.Request, webSessionID string, result *Result)
}

type OAuthClientResolver

type OAuthClientResolver interface {
	ResolveClient(clientID string) *config.OAuthClientConfig
}

type PublicOriginMiddleware

type PublicOriginMiddleware struct {
	Config     *config.HTTPConfig
	TrustProxy config.TrustProxy
	Logger     PublicOriginMiddlewareLogger
}

func (*PublicOriginMiddleware) Handle

type PublicOriginMiddlewareLogger

type PublicOriginMiddlewareLogger struct{ *log.Logger }

func NewPublicOriginMiddlewareLogger

func NewPublicOriginMiddlewareLogger(lf *log.Factory) PublicOriginMiddlewareLogger

type RequireAuthenticatedMiddleware

type RequireAuthenticatedMiddleware struct{}

func (RequireAuthenticatedMiddleware) Handle

type RequireAuthenticationEnabledMiddleware

type RequireAuthenticationEnabledMiddleware struct {
	AuthUI *config.UIConfig
}

func (RequireAuthenticationEnabledMiddleware) Handle

type RequireSettingsEnabledMiddleware

type RequireSettingsEnabledMiddleware struct {
	AuthUI *config.UIConfig
}

func (RequireSettingsEnabledMiddleware) Handle

type Result

type Result struct {
	UILocales        string              `json:"ui_locales,omitempty"`
	ColorScheme      string              `json:"color_scheme,omitempty"`
	RedirectURI      string              `json:"redirect_uri,omitempty"`
	NavigationAction NavigationAction    `json:"navigation_action,omitempty"`
	Cookies          []*http.Cookie      `json:"cookies,omitempty"`
	IsInteractionErr bool                `json:"is_interaction_err,omitempty"`
	RemoveQueries    setutil.Set[string] `json:"remove_queries,omitempty"`
}

func (*Result) IsInternalError

func (r *Result) IsInternalError() bool

func (*Result) WriteResponse

func (r *Result) WriteResponse(w http.ResponseWriter, req *http.Request)

type Service2

type Service2 struct {
	Logger               ServiceLogger
	Request              *http.Request
	Sessions             SessionStore
	SessionCookie        SessionCookieDef
	SignedUpCookie       SignedUpCookieDef
	MFADeviceTokenCookie mfa.CookieDef
	ErrorService         *ErrorService
	Cookies              CookieManager
	OAuthConfig          *config.OAuthConfig
	UIConfig             *config.UIConfig
	TrustProxy           config.TrustProxy
	UIInfoResolver       UIInfoResolver
	OAuthClientResolver  OAuthClientResolver

	Graph GraphService
}

func (*Service2) CreateSession

func (s *Service2) CreateSession(ctx context.Context, session *Session, redirectURI string) (*Result, error)

func (*Service2) DeleteSession

func (s *Service2) DeleteSession(ctx context.Context, sessionID string) error

func (*Service2) Get

func (s *Service2) Get(ctx context.Context, session *Session) (*interaction.Graph, error)

func (*Service2) GetSession

func (s *Service2) GetSession(ctx context.Context, id string) (*Session, error)

func (*Service2) GetWithIntent

func (s *Service2) GetWithIntent(ctx context.Context, session *Session, intent interaction.Intent) (*interaction.Graph, error)

func (*Service2) PeekUncommittedChanges

func (s *Service2) PeekUncommittedChanges(ctx context.Context, session *Session, fn func(graph *interaction.Graph) error) error

PeekUncommittedChanges runs fn with the effects of the graph fully applied. This is useful if fn needs the effects of the graph visible to it.

func (*Service2) PostWithInput

func (s *Service2) PostWithInput(
	ctx context.Context,
	session *Session,
	inputFn func() (interface{}, error),
) (result *Result, err error)

func (*Service2) PostWithIntent

func (s *Service2) PostWithIntent(
	ctx context.Context,
	session *Session,
	intent interaction.Intent,
	inputFn func() (interface{}, error),
) (result *Result, err error)

func (*Service2) UpdateSession

func (s *Service2) UpdateSession(ctx context.Context, session *Session) error

type ServiceLogger

type ServiceLogger struct{ *log.Logger }

func NewServiceLogger

func NewServiceLogger(lf *log.Factory) ServiceLogger

type Session

type Session struct {
	ID string `json:"id"`

	// Steps is a history stack of steps taken within this session.
	Steps []SessionStep `json:"steps,omitempty"`

	// Authflow keeps track of an authflow.
	Authflow *Authflow `json:"authflow,omitempty"`

	SAMLSessionID  string `json:"saml_session_id,omitempty"`
	OAuthSessionID string `json:"oauth_session_id,omitempty"`

	// ClientID is the client ID from SAMLSessionID or OAuthSessionID.
	ClientID string `json:"client_id,omitempty"`

	// RedirectURI is the URI to redirect to after the completion of session.
	RedirectURI string `json:"redirect_uri,omitempty"`

	// KeepAfterFinish indicates the session would not be deleted after the
	// completion of interaction graph.
	KeepAfterFinish bool `json:"keep_after_finish,omitempty"`

	// Extra is used to store extra information for use of webapp.
	Extra map[string]interface{} `json:"extra"`

	// Prompt is used to indicate requested authentication behavior
	// which includes both supported and unsupported prompt
	Prompt []string `json:"prompt_list,omitempty"`

	// Page is used to indicate the preferred page to show.
	Page string `json:"page,omitempty"`

	// UpdatedAt indicate the session last updated time
	UpdatedAt time.Time `json:"updated_at,omitempty"`

	// UserIDHint is the intended user ID.
	// It is expected that the authenticated user is indicated by this user ID,
	// otherwise it is an error.
	UserIDHint string `json:"user_id_hint,omitempty"`

	// CanUseIntentReauthenticate indicates whether IntentReauthenticate can be used.
	CanUseIntentReauthenticate bool `json:"can_use_intent_reauthenticate,omitempty"`

	// SuppressIDPSessionCookie indicates whether IDP session cookie should neither be read or written.
	SuppressIDPSessionCookie bool `json:"suppress_idp_session_cookie,omitempty"`

	// OAuthProviderAlias is used to auto redirect user to the given oauth provider in the login page
	OAuthProviderAlias string `json:"oauth_provider_alias,omitempty"`

	// LoginHint is the OIDC login_hint parameter.
	LoginHint string `json:"login_hint,omitempty"`

	// The settings action associated with this session
	// Empty if it is not a settings action
	SettingsActionID string `json:"settings_action_id,omitempty"`

	// The current flow is completed or not
	IsCompleted bool `json:"is_completed,omitempty"`
}

func GetSession

func GetSession(ctx context.Context) *Session

func NewSession

func NewSession(options SessionOptions) *Session

func (*Session) CurrentStep

func (s *Session) CurrentStep() SessionStep

func (*Session) RememberScreen

func (s *Session) RememberScreen(screen *AuthflowScreen)

type SessionCookieDef

type SessionCookieDef struct {
	Def *httputil.CookieDef
}

func NewSessionCookieDef

func NewSessionCookieDef() SessionCookieDef

type SessionMiddleware

func (*SessionMiddleware) Handle

func (m *SessionMiddleware) Handle(next http.Handler) http.Handler

type SessionMiddlewareOAuthSessionService

type SessionMiddlewareOAuthSessionService interface {
	Get(ctx context.Context, entryID string) (*oauthsession.Entry, error)
}

type SessionMiddlewareOAuthUIInfoResolver

type SessionMiddlewareOAuthUIInfoResolver interface {
	GetOAuthSessionID(req *http.Request, urlQuery string) (string, bool)
	RemoveOAuthSessionID(w http.ResponseWriter, r *http.Request)
	ResolveForUI(ctx context.Context, r protocol.AuthorizationRequest) (*oidc.UIInfo, error)
}

type SessionMiddlewareSAMLSessionService

type SessionMiddlewareSAMLSessionService interface {
	Get(ctx context.Context, sessionID string) (*samlsession.SAMLSession, error)
}

type SessionMiddlewareSAMLUIInfoResolver

type SessionMiddlewareSAMLUIInfoResolver interface {
	GetSAMLSessionID(req *http.Request, urlQuery string) (string, bool)
	RemoveSAMLSessionID(w http.ResponseWriter, r *http.Request)
}

type SessionMiddlewareSessionService

type SessionMiddlewareSessionService interface {
	CreateSession(ctx context.Context, session *Session, redirectURI string) (*Result, error)
}

type SessionMiddlewareStore

type SessionMiddlewareStore interface {
	Get(ctx context.Context, id string) (*Session, error)
}

type SessionOptions

type SessionOptions struct {
	SAMLSessionID    string
	OAuthSessionID   string
	SettingsActionID string
	ClientID         string
	RedirectURI      string
	KeepAfterFinish  bool
	Prompt           []string
	Extra            map[string]interface{}
	Page             string
	// TODO(authflow): UserIDHint is now handled natively by authflow.
	UserIDHint                 string
	UpdatedAt                  time.Time
	CanUseIntentReauthenticate bool
	// TODO(authflow): SuppressIDPSessionCookie is now handled natively by authflow.
	SuppressIDPSessionCookie bool
	OAuthProviderAlias       string
	LoginHint                string
}

func NewSessionOptionsFromSession

func NewSessionOptionsFromSession(s *Session) SessionOptions

type SessionStep

type SessionStep struct {
	// Kind is the kind of the step.
	Kind SessionStepKind `json:"kind"`
	// GraphID is the graph ID of the step.
	GraphID string `json:"graph_id"`
	// FormData is the place to store shared form data across different user agents.
	// The only use case currently is verification email being opened in another user agent.
	// In that case, the form submitted by the other user agent will update FormData.
	// The original user agent will then read from it to fill in its form.
	FormData map[string]interface{} `json:"form_data"`
}

func NewSessionStep

func NewSessionStep(kind SessionStepKind, graphID string) SessionStep

func (SessionStep) URL

func (s SessionStep) URL() *url.URL

type SessionStepKind

type SessionStepKind string
const (
	SessionStepOAuthRedirect                 SessionStepKind = "oauth-redirect"
	SessionStepPromoteUser                   SessionStepKind = "promote-user"
	SessionStepAuthenticate                  SessionStepKind = "authenticate"
	SessionStepCreateAuthenticator           SessionStepKind = "create-authenticator"
	SessionStepEnterPassword                 SessionStepKind = "enter-password"
	SessionStepUsePasskey                    SessionStepKind = "use-passkey"
	SessionStepCreatePassword                SessionStepKind = "create-password"
	SessionStepCreatePasskey                 SessionStepKind = "create-passkey"
	SessionStepPromptCreatePasskey           SessionStepKind = "prompt-create-passkey"
	SessionStepChangePrimaryPassword         SessionStepKind = "change-primary-password"
	SessionStepChangeSecondaryPassword       SessionStepKind = "change-secondary-password"
	SessionStepEnterOOBOTPAuthnEmail         SessionStepKind = "enter-oob-otp-authn-email"
	SessionStepEnterOOBOTPAuthnSMS           SessionStepKind = "enter-oob-otp-authn-sms"
	SessionStepEnterOOBOTPSetupEmail         SessionStepKind = "enter-oob-otp-setup-email"
	SessionStepEnterOOBOTPSetupSMS           SessionStepKind = "enter-oob-otp-setup-sms"
	SessionStepSetupOOBOTPEmail              SessionStepKind = "setup-oob-otp-email"
	SessionStepSetupOOBOTPSMS                SessionStepKind = "setup-oob-otp-sms"
	SessionStepSetupWhatsappOTP              SessionStepKind = "setup-whatsapp-otp"
	SessionStepSetupLoginLinkOTP             SessionStepKind = "setup-login-link-otp"
	SessionStepVerifyWhatsappOTPAuthn        SessionStepKind = "verify-whatsapp-otp-authn"
	SessionStepVerifyWhatsappOTPSetup        SessionStepKind = "verify-whatsapp-otp-setup"
	SessionStepVerifyLoginLinkOTPAuthn       SessionStepKind = "verify-login-link-otp-authn"
	SessionStepVerifyLoginLinkOTPSetup       SessionStepKind = "verify-login-link-otp-setup"
	SessionStepEnterTOTP                     SessionStepKind = "enter-totp"
	SessionStepSetupTOTP                     SessionStepKind = "setup-totp"
	SessionStepEnterRecoveryCode             SessionStepKind = "enter-recovery-code"
	SessionStepSetupRecoveryCode             SessionStepKind = "setup-recovery-code"
	SessionStepVerifyIdentityBegin           SessionStepKind = "verify-identity-begin"
	SessionStepVerifyIdentityViaOOBOTP       SessionStepKind = "verify-identity"
	SessionStepVerifyIdentityViaWhatsapp     SessionStepKind = "verify-identity-via-whatsapp"
	SessionStepAccountStatus                 SessionStepKind = "account-status"
	SessionStepConfirmTerminateOtherSessions SessionStepKind = "confirm-terminate-other-sessions"
)

func (SessionStepKind) MatchPath

func (k SessionStepKind) MatchPath(path string) bool

func (SessionStepKind) Path

func (k SessionStepKind) Path() string

type SessionStore

type SessionStore interface {
	Get(ctx context.Context, id string) (*Session, error)
	Create(ctx context.Context, session *Session) (err error)
	Update(ctx context.Context, session *Session) (err error)
	Delete(ctx context.Context, id string) (err error)
}

type SessionStoreRedis

type SessionStoreRedis struct {
	AppID config.AppID
	Redis *appredis.Handle
}

func (*SessionStoreRedis) Create

func (s *SessionStoreRedis) Create(ctx context.Context, session *Session) (err error)

func (*SessionStoreRedis) Delete

func (s *SessionStoreRedis) Delete(ctx context.Context, id string) error

func (*SessionStoreRedis) Get

func (s *SessionStoreRedis) Get(ctx context.Context, id string) (session *Session, err error)

func (*SessionStoreRedis) Update

func (s *SessionStoreRedis) Update(ctx context.Context, session *Session) (err error)

type SettingsSubRoutesMiddleware

type SettingsSubRoutesMiddleware struct {
	Database   *appdb.Handle
	Identities SettingsSubRoutesMiddlewareIdentityService
}

SettingsSubRoutesMiddleware redirect all settings sub routes to /settings if the current user is anonymous user

func (SettingsSubRoutesMiddleware) Handle

type SettingsSubRoutesMiddlewareIdentityService

type SettingsSubRoutesMiddlewareIdentityService interface {
	ListByUser(ctx context.Context, userID string) ([]*identity.Info, error)
}

type SignedUpCookieDef

type SignedUpCookieDef struct {
	Def *httputil.CookieDef
}

func NewSignedUpCookieDef

func NewSignedUpCookieDef() SignedUpCookieDef

type SuccessPageMiddleware

type SuccessPageMiddleware struct {
	Endpoints    SuccessPageMiddlewareEndpointsProvider
	UIConfig     *config.UIConfig
	Cookies      CookieManager
	ErrorService *ErrorService
}

func (*SuccessPageMiddleware) Handle

func (m *SuccessPageMiddleware) Handle(next http.Handler) http.Handler

SuccessPageMiddleware check the success path cookie to determine whether it is valid to visit the success page the cookie should be set right before redirecting to the success page

func (*SuccessPageMiddleware) Pop

type SuccessPageMiddlewareEndpointsProvider

type SuccessPageMiddlewareEndpointsProvider interface {
	ErrorEndpointURL() *url.URL
}

type TakeBranchInput

type TakeBranchInput struct {
	Index   int
	Channel model.AuthenticatorOOBChannel

	// bot protection specific inputs
	BotProtectionProviderType     string
	BotProtectionProviderResponse string
}

func (*TakeBranchInput) HasBotProtectionInput

func (i *TakeBranchInput) HasBotProtectionInput() bool

type TakeBranchOptions

type TakeBranchOptions struct {
	DisableFallbackToSMS bool
}

type TakeBranchResult

type TakeBranchResult interface {
	// contains filtered or unexported methods
}

type TakeBranchResultInput

type TakeBranchResultInput struct {
	Input                 map[string]interface{}
	NewAuthflowScreenFull func(flowResponse *authflow.FlowResponse, retriedForError error) *AuthflowScreenWithFlowResponse
	OnRetry               *TakeBranchResultInputRetryHandler
}

type TakeBranchResultInputRetryHandler

type TakeBranchResultInputRetryHandler func(err error) (nextInput interface{})

type TakeBranchResultSimple

type TakeBranchResultSimple struct {
	Screen *AuthflowScreenWithFlowResponse
}

type TutorialMiddleware

type TutorialMiddleware struct {
	TutorialCookie TutorialMiddlewareTutorialCookie
}

func (*TutorialMiddleware) Handle

func (m *TutorialMiddleware) Handle(next http.Handler) http.Handler

type TutorialMiddlewareTutorialCookie

type TutorialMiddlewareTutorialCookie interface {
	SetAll(rw http.ResponseWriter)
}

type UIInfoResolver

type UIInfoResolver interface {
	SetAuthenticationInfoInQuery(redirectURI string, e *authenticationinfo.Entry) string
}

type UIParamMiddleware

type UIParamMiddleware struct {
	OAuthUIInfoResolver SessionMiddlewareOAuthUIInfoResolver
	OAuthSessions       SessionMiddlewareOAuthSessionService
	SAMLSessions        SessionMiddlewareSAMLSessionService
	Cookies             CookieManager
}

func (*UIParamMiddleware) Handle

func (m *UIParamMiddleware) Handle(next http.Handler) http.Handler

type VisitorIDMiddleware

type VisitorIDMiddleware struct {
	Cookies CookieManager
}

func (*VisitorIDMiddleware) Handle

func (m *VisitorIDMiddleware) Handle(next http.Handler) http.Handler

type WeChatRedirectURIMiddleware

type WeChatRedirectURIMiddleware struct {
	Cookies        CookieManager
	IdentityConfig *config.IdentityConfig
}

WeChatRedirectURIMiddleware validates x_wechat_redirect_uri and stores it in context. Ideally we should store x_wechat_redirect_uri in web app session. But we can link wechat in settings page so that is not possible at the moment.

func (*WeChatRedirectURIMiddleware) Handle

Jump to

Keyboard shortcuts

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