update frontend
This commit is contained in:
parent
9ee948fcb8
commit
9da994cfbb
|
|
@ -252,10 +252,6 @@ export function usePostsEngine({
|
|||
|
||||
setLoadingPosts(false);
|
||||
} catch (err) {
|
||||
console.error("Erreur chargement posts:", err);
|
||||
if (!cancelled) {
|
||||
setLoadError("Error loading posts.");
|
||||
setLoadingPosts(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ===== CONFIG =====
|
||||
BACKEND_DIR="${BACKEND_DIR:-sociowire-backend}"
|
||||
|
||||
cd "$BACKEND_DIR"
|
||||
|
||||
echo "[1/2] Write auth_refresh.go"
|
||||
cat > auth_refresh.go <<'GO'
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func refreshHandler(w http.ResponseWriter, r *http.Request) {
|
||||
setCommonHeaders(w)
|
||||
|
||||
if r.Method == http.MethodOptions {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
type req struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
var body req
|
||||
_ = json.NewDecoder(r.Body).Decode(&body)
|
||||
|
||||
rt := strings.TrimSpace(body.RefreshToken)
|
||||
if rt == "" {
|
||||
http.Error(w, "refresh_token required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
kcURL := strings.TrimRight(strings.TrimSpace(os.Getenv("KEYCLOAK_URL")), "/")
|
||||
realm := strings.TrimSpace(os.Getenv("KEYCLOAK_REALM"))
|
||||
clientID := strings.TrimSpace(os.Getenv("KC_PUBLIC_CLIENT_ID"))
|
||||
clientSecret := strings.TrimSpace(os.Getenv("KC_PUBLIC_CLIENT_SECRET"))
|
||||
|
||||
if kcURL == "" || realm == "" || clientID == "" {
|
||||
http.Error(w, "keycloak env missing", http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
|
||||
tokenURL := kcURL + "/realms/" + realm + "/protocol/openid-connect/token"
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("grant_type", "refresh_token")
|
||||
form.Set("client_id", clientID)
|
||||
form.Set("refresh_token", rt)
|
||||
if clientSecret != "" {
|
||||
form.Set("client_secret", clientSecret)
|
||||
}
|
||||
|
||||
req2, _ := http.NewRequest("POST", tokenURL, strings.NewReader(form.Encode()))
|
||||
req2.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
client := &http.Client{Timeout: 8 * time.Second}
|
||||
resp, err := client.Do(req2)
|
||||
if err != nil {
|
||||
http.Error(w, "keycloak refresh error", http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
raw, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode != 200 {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
_, _ = w.Write(raw)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write(raw)
|
||||
}
|
||||
GO
|
||||
|
||||
echo "[2/2] Patch main.go to add /api/refresh route"
|
||||
if ! grep -q '"/api/refresh"' main.go; then
|
||||
# Insert after /api/login line if present, else near auth routes block
|
||||
# This is a simple awk insert.
|
||||
awk '
|
||||
{print}
|
||||
/mux\.HandleFunc\("\/api\/login", loginHandler\)/ {
|
||||
print "\tmux.HandleFunc(\"/api/refresh\", refreshHandler)"
|
||||
}
|
||||
' main.go > main.go.tmp
|
||||
|
||||
# If insertion didn’t happen (no match), append under auth routes area:
|
||||
if ! grep -q '"/api/refresh"' main.go.tmp; then
|
||||
awk '
|
||||
{print}
|
||||
/mux\.HandleFunc\("\/api\/login", loginHandler\)/==0 && /\/\/ Auth\/debug/ {
|
||||
# no-op marker
|
||||
}
|
||||
' main.go.tmp > /dev/null 2>&1 || true
|
||||
# fallback: append near other routes (safe)
|
||||
sed -i 's|mux.HandleFunc("/api/login", loginHandler)|mux.HandleFunc("/api/login", loginHandler)\n\tmux.HandleFunc("/api/refresh", refreshHandler)|' main.go.tmp || true
|
||||
fi
|
||||
|
||||
mv main.go.tmp main.go
|
||||
else
|
||||
echo "main.go already has /api/refresh"
|
||||
fi
|
||||
|
||||
echo "DONE backend patch."
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
FRONTEND_DIR="${FRONTEND_DIR:-sociowire-frontend}"
|
||||
FILE="$FRONTEND_DIR/src/auth/AuthContext.jsx"
|
||||
|
||||
if [ ! -f "$FILE" ]; then
|
||||
echo "ERROR: not found: $FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[1/3] Backup AuthContext.jsx"
|
||||
cp -a "$FILE" "$FILE.bak.$(date +%s)"
|
||||
|
||||
echo "[2/3] Remove direct Keycloak constants (KC_BASE/KC_REALM/KC_CLIENT_ID) if present"
|
||||
# delete block lines that define KC_BASE/KC_REALM/KC_CLIENT_ID
|
||||
sed -i \
|
||||
-e '/^const KC_BASE = /d' \
|
||||
-e '/^const KC_REALM = /d' \
|
||||
-e '/^const KC_CLIENT_ID = /d' \
|
||||
"$FILE"
|
||||
|
||||
echo "[3/3] Replace refreshWithKeycloak + login() to use backend /api/login + /api/refresh"
|
||||
|
||||
# Replace function refreshWithKeycloak(...) { ... } with refreshViaBackend(...)
|
||||
perl -0777 -i -pe '
|
||||
s/async function refreshWithKeycloak\([^\)]*\)\s*\{.*?\n\}\n/async function refreshViaBackend(refreshToken) {\n const res = await fetch(\"\/api\/refresh\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application\/json\" },\n credentials: \"include\",\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n\n const text = await res.text();\n if (!res.ok) {\n let msg = text;\n try {\n const j = JSON.parse(text);\n msg = j.error_description || j.error || text;\n } catch {}\n throw new Error(`${res.status} ${msg}`);\n }\n\n const data = JSON.parse(text);\n if (!data.access_token) throw new Error(\"No access_token in refresh response\");\n return {\n accessToken: data.access_token,\n refreshToken: data.refresh_token || refreshToken,\n };\n}\n/sms
|
||||
' "$FILE"
|
||||
|
||||
# Replace any calls to refreshWithKeycloak( with refreshViaBackend(
|
||||
sed -i 's/refreshWithKeycloak(/refreshViaBackend(/g' "$FILE"
|
||||
|
||||
# Replace login() body to call /api/login
|
||||
perl -0777 -i -pe '
|
||||
s/async function login\([^\)]*\)\s*\{.*?\n\s*\}\n\n\s*function logout\(/async function login(user, pass) {\n setLastError(\"\");\n const u = (user || \"\").trim();\n if (!u || !pass) {\n setLastError(\"Username and password required.\");\n return;\n }\n\n try {\n setLoading(true);\n\n const res = await fetch(\"\/api\/login\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application\/json\" },\n credentials: \"include\",\n body: JSON.stringify({ username: u, password: pass }),\n });\n\n const text = await res.text();\n if (!res.ok) {\n let msg = \"Invalid credentials or auth error.\";\n try {\n const j = JSON.parse(text);\n msg = j.error_description || j.error || msg;\n } catch {}\n clearAuth(`${res.status} ${msg}`);\n return;\n }\n\n const data = JSON.parse(text);\n const accessToken = data.access_token;\n const refreshToken = data.refresh_token;\n\n if (!accessToken) {\n clearAuth(\"No access token in response.\");\n return;\n }\n\n persistAuth({ accessToken, refreshToken, user: u });\n setLastError(\"\");\n } catch (e) {\n console.error(\"[AUTH] network error\", e);\n clearAuth(\"Network error during login.\");\n } finally {\n setLoading(false);\n }\n }\n\n function logout(/sms
|
||||
' "$FILE"
|
||||
|
||||
echo "DONE frontend patch."
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
APP_DIR="${APP_DIR:-sociowire-frontend}"
|
||||
FILE="$APP_DIR/src/components/Layout/TopBar.jsx"
|
||||
|
||||
cp -a "$FILE" "$FILE.bak.$(date +%s)"
|
||||
|
||||
# Ajoute l'affichage lastError dans le form login (sous le bouton)
|
||||
perl -0777 -i -pe '
|
||||
s|(</button>\s*</form>)|</button>\n {lastError && <div className="auth-error" style={{marginTop:"0.6rem"}}>{lastError}</div>}\n </form>|ms
|
||||
' "$FILE"
|
||||
|
||||
echo "OK patched: $FILE"
|
||||
Loading…
Reference in New Issue