Files
hanko/backend/flow_api/flow/shared/hook_generate_oauth_links.go
2025-09-25 19:15:20 +02:00

69 lines
2.0 KiB
Go

package shared
import (
"fmt"
"net/url"
"github.com/labstack/echo/v4"
"github.com/teamhanko/hanko/backend/v2/flowpilot"
)
type GenerateOAuthLinks struct {
Action
}
func (h GenerateOAuthLinks) Execute(c flowpilot.HookExecutionContext) error {
deps := h.GetDeps(c)
returnToUrl := deps.Cfg.ThirdParty.DefaultRedirectURL
referer := deps.HttpContext.Request().Header.Get("Referer")
if referer != "" {
u, err := url.Parse(referer)
if err != nil {
return err
}
// remove any query and fragment parts of the referer
u.RawQuery = ""
u.Fragment = ""
returnToUrl = u.String()
}
if deps.Cfg.ThirdParty.Providers.GitHub.Enabled {
c.AddLink(OAuthLink("github", h.generateHref(deps.HttpContext, "github", returnToUrl)))
}
if deps.Cfg.ThirdParty.Providers.Google.Enabled {
c.AddLink(OAuthLink("google", h.generateHref(deps.HttpContext, "google", returnToUrl)))
}
if deps.Cfg.ThirdParty.Providers.Apple.Enabled {
c.AddLink(OAuthLink("apple", h.generateHref(deps.HttpContext, "apple", returnToUrl)))
}
if deps.Cfg.ThirdParty.Providers.Facebook.Enabled {
c.AddLink(OAuthLink("facebook", h.generateHref(deps.HttpContext, "facebook", returnToUrl)))
}
return nil
}
func (h GenerateOAuthLinks) generateHref(c echo.Context, provider string, returnToUrl string) string {
host := c.Request().Host
forwardedProto := c.Request().Header.Get("X-Forwarded-Proto")
if forwardedProto == "" {
// Assume that a proxy is setting the X-Forwarded-Proto header correctly. Hanko should always be deployed behind a proxy,
// because you cannot start the backend with https and passkeys only work in a secure context.
// If the X-Forwarded-Proto header is not set, set it to 'http' because otherwise you would need to set up a https environment for local testing.
forwardedProto = "http"
}
u, _ := url.Parse(fmt.Sprintf("%s://%s/thirdparty/auth", forwardedProto, host))
query := url.Values{}
query.Set("provider", provider)
if returnToUrl != "" {
query.Set("redirect_to", returnToUrl)
}
u.RawQuery = query.Encode()
return u.String()
}