- Replace the v1 submit endpoint with a full JSON API under
/api/fe-comment/ (state, feedback create/update/delete, uploads,
summary notes/recipients, submit), guarded by frontend login and a
configurable FE user group; unauthorized callers get {"allowed":false}
- New models: tx_fecomment_summary (one open ticket per user, status
open/sent) and tx_fecomment_feedback (url, RTE note, FAL attachments),
both editable in the backend on the ticket storage page
- FeedbackApiMiddleware registered after frontend authentication (the
frontend.user attribute does not exist earlier); uploads land in
fileadmin/fe_comment/summary-<uid>/ with mime/extension check, 20 MB cap
- Submit sends one HTML mail (author block, items with attachment links,
reply-to = FE user mail) to selected recipients with mailTo fallback,
then closes the summary
- felogin wired React-compatible: felogin.pid=520 plus headless FeLogin
JSON templates via site settings - felogin v14 and EXT:headless both
claim templateRootPaths.10, the felogin.view.* settings feed exactly
that index, so the structured JSON form (incl. __RequestToken) wins
- Read the sys_file_reference insert id before syncAttachmentCount():
DBAL throws "no identity value" once the count UPDATE has run
- migrations: drop_fecomment_tables.php (repairs the no-uid tables,
only drops when empty), check_feuser.php (login diagnosis),
fec_login_test.sh / fec_api_test.sh (curl chains incl. CSRF token flow)
62 lines
2.8 KiB
PHP
62 lines
2.8 KiB
PHP
<?php
|
|
/**
|
|
* Diagnose: warum schlaegt der FE-Login fehl?
|
|
* Aufruf: php migrations/check_feuser.php <username> '<passwort>'
|
|
* Gibt KEINE Geheimnisse aus - nur Statusfelder und ein verify-Ergebnis.
|
|
*/
|
|
if ($argc < 2) {
|
|
fwrite(STDERR, "Aufruf: php migrations/check_feuser.php <username> ['<passwort>']\n");
|
|
exit(1);
|
|
}
|
|
$username = $argv[1];
|
|
$password = $argv[2] ?? null;
|
|
|
|
$settings = require __DIR__ . '/../config/system/settings.php';
|
|
$db = $settings['DB']['Connections']['Default'];
|
|
$pdo = new PDO(
|
|
'mysql:host=' . $db['host'] . ';dbname=' . $db['dbname'] . ';charset=utf8mb4',
|
|
$db['user'],
|
|
$db['password']
|
|
);
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
|
|
$stmt = $pdo->prepare(
|
|
'SELECT uid, pid, username, usergroup, disable, deleted, starttime, endtime, password
|
|
FROM fe_users WHERE username = ?'
|
|
);
|
|
$stmt->execute([$username]);
|
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
if (!$rows) {
|
|
echo "KEIN fe_users-Datensatz mit username='$username' gefunden (auch kein geloeschter).\n";
|
|
exit(0);
|
|
}
|
|
|
|
$now = time();
|
|
foreach ($rows as $r) {
|
|
echo "--- fe_users uid={$r['uid']} ---\n";
|
|
echo 'pid: ' . $r['pid'] . ($r['pid'] == 520 ? ' (ok)' : ' <-- NICHT 520! Login-POST braucht pid=' . $r['pid']) . "\n";
|
|
echo 'usergroup: "' . $r['usergroup'] . '"' . (in_array('1', array_map('trim', explode(',', (string)$r['usergroup'])), true) ? ' (enthaelt Gruppe 1, ok)' : ' <-- Gruppe 1 FEHLT') . "\n";
|
|
echo 'deleted: ' . $r['deleted'] . ($r['deleted'] ? ' <-- GELOESCHT' : ' (ok)') . "\n";
|
|
echo 'disable: ' . $r['disable'] . ($r['disable'] ? ' <-- DEAKTIVIERT' : ' (ok)') . "\n";
|
|
echo 'starttime: ' . $r['starttime'] . ($r['starttime'] > $now ? ' <-- liegt in der ZUKUNFT' : ' (ok)') . "\n";
|
|
echo 'endtime: ' . $r['endtime'] . (($r['endtime'] && $r['endtime'] < $now) ? ' <-- ABGELAUFEN' : ' (ok)') . "\n";
|
|
$hash = (string)$r['password'];
|
|
$prefix = substr($hash, 0, strpos($hash, '$', 1) ?: 8);
|
|
echo 'hash-typ: ' . ($prefix !== '' ? $prefix : '(leer!)') . "\n";
|
|
if ($password !== null) {
|
|
if (str_starts_with($hash, '$argon2') || str_starts_with($hash, '$2y$')) {
|
|
echo 'passwort: ' . (password_verify($password, $hash) ? 'VERIFIZIERT - stimmt mit dem Hash ueberein' : 'FALSCH - stimmt NICHT mit dem Hash ueberein') . "\n";
|
|
} else {
|
|
echo "passwort: Hash-Format unbekannt, kein lokaler Verify moeglich\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Gruppe 1 existiert und ist nicht versteckt/geloescht?
|
|
$g = $pdo->query('SELECT uid, pid, title, hidden, deleted FROM fe_groups WHERE uid = 1')->fetch(PDO::FETCH_ASSOC);
|
|
echo "--- fe_groups uid=1 ---\n";
|
|
echo $g
|
|
? "title: \"{$g['title']}\" pid: {$g['pid']} hidden: {$g['hidden']} deleted: {$g['deleted']}\n"
|
|
: "EXISTIERT NICHT!\n";
|