diff --git a/backend/internal/controller/oidc_controller.go b/backend/internal/controller/oidc_controller.go index c95d6fa..943e356 100644 --- a/backend/internal/controller/oidc_controller.go +++ b/backend/internal/controller/oidc_controller.go @@ -1,13 +1,14 @@ package controller import ( - "github.com/pocket-id/pocket-id/backend/internal/common" - "github.com/pocket-id/pocket-id/backend/internal/utils/cookie" "log" "net/http" "net/url" "strings" + "github.com/pocket-id/pocket-id/backend/internal/common" + "github.com/pocket-id/pocket-id/backend/internal/utils/cookie" + "github.com/gin-gonic/gin" "github.com/pocket-id/pocket-id/backend/internal/dto" "github.com/pocket-id/pocket-id/backend/internal/middleware" @@ -149,7 +150,7 @@ func (oc *OidcController) EndSessionHandler(c *gin.Context) { if err != nil { // If the validation fails, the user has to confirm the logout manually and doesn't get redirected log.Printf("Error getting logout callback URL, the user has to confirm the logout manually: %v", err) - c.Redirect(http.StatusFound, common.EnvConfig.AppURL+"/logout") + c.Redirect(http.StatusFound, utils.GetAbsoluteURL(common.EnvConfig.AppURL, "/logout")) return } diff --git a/backend/internal/controller/well_known_controller.go b/backend/internal/controller/well_known_controller.go index 3672d85..c891ed8 100644 --- a/backend/internal/controller/well_known_controller.go +++ b/backend/internal/controller/well_known_controller.go @@ -6,6 +6,7 @@ import ( "github.com/gin-gonic/gin" "github.com/pocket-id/pocket-id/backend/internal/common" "github.com/pocket-id/pocket-id/backend/internal/service" + "github.com/pocket-id/pocket-id/backend/internal/utils" ) func NewWellKnownController(group *gin.RouterGroup, jwtService *service.JwtService) { @@ -32,11 +33,11 @@ func (wkc *WellKnownController) openIDConfigurationHandler(c *gin.Context) { appUrl := common.EnvConfig.AppURL config := map[string]interface{}{ "issuer": appUrl, - "authorization_endpoint": appUrl + "/authorize", - "token_endpoint": appUrl + "/api/oidc/token", - "userinfo_endpoint": appUrl + "/api/oidc/userinfo", - "end_session_endpoint": appUrl + "/api/oidc/end-session", - "jwks_uri": appUrl + "/.well-known/jwks.json", + "authorization_endpoint": utils.GetAbsoluteURL(appUrl, "/authorize"), + "token_endpoint": utils.GetAbsoluteURL(appUrl, "/api/oidc/token"), + "userinfo_endpoint": utils.GetAbsoluteURL(appUrl, "/api/oidc/userinfo"), + "end_session_endpoint": utils.GetAbsoluteURL(appUrl, "/api/oidc/end-session"), + "jwks_uri": utils.GetAbsoluteURL(appUrl, "/.well-known/jwks.json"), "scopes_supported": []string{"openid", "profile", "email"}, "claims_supported": []string{"sub", "given_name", "family_name", "name", "email", "email_verified", "preferred_username", "picture"}, "response_types_supported": []string{"code", "id_token"}, diff --git a/backend/internal/service/email_service.go b/backend/internal/service/email_service.go index 2aa6cb6..1c5aa89 100644 --- a/backend/internal/service/email_service.go +++ b/backend/internal/service/email_service.go @@ -16,6 +16,7 @@ import ( "github.com/pocket-id/pocket-id/backend/internal/common" "github.com/pocket-id/pocket-id/backend/internal/model" + "github.com/pocket-id/pocket-id/backend/internal/utils" "github.com/pocket-id/pocket-id/backend/internal/utils/email" "gorm.io/gorm" ) @@ -66,7 +67,7 @@ func (srv *EmailService) SendTestEmail(recipientUserId string) error { func SendEmail[V any](srv *EmailService, toEmail email.Address, template email.Template[V], tData *V) error { data := &email.TemplateData[V]{ AppName: srv.appConfigService.DbConfig.AppName.Value, - LogoURL: common.EnvConfig.AppURL + "/api/application-configuration/logo", + LogoURL: utils.GetAbsoluteURL(common.EnvConfig.AppURL, "/api/application-configuration/logo"), Data: tData, } diff --git a/backend/internal/service/oidc_service.go b/backend/internal/service/oidc_service.go index 96967cc..f9293cb 100644 --- a/backend/internal/service/oidc_service.go +++ b/backend/internal/service/oidc_service.go @@ -401,7 +401,7 @@ func (s *OidcService) GetUserClaimsForClient(userID string, clientID string) (ma "family_name": user.LastName, "name": user.FullName(), "preferred_username": user.Username, - "picture": fmt.Sprintf("%s/api/users/%s/profile-picture.png", common.EnvConfig.AppURL, user.ID), + "picture": utils.GetAbsoluteURL(common.EnvConfig.AppURL, fmt.Sprintf("/api/users/%s/profile-picture.png", user.ID)), } if strings.Contains(scope, "profile") { diff --git a/backend/internal/service/user_service.go b/backend/internal/service/user_service.go index 2166f02..ecc562a 100644 --- a/backend/internal/service/user_service.go +++ b/backend/internal/service/user_service.go @@ -3,8 +3,6 @@ package service import ( "errors" "fmt" - "github.com/google/uuid" - "github.com/pocket-id/pocket-id/backend/internal/utils/image" "io" "log" "net/url" @@ -12,6 +10,9 @@ import ( "strings" "time" + "github.com/google/uuid" + profilepicture "github.com/pocket-id/pocket-id/backend/internal/utils/image" + "github.com/pocket-id/pocket-id/backend/internal/common" "github.com/pocket-id/pocket-id/backend/internal/dto" "github.com/pocket-id/pocket-id/backend/internal/model" @@ -197,7 +198,7 @@ func (s *UserService) RequestOneTimeAccessEmail(emailAddress, redirectPath strin return err } - link := fmt.Sprintf("%s/login/%s", common.EnvConfig.AppURL, oneTimeAccessToken) + link := utils.GetAbsoluteURL(common.EnvConfig.AppURL, fmt.Sprintf("/login/%s", oneTimeAccessToken)) // Add redirect path to the link if strings.HasPrefix(redirectPath, "/") { diff --git a/backend/internal/utils/string_util.go b/backend/internal/utils/string_util.go index 24c78c9..ed59935 100644 --- a/backend/internal/utils/string_util.go +++ b/backend/internal/utils/string_util.go @@ -40,6 +40,15 @@ func GetHostnameFromURL(rawURL string) string { return parsedURL.Hostname() } +// Returns an absolute path when provided with a URL (https://test.com) and a path "/.well-known/openid-configuration" +func GetAbsoluteURL(baseURL string, path string) string { + url, err := url.JoinPath(baseURL, path) + if err != nil { + return "" + } + return url +} + // StringPointer creates a string pointer from a string value func StringPointer(s string) *string { return &s