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
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 6s
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user