fix: use App.jwtSecret instead of env for OAuth state token
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 6s

This commit is contained in:
Play Life Bot
2026-01-02 15:42:59 +03:00
parent 53e3f23422
commit 7547058507

View File

@@ -5767,7 +5767,7 @@ type OAuthStateClaims struct {
} }
// generateOAuthState генерирует JWT state для OAuth // generateOAuthState генерирует JWT state для OAuth
func generateOAuthState(userID int, jwtSecret string) (string, error) { func generateOAuthState(userID int, jwtSecret []byte) (string, error) {
claims := OAuthStateClaims{ claims := OAuthStateClaims{
UserID: userID, UserID: userID,
Type: "todoist_oauth", Type: "todoist_oauth",
@@ -5777,16 +5777,16 @@ func generateOAuthState(userID int, jwtSecret string) (string, error) {
}, },
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(jwtSecret)) return token.SignedString(jwtSecret)
} }
// validateOAuthState проверяет и извлекает user_id из JWT state // validateOAuthState проверяет и извлекает user_id из JWT state
func validateOAuthState(stateString string, jwtSecret string) (int, error) { func validateOAuthState(stateString string, jwtSecret []byte) (int, error) {
token, err := jwt.ParseWithClaims(stateString, &OAuthStateClaims{}, func(token *jwt.Token) (interface{}, error) { token, err := jwt.ParseWithClaims(stateString, &OAuthStateClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
} }
return []byte(jwtSecret), nil return jwtSecret, nil
}) })
if err != nil { if err != nil {
return 0, err return 0, err
@@ -5895,7 +5895,6 @@ func (a *App) todoistOAuthConnectHandler(w http.ResponseWriter, r *http.Request)
clientID := getEnv("TODOIST_CLIENT_ID", "") clientID := getEnv("TODOIST_CLIENT_ID", "")
clientSecret := getEnv("TODOIST_CLIENT_SECRET", "") clientSecret := getEnv("TODOIST_CLIENT_SECRET", "")
jwtSecret := getEnv("JWT_SECRET", "")
baseURL := getEnv("WEBHOOK_BASE_URL", "") baseURL := getEnv("WEBHOOK_BASE_URL", "")
if clientID == "" || clientSecret == "" { if clientID == "" || clientSecret == "" {
@@ -5906,14 +5905,10 @@ func (a *App) todoistOAuthConnectHandler(w http.ResponseWriter, r *http.Request)
sendErrorWithCORS(w, "WEBHOOK_BASE_URL must be configured", http.StatusInternalServerError) sendErrorWithCORS(w, "WEBHOOK_BASE_URL must be configured", http.StatusInternalServerError)
return return
} }
if jwtSecret == "" {
sendErrorWithCORS(w, "JWT_SECRET must be configured", http.StatusInternalServerError)
return
}
redirectURI := strings.TrimRight(baseURL, "/") + "/api/integrations/todoist/oauth/callback" redirectURI := strings.TrimRight(baseURL, "/") + "/api/integrations/todoist/oauth/callback"
state, err := generateOAuthState(userID, jwtSecret) state, err := generateOAuthState(userID, a.jwtSecret)
if err != nil { if err != nil {
log.Printf("Todoist OAuth: failed to generate state: %v", err) log.Printf("Todoist OAuth: failed to generate state: %v", err)
sendErrorWithCORS(w, "Failed to generate OAuth state", http.StatusInternalServerError) sendErrorWithCORS(w, "Failed to generate OAuth state", http.StatusInternalServerError)
@@ -5942,12 +5937,11 @@ func (a *App) todoistOAuthCallbackHandler(w http.ResponseWriter, r *http.Request
redirectSuccess := frontendURL + "/?integration=todoist&status=connected" redirectSuccess := frontendURL + "/?integration=todoist&status=connected"
redirectError := frontendURL + "/?integration=todoist&status=error" redirectError := frontendURL + "/?integration=todoist&status=error"
jwtSecret := getEnv("JWT_SECRET", "")
clientID := getEnv("TODOIST_CLIENT_ID", "") clientID := getEnv("TODOIST_CLIENT_ID", "")
clientSecret := getEnv("TODOIST_CLIENT_SECRET", "") clientSecret := getEnv("TODOIST_CLIENT_SECRET", "")
baseURL := getEnv("WEBHOOK_BASE_URL", "") baseURL := getEnv("WEBHOOK_BASE_URL", "")
if jwtSecret == "" || clientID == "" || clientSecret == "" || baseURL == "" { if clientID == "" || clientSecret == "" || baseURL == "" {
log.Printf("Todoist OAuth: missing configuration") log.Printf("Todoist OAuth: missing configuration")
http.Redirect(w, r, redirectError+"&message=config_error", http.StatusTemporaryRedirect) http.Redirect(w, r, redirectError+"&message=config_error", http.StatusTemporaryRedirect)
return return
@@ -5957,7 +5951,7 @@ func (a *App) todoistOAuthCallbackHandler(w http.ResponseWriter, r *http.Request
// Проверяем state // Проверяем state
state := r.URL.Query().Get("state") state := r.URL.Query().Get("state")
userID, err := validateOAuthState(state, jwtSecret) userID, err := validateOAuthState(state, a.jwtSecret)
if err != nil { if err != nil {
log.Printf("Todoist OAuth: invalid state: %v", err) log.Printf("Todoist OAuth: invalid state: %v", err)
http.Redirect(w, r, redirectError+"&message=invalid_state", http.StatusTemporaryRedirect) http.Redirect(w, r, redirectError+"&message=invalid_state", http.StatusTemporaryRedirect)