mirror of
https://github.com/netbirdio/dex.git
synced 2026-05-22 18:43:53 -07:00
feat: include prompt=select_account in back link for multiple connectors (#4694)
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com> Signed-off-by: Maksim Nabokikh <max.nabokih@gmail.com>
This commit is contained in:
+9
-1
@@ -10,6 +10,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -464,11 +465,18 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
|
||||
scopes := parseScopes(authReq.Scopes)
|
||||
|
||||
// Work out where the "Select another login method" link should go.
|
||||
// Include prompt=select_account so that handleAuthorization skips
|
||||
// session-based connector reuse and shows the connector list.
|
||||
backLink := ""
|
||||
if len(s.connectors) > 1 {
|
||||
backLinkParams := make(url.Values)
|
||||
maps.Copy(backLinkParams, r.Form)
|
||||
if s.sessionConfig != nil {
|
||||
backLinkParams.Set("prompt", "select_account")
|
||||
}
|
||||
backLinkURL := url.URL{
|
||||
Path: s.absPath("/auth"),
|
||||
RawQuery: r.Form.Encode(),
|
||||
RawQuery: backLinkParams.Encode(),
|
||||
}
|
||||
backLink = backLinkURL.String()
|
||||
}
|
||||
|
||||
@@ -2074,3 +2074,52 @@ func TestHandleAuthorizationWithoutAllowedConnectors(t *testing.T) {
|
||||
// With multiple connectors and no filter, the login page should be rendered (200 OK)
|
||||
require.Equal(t, http.StatusOK, rr.Code)
|
||||
}
|
||||
|
||||
func TestBackLinkIncludesPromptSelectAccount(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
httpServer, s := newTestServerMultipleConnectors(t, nil)
|
||||
defer httpServer.Close()
|
||||
|
||||
// select_account prompt only works with the sessions feature flag enabled.
|
||||
s.sessionConfig = &SessionConfig{}
|
||||
|
||||
// Add a password connector so handleConnectorLogin passes the backlink via redirect.
|
||||
pwConn := storage.Connector{
|
||||
ID: "mockPw",
|
||||
Type: "mockPassword",
|
||||
Name: "MockPassword",
|
||||
ResourceVersion: "1",
|
||||
Config: []byte(`{"username": "foo", "password": "bar"}`),
|
||||
}
|
||||
require.NoError(t, s.storage.CreateConnector(ctx, pwConn))
|
||||
_, err := s.OpenConnector(pwConn)
|
||||
require.NoError(t, err)
|
||||
|
||||
client := storage.Client{
|
||||
ID: "test-client",
|
||||
Secret: "secret",
|
||||
RedirectURIs: []string{"https://example.com/callback"},
|
||||
Name: "Test Client",
|
||||
}
|
||||
require.NoError(t, s.storage.CreateClient(ctx, client))
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
authURL := fmt.Sprintf("/auth/mockPw?client_id=%s&redirect_uri=%s&response_type=code&scope=openid",
|
||||
client.ID, url.QueryEscape("https://example.com/callback"))
|
||||
req := httptest.NewRequest("GET", authURL, nil)
|
||||
s.ServeHTTP(rr, req)
|
||||
|
||||
require.Equal(t, http.StatusFound, rr.Code)
|
||||
|
||||
loc, err := url.Parse(rr.Header().Get("Location"))
|
||||
require.NoError(t, err)
|
||||
|
||||
backLink := loc.Query().Get("back")
|
||||
require.NotEmpty(t, backLink, "back link should be set when multiple connectors exist")
|
||||
|
||||
backURL, err := url.Parse(backLink)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "select_account", backURL.Query().Get("prompt"),
|
||||
"back link should include prompt=select_account")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user