Datapath stories, grid repairs, menu v2 pure, hero placeholders, fec test
Batch of 2026-10-28/29 plus 2026-11-03: - NEW vitec:import-datapath-stories: 22 story packages from the agency dump (docx + Links/ assets) as usecase records with content, quotes, images, customer logos, download cards; --repair-quotes normalizes attribution lines; asset backfill for existing stories - /products grid incident repaired (fix_products_grid, fix_graphics_grid, check_grid_page): containers unhidden, 46 duplicate cards soft-deleted, section order restored; BuildProductPortfolio and ImportProductCategoryPages now GUARD against re-runs on pages that already carry vitec_cols_% containers - ' double-encoding fixed: render-pipeline importers write literal apostrophes (ENT_NOQUOTES), fix_double_entities literalizes existing rows - ticket quick wins (ticket_quickwins_20261028), broadcast market page cleanup, AttachCardImages market-card handling, SubmarketWorkbook META REPAIR, story content/video fixes (fix_story_*) - ProvideProductCatalog: transitional v1 fields removed (categories uid/link, legacyGroupFields, item products teaser) - pure v2 shape (ticket 0024-FE); search renderer keeps its teaser - BuildProductOverviews: heroes get the numbered placeholder background (placeholders/pages/<uid>-01.png, wide grey fallback) - backfill on existing pages with empty hero_bgimage, attached at creation for new pages; existing references always win (ticket 0026-FE); 40 placeholder PNGs shipped to fileadmin (not tracked) - AttachPageMedia: --depth=3 with sysfolders as pass-through parents for the overview pages' -08 menu tiles - NEW migrations/fec_isolation_test.sh: two-user live test proving fe_comment ticket isolation (backend verified tight, cross-user sighting traced to the FE page-JSON cache, ticket 0027-BE) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9211c8a395
commit
77661bf0b6
22 files changed
+2103
-63
No files matched your search
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
# fe_comment Isolationstest (2026-11-03): zwei FE-User NACHEINANDER einloggen
|
||||
# und pruefen, dass /api/fe-comment/state UND das USER_INT-Feld auf
|
||||
# /_json/ticket-overview jedem User nur die EIGENEN Tickets zeigen.
|
||||
# Aufruf: bash migrations/fec_isolation_test.sh <user1> <user2>
|
||||
# (fragt beide Passwoerter unsichtbar ab)
|
||||
set -e
|
||||
cd /usr/www/users/vitecevo/live
|
||||
BASE=https://dev.vitec.com
|
||||
|
||||
U1=${1:?Aufruf: fec_isolation_test.sh <user1> <user2>}
|
||||
U2=${2:?Aufruf: fec_isolation_test.sh <user1> <user2>}
|
||||
|
||||
extract_token() {
|
||||
php -r '
|
||||
$j = json_decode(file_get_contents($argv[1]), true);
|
||||
$f = "";
|
||||
$w = function ($n) use (&$w, &$f) {
|
||||
if (is_array($n)) {
|
||||
if (($n["name"] ?? "") === "__RequestToken" && isset($n["value"])) {
|
||||
$f = (string)$n["value"];
|
||||
}
|
||||
foreach ($n as $c) { $w($c); }
|
||||
} elseif (is_string($n) && $f === "") {
|
||||
if (preg_match("/name=\"__RequestToken\" value=\"([^\"]+)\"/", $n, $m)) {
|
||||
$f = $m[1];
|
||||
}
|
||||
}
|
||||
};
|
||||
$w($j);
|
||||
echo $f;
|
||||
' "$1"
|
||||
}
|
||||
|
||||
login() { # $1=user $2=pass $3=jar
|
||||
rm -f "$3"
|
||||
curl -sS -c "$3" -o /tmp/fec_form.json "$BASE/_json/fe-user-profile"
|
||||
TOKEN=$(extract_token /tmp/fec_form.json)
|
||||
if [ -z "$TOKEN" ]; then echo "KEIN __RequestToken gefunden"; exit 1; fi
|
||||
curl -sS -b "$3" -c "$3" -o /tmp/fec_login.json \
|
||||
--data-urlencode "user=$1" \
|
||||
--data-urlencode "pass=$2" \
|
||||
--data-urlencode "logintype=login" \
|
||||
--data-urlencode "pid=520" \
|
||||
--data-urlencode "__RequestToken=$TOKEN" \
|
||||
"$BASE/_json/fe-user-profile"
|
||||
if ! grep -q fe_typo_user "$3"; then
|
||||
echo "LOGIN FEHLGESCHLAGEN fuer $1 (kein fe_typo_user-Cookie)"; exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
summarize_state() { # stdin = state json, $1 = label
|
||||
php -r '
|
||||
$j = json_decode(stream_get_contents(STDIN), true);
|
||||
printf("%-28s allowed=%s user=%s summaryUid=%s items=%d\n",
|
||||
$argv[1],
|
||||
var_export($j["allowed"] ?? null, true),
|
||||
$j["user"]["name"] ?? "-",
|
||||
isset($j["summary"]["uid"]) ? (string)$j["summary"]["uid"] : "-",
|
||||
is_array($j["summary"]["items"] ?? null) ? count($j["summary"]["items"]) : 0);
|
||||
foreach (($j["summary"]["items"] ?? []) as $i) {
|
||||
printf(" item #%d %s\n", $i["uid"], mb_substr($i["url"], 0, 70));
|
||||
}
|
||||
' "$1"
|
||||
}
|
||||
|
||||
summarize_overview() { # stdin = page json, $1 = label
|
||||
php -r '
|
||||
$j = json_decode(stream_get_contents(STDIN), true);
|
||||
$fo = null;
|
||||
foreach (($j["content"]["colPos0"] ?? []) as $el) {
|
||||
if (($el["type"] ?? "") === "fecomment_overview") {
|
||||
$fo = $el["content"]["feedbackOverview"] ?? null;
|
||||
}
|
||||
}
|
||||
if ($fo === null) { echo $argv[1] . " KEIN fecomment_overview-Element gefunden\n"; exit; }
|
||||
printf("%-28s allowed=%s user=%s summaryUid=%s items=%d\n",
|
||||
$argv[1],
|
||||
var_export($fo["allowed"] ?? null, true),
|
||||
$fo["user"]["name"] ?? "-",
|
||||
isset($fo["summary"]["uid"]) ? (string)$fo["summary"]["uid"] : "-",
|
||||
is_array($fo["summary"]["items"] ?? null) ? count($fo["summary"]["items"]) : 0);
|
||||
' "$1"
|
||||
}
|
||||
|
||||
check_user() { # $1=user $2=jar
|
||||
echo "=== $1 ==="
|
||||
curl -sS -b "$2" "$BASE/api/fe-comment/state" | summarize_state "state-API"
|
||||
curl -sS -b "$2" "$BASE/_json/ticket-overview" | summarize_overview "ticket-overview (USER_INT)"
|
||||
echo
|
||||
}
|
||||
|
||||
read -rsp "Passwort fuer $U1: " P1; echo
|
||||
read -rsp "Passwort fuer $U2: " P2; echo
|
||||
|
||||
login "$U1" "$P1" /tmp/fec_u1.jar
|
||||
login "$U2" "$P2" /tmp/fec_u2.jar
|
||||
|
||||
# Testticket als U1 anlegen, damit es etwas zu sehen (bzw. NICHT zu sehen) gibt
|
||||
echo "--- lege Testticket als $U1 an ---"
|
||||
TICKET=$(curl -sS -b /tmp/fec_u1.jar -H 'Content-Type: application/json' \
|
||||
-d '{"url":"/isolation-test","note":"<p>Isolationstest - bitte ignorieren</p>"}' \
|
||||
"$BASE/api/fe-comment/feedback" | php -r '
|
||||
$j = json_decode(stream_get_contents(STDIN), true);
|
||||
echo (int)($j["uid"] ?? 0);')
|
||||
echo "Testticket uid=$TICKET"
|
||||
if [ "$TICKET" = "0" ]; then echo "ANLEGEN FEHLGESCHLAGEN"; exit 1; fi
|
||||
echo
|
||||
|
||||
# beide Sessions leben gleichzeitig - genau wie zwei Browser
|
||||
check_user "$U1" /tmp/fec_u1.jar
|
||||
check_user "$U2" /tmp/fec_u2.jar
|
||||
|
||||
# Gegenprobe: darf U2 das Ticket von U1 veraendern? (erwartet: Fehler)
|
||||
echo "--- Gegenprobe: $U2 versucht Ticket #$TICKET von $U1 zu loeschen ---"
|
||||
curl -sS -b /tmp/fec_u2.jar -X POST "$BASE/api/fe-comment/feedback/$TICKET/delete"; echo
|
||||
echo "(erwartet: {\"error\":\"feedback not found or not yours\"})"
|
||||
echo
|
||||
|
||||
# aufraeumen: U1 loescht sein eigenes Testticket
|
||||
echo "--- aufraeumen: $U1 loescht Testticket #$TICKET ---"
|
||||
curl -sS -b /tmp/fec_u1.jar -X POST "$BASE/api/fe-comment/feedback/$TICKET/delete"; echo
|
||||
echo
|
||||
|
||||
echo "=== anonym (ohne Session) ==="
|
||||
curl -sS "$BASE/api/fe-comment/state" | summarize_state "state-API"
|
||||
curl -sS "$BASE/_json/ticket-overview" | summarize_overview "ticket-overview (USER_INT)"
|
||||
echo
|
||||
echo "ERWARTUNG: $U1 sieht 1 Item (das Testticket), $U2 sieht 0 Items,"
|
||||
echo "die Gegenprobe-Loeschung durch $U2 schlaegt fehl, anonym ist allowed=false."
|
||||
rm -f /tmp/fec_u1.jar /tmp/fec_u2.jar /tmp/fec_form.json /tmp/fec_login.json
|
||||
Reference in new issue
Block a user