diff --git a/cmd/desktop/main.go b/cmd/desktop/main.go index 0e40b3a..7a00c14 100644 --- a/cmd/desktop/main.go +++ b/cmd/desktop/main.go @@ -142,80 +142,65 @@ func startOIDCServer() *http.Server { }) } - h("/oidc/open", func(w http.ResponseWriter, r *http.Request) { + h("/oidc/start", func(w http.ResponseWriter, r *http.Request) { apiUrl := strings.TrimRight(r.URL.Query().Get("apiUrl"), "/") + returnURL := r.URL.Query().Get("ret") if apiUrl == "" { http.Error(w, "apiUrl required", http.StatusBadRequest) return } - - sessionID := randomString(16) - - go func() { - oidcCfg, err := fetchOIDCConfig(apiUrl) - if err != nil { - return - } - - verifier, challenge, _ := pkceParams() - state := randomString(32) - redirectURI := fmt.Sprintf("http://127.0.0.1:%d/oidc/callback", oidcCallbackPort) - - ch := make(chan string, 1) - oidcSessionsMu.Lock() - oidcSessions[sessionID] = &oidcSession{apiUrl: apiUrl, verifier: verifier, state: state, ch: ch} - oidcSessionsMu.Unlock() - - authURL := fmt.Sprintf("%s?%s", - oidcCfg.AuthorizationEndpoint, - url.Values{ - "response_type": {"code"}, - "client_id": {oidcCfg.ClientID}, - "redirect_uri": {redirectURI}, - "code_challenge": {challenge}, - "code_challenge_method": {"S256"}, - "state": {state}, - "scope": {"openid profile email"}, - }.Encode(), - ) - - exec.Command("open", authURL).Start() - - select { - case token := <-ch: - if token != "" { - c := &ConfigService{} - c.SaveConfig(apiUrl, token) - } - case <-time.After(5 * time.Minute): - } - }() - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{"id": sessionID}) - }) - - h("/oidc/result", func(w http.ResponseWriter, r *http.Request) { - sessionID := r.URL.Query().Get("id") - var token string - - oidcSessionsMu.Lock() - session, ok := oidcSessions[sessionID] - if ok { - select { - case t := <-session.ch: - token = t - session.ch <- t // put it back for other pollers - default: - } + if returnURL == "" { + returnURL = "/?desktop=1" } + + oidcCfg, err := fetchOIDCConfig(apiUrl) + if err != nil { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + + verifier, challenge, _ := pkceParams() + state := randomString(32) + redirectURI := fmt.Sprintf("http://127.0.0.1:%d/oidc/callback", oidcCallbackPort) + + ch := make(chan string, 1) + oidcSessionsMu.Lock() + sessionID := randomString(16) + oidcSessions[sessionID] = &oidcSession{apiUrl: apiUrl, verifier: verifier, state: state, ch: ch} oidcSessionsMu.Unlock() - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{ - "token": token, - "pending": fmt.Sprintf("%t", !ok || (ok && token == "")), - }) + authURL := fmt.Sprintf("%s?%s", + oidcCfg.AuthorizationEndpoint, + url.Values{ + "response_type": {"code"}, + "client_id": {oidcCfg.ClientID}, + "redirect_uri": {redirectURI}, + "code_challenge": {challenge}, + "code_challenge_method": {"S256"}, + "state": {state}, + "scope": {"openid profile email"}, + }.Encode(), + ) + + exec.Command("open", authURL).Start() + + select { + case token := <-ch: + if token != "" { + c := &ConfigService{} + c.SaveConfig(apiUrl, token) + returnURL += "&token=" + url.QueryEscape(token) + } + case <-time.After(5 * time.Minute): + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + fmt.Fprintf(w, `
Redirecting back to Oikos…