mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
refactor: move Restrictions d'accès aux fichiers from contenus.php to acces.php, cleanup section
This commit is contained in:
19
TODO.md
19
TODO.md
@@ -1,5 +1,24 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
## Move Restrictions d'accès aux fichiers to acces.php
|
||||||
|
|
||||||
|
- [x] Remove fieldset from templates/admin/contenus.php
|
||||||
|
- [x] Add fieldset to templates/admin/acces.php
|
||||||
|
- [x] Load $siteSettings in admin/acces.php controller
|
||||||
|
- [x] Update redirect in settings.php for formulaire_restrictions → /admin/acces.php
|
||||||
|
|
||||||
|
## Fix PeerTube upload — Google-resumable protocol adherence
|
||||||
|
|
||||||
|
- [x] Use Location header from init response (not reconstruct URL from JSON body)
|
||||||
|
- [x] Switch chunk method from PUT → PATCH (Google-resumable variant)
|
||||||
|
- [x] Use actual file MIME type in chunk Content-Type (not application/octet-stream)
|
||||||
|
- [x] Ensure chunk size is multiple of 256 KB
|
||||||
|
- [x] Add PATCH/HEAD methods to httpRequest()
|
||||||
|
- [x] Add CURLOPT_HEADERFUNCTION to capture response headers
|
||||||
|
- [x] Disable CURLOPT_FOLLOWLOCATION to preserve Location header
|
||||||
|
- [x] Add cancelUpload() helper for Delete-on-error cleanup
|
||||||
|
- [ ] Test with actual PeerTube instance
|
||||||
|
|
||||||
## HTMX Toast Feedback for Settings Checkboxes (contenus.php)
|
## HTMX Toast Feedback for Settings Checkboxes (contenus.php)
|
||||||
|
|
||||||
- [x] Add `hx-target` response divs to the three fieldsets in contenus.php
|
- [x] Add `hx-target` response divs to the three fieldsets in contenus.php
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https'
|
|||||||
$baseUrl = $protocol . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
|
$baseUrl = $protocol . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
|
||||||
|
|
||||||
// ── Demandes d'accès aux fichiers ─────────────────────────────────────────────
|
// ── Demandes d'accès aux fichiers ─────────────────────────────────────────────
|
||||||
|
require_once APP_ROOT . '/src/Database.php';
|
||||||
require_once APP_ROOT . '/src/Controllers/FileAccessController.php';
|
require_once APP_ROOT . '/src/Controllers/FileAccessController.php';
|
||||||
|
|
||||||
|
$db = new Database();
|
||||||
|
$siteSettings = $db->getAllSettings();
|
||||||
|
|
||||||
$controller = FileAccessController::create();
|
$controller = FileAccessController::create();
|
||||||
$vars = $controller->handle();
|
$vars = $controller->handle();
|
||||||
extract($vars);
|
extract($vars);
|
||||||
|
|||||||
@@ -162,8 +162,10 @@ $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
|||||||
|
|
||||||
// Redirect back to wherever the form came from, defaulting to parametres
|
// Redirect back to wherever the form came from, defaulting to parametres
|
||||||
$redirect = '/admin/parametres.php';
|
$redirect = '/admin/parametres.php';
|
||||||
if (in_array($section, ['formulaire_restrictions', 'formulaire_acces', 'objet_types'], true)) {
|
if (in_array($section, ['formulaire_acces', 'objet_types'], true)) {
|
||||||
$redirect = '/admin/contenus.php';
|
$redirect = '/admin/contenus.php';
|
||||||
|
} elseif ($section === 'formulaire_restrictions') {
|
||||||
|
$redirect = '/admin/acces.php';
|
||||||
}
|
}
|
||||||
header('Location: ' . $redirect);
|
header('Location: ' . $redirect);
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
* instance's /api/v1/oauth-clients/local endpoint and cached in-memory
|
* instance's /api/v1/oauth-clients/local endpoint and cached in-memory
|
||||||
* per process lifetime.
|
* per process lifetime.
|
||||||
*
|
*
|
||||||
* Upload uses the resumable protocol:
|
* Upload uses the Google-resumable protocol:
|
||||||
* POST /api/v1/videos/upload-resumable — init
|
* POST /api/v1/videos/upload-resumable — init (→ Location header with upload URL token)
|
||||||
* PUT /api/v1/videos/upload-resumable — send chunk
|
* PATCH <Location URL> — send chunk
|
||||||
* DELETE /api/v1/videos/upload-resumable — cancel
|
* HEAD <Location URL> — resume check
|
||||||
|
* DELETE <Location URL> — cancel
|
||||||
*/
|
*/
|
||||||
class PeerTubeService
|
class PeerTubeService
|
||||||
{
|
{
|
||||||
@@ -205,33 +206,31 @@ class PeerTubeService
|
|||||||
'Content-Length: ' . strlen($initBody),
|
'Content-Length: ' . strlen($initBody),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$initJson = json_decode($initResponse['body'], true);
|
// PeerTube Google-resumable returns the upload session URL in the Location header.
|
||||||
if ($initResponse['status'] < 200 || $initResponse['status'] >= 300) {
|
// The JSON body contains video.id (upload session ID, not final video ID).
|
||||||
|
$chunkUrl = $initResponse['headers']['location'] ?? $initResponse['headers']['Location'] ?? null;
|
||||||
|
if (!$chunkUrl) {
|
||||||
|
$initJson = json_decode($initResponse['body'], true);
|
||||||
$msg = $initJson['error'] ?? $initJson['detail'] ?? $initResponse['body'];
|
$msg = $initJson['error'] ?? $initJson['detail'] ?? $initResponse['body'];
|
||||||
throw new \RuntimeException('PeerTube upload init failed (' . $initResponse['status'] . '): ' . $msg);
|
throw new \RuntimeException('PeerTube upload init: no Location header (' . $initResponse['status'] . '): ' . $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Small files may complete in one shot
|
// Relative Location? Make it absolute.
|
||||||
$shortUuid = $initJson['video']['shortUUID'] ?? $initJson['video']['uuid'] ?? null;
|
if (!str_starts_with($chunkUrl, 'http')) {
|
||||||
if ($shortUuid && !isset($initJson['video']['id'])) {
|
$chunkUrl = rtrim($baseUrl, '/') . $chunkUrl;
|
||||||
$watchUrl = rtrim($baseUrl, '/') . '/videos/watch/' . $shortUuid;
|
|
||||||
return ['uuid' => $shortUuid, 'watchUrl' => $watchUrl];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$uploadId = $initJson['video']['id'] ?? null;
|
// ── Step 2: Send chunks via PATCH (Google-resumable variant) ──
|
||||||
if (!$uploadId) {
|
|
||||||
throw new \RuntimeException('PeerTube upload init: no upload session returned.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Step 2: Send chunks ──
|
|
||||||
$chunkUrl = $baseUrl . '/api/v1/videos/upload-resumable?upload_id=' . urlencode((string)$uploadId);
|
|
||||||
|
|
||||||
$fh = fopen($filePath, 'rb');
|
$fh = fopen($filePath, 'rb');
|
||||||
if (!$fh) {
|
if (!$fh) {
|
||||||
throw new \RuntimeException('Cannot open file for resumable upload.');
|
throw new \RuntimeException('Cannot open file for resumable upload.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunkSize = 4 * 1024 * 1024;
|
// Chunk size: 1 MB, must be a multiple of 256 KB (262144 bytes).
|
||||||
|
$chunkSizeBase = 256 * 1024;
|
||||||
|
$chunkSize = max($chunkSizeBase, min(4 * 1024 * 1024, (int)ceil($fileSize / 100)));
|
||||||
|
$chunkSize = (int)ceil($chunkSize / $chunkSizeBase) * $chunkSizeBase;
|
||||||
|
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
$lastResponse = null;
|
$lastResponse = null;
|
||||||
|
|
||||||
@@ -240,9 +239,9 @@ class PeerTubeService
|
|||||||
$chunkLen = strlen($chunk);
|
$chunkLen = strlen($chunk);
|
||||||
$end = $offset + $chunkLen - 1;
|
$end = $offset + $chunkLen - 1;
|
||||||
|
|
||||||
$resp = self::httpRequest($chunkUrl, 'PUT', $chunk, [
|
$resp = self::httpRequest($chunkUrl, 'PATCH', $chunk, [
|
||||||
'Authorization: Bearer ' . $token,
|
'Authorization: Bearer ' . $token,
|
||||||
'Content-Type: application/octet-stream',
|
'Content-Type: ' . $mimeType,
|
||||||
'Content-Range: bytes ' . $offset . '-' . $end . '/' . $fileSize,
|
'Content-Range: bytes ' . $offset . '-' . $end . '/' . $fileSize,
|
||||||
'Content-Length: ' . $chunkLen,
|
'Content-Length: ' . $chunkLen,
|
||||||
], 600);
|
], 600);
|
||||||
@@ -256,13 +255,12 @@ class PeerTubeService
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} elseif ($resp['status'] === 308) {
|
} elseif ($resp['status'] === 308) {
|
||||||
|
// Resume Incomplete — chunk accepted, continue
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
fclose($fh);
|
fclose($fh);
|
||||||
try {
|
try {
|
||||||
self::httpRequest($chunkUrl, 'DELETE', '', [
|
self::cancelUpload($chunkUrl, $token);
|
||||||
'Authorization: Bearer ' . $token, 'Content-Length: 0',
|
|
||||||
], 10);
|
|
||||||
} catch (\Throwable $e) { /* ignore */ }
|
} catch (\Throwable $e) { /* ignore */ }
|
||||||
$errJson = json_decode($resp['body'], true);
|
$errJson = json_decode($resp['body'], true);
|
||||||
$msg = $errJson['error'] ?? $errJson['detail'] ?? $resp['body'];
|
$msg = $errJson['error'] ?? $errJson['detail'] ?? $resp['body'];
|
||||||
@@ -436,10 +434,25 @@ class PeerTubeService
|
|||||||
// HTTP helper
|
// HTTP helper
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a resumable upload session.
|
||||||
|
*/
|
||||||
|
private static function cancelUpload(string $chunkUrl, string $token): void
|
||||||
|
{
|
||||||
|
self::httpRequest($chunkUrl, 'DELETE', '', [
|
||||||
|
'Authorization: Bearer ' . $token,
|
||||||
|
'Content-Length: 0',
|
||||||
|
], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// HTTP helper
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal cURL HTTP helper.
|
* Minimal cURL HTTP helper.
|
||||||
*
|
*
|
||||||
* @return array{status:int, body:string}
|
* @return array{status:int, body:string, headers:array<string,string>}
|
||||||
*/
|
*/
|
||||||
public static function httpRequest(
|
public static function httpRequest(
|
||||||
string $url,
|
string $url,
|
||||||
@@ -457,31 +470,47 @@ class PeerTubeService
|
|||||||
CURLOPT_RETURNTRANSFER => true,
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
CURLOPT_TIMEOUT => $timeout,
|
CURLOPT_TIMEOUT => $timeout,
|
||||||
CURLOPT_CONNECTTIMEOUT => 15,
|
CURLOPT_CONNECTTIMEOUT => 15,
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
CURLOPT_FOLLOWLOCATION => false, // Must be false to capture Location header
|
||||||
CURLOPT_MAXREDIRS => 3,
|
CURLOPT_MAXREDIRS => 3,
|
||||||
CURLOPT_SSL_VERIFYPEER => true,
|
CURLOPT_SSL_VERIFYPEER => true,
|
||||||
CURLOPT_SSL_VERIFYHOST => 2,
|
CURLOPT_SSL_VERIFYHOST => 2,
|
||||||
CURLOPT_HTTPHEADER => $headers,
|
CURLOPT_HTTPHEADER => $headers,
|
||||||
|
CURLOPT_HEADERFUNCTION => function ($ch, $headerLine) use (&$responseHeaders) {
|
||||||
|
$len = strlen($headerLine);
|
||||||
|
$parts = explode(':', $headerLine, 2);
|
||||||
|
if (count($parts) === 2) {
|
||||||
|
$responseHeaders[strtolower(trim($parts[0]))] = trim($parts[1]);
|
||||||
|
}
|
||||||
|
return $len;
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$responseHeaders = [];
|
||||||
|
|
||||||
if ($method === 'POST') {
|
if ($method === 'POST') {
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||||
} elseif ($method === 'PUT') {
|
} elseif ($method === 'PUT') {
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||||
|
} elseif ($method === 'PATCH') {
|
||||||
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||||
} elseif ($method === 'DELETE') {
|
} elseif ($method === 'DELETE') {
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||||
|
} elseif ($method === 'HEAD') {
|
||||||
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
||||||
|
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$responseBody = curl_exec($ch);
|
$responseBody = curl_exec($ch);
|
||||||
$status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
$error = curl_error($ch);
|
$error = curl_error($ch);
|
||||||
|
|
||||||
if ($responseBody === false) {
|
if ($responseBody === false && $method !== 'HEAD') {
|
||||||
throw new \RuntimeException('Erreur réseau PeerTube : ' . $error);
|
throw new \RuntimeException('Erreur réseau PeerTube : ' . $error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['status' => $status, 'body' => (string)$responseBody];
|
return ['status' => $status, 'body' => (string)$responseBody, 'headers' => $responseHeaders];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -844,6 +844,32 @@
|
|||||||
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
+\\\\\\\ to: usmyqlwr 6acee66b "cleanup: merge SMTP fields into single fieldset, rename to Emails" (rebased revision)
|
+\\\\\\\ to: usmyqlwr 6acee66b "cleanup: merge SMTP fields into single fieldset, rename to Emails" (rebased revision)
|
||||||
++ $linkName = $link['name'] ?? '';
|
++ $linkName = $link['name'] ?? '';
|
||||||
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: usmyqlwr 6acee66b "cleanup: merge SMTP fields into single fieldset, rename to Emails" (rebased revision)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
- $linkName = $link['name'] ?? '';
|
||||||
|
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: omwsuqoy 6cde5a47 "move Restrictions d'accès aux fichiers from contenus.php to acces.php" (rebased revision)
|
||||||
|
$linkName = $link['name'] ?? '';
|
||||||
|
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
$linkLockedYear = $link['locked_year'] ?? null;
|
||||||
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
+\\\\\\\ to: omwsuqoy 5886b400 "move Restrictions d'accès aux fichiers from contenus.php to acces.php" (rebased revision)
|
||||||
|
++ $linkName = $link['name'] ?? '';
|
||||||
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: omwsuqoy 5886b400 "move Restrictions d'accès aux fichiers from contenus.php to acces.php" (rebased revision)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
- $linkName = $link['name'] ?? '';
|
||||||
|
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: usxlqwxk 4dda0271 "Cleanup acces fichier section" (rebased revision)
|
||||||
|
$linkName = $link['name'] ?? '';
|
||||||
|
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
$linkLockedYear = $link['locked_year'] ?? null;
|
||||||
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
+\\\\\\\ to: usxlqwxk 3cd56fd1 "Cleanup acces fichier section" (rebased revision)
|
||||||
|
++ $linkName = $link['name'] ?? '';
|
||||||
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
?>
|
?>
|
||||||
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
||||||
@@ -970,7 +996,39 @@
|
|||||||
DEMANDES D'ACCÈS AUX FICHIERS
|
DEMANDES D'ACCÈS AUX FICHIERS
|
||||||
══════════════════════════════════════════════════════════════ -->
|
══════════════════════════════════════════════════════════════ -->
|
||||||
<section aria-labelledby="acces-fichiers-title">
|
<section aria-labelledby="acces-fichiers-title">
|
||||||
<h2 id="acces-fichiers-title">Demandes d'accès aux fichiers</h2>
|
|
||||||
|
<h2>Fichiers</h2>
|
||||||
|
|
||||||
|
<h3 id="acces-fichiers-title">Restrictions d'accès aux fichiers</h3>
|
||||||
|
|
||||||
|
<fieldset id="fieldset-restrictions">
|
||||||
|
<legend>Paramètre global</legend>
|
||||||
|
|
||||||
|
<div class="param-form">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||||
|
<input type="hidden" name="section" value="formulaire_restrictions">
|
||||||
|
|
||||||
|
<label class="param-checkbox">
|
||||||
|
<input type="checkbox" name="restricted_files_enabled" value="1"
|
||||||
|
<?= ($siteSettings['restricted_files_enabled'] ?? '0') === '1' ? 'checked' : '' ?>
|
||||||
|
hx-post="/admin/actions/settings.php"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-target="#restrictions-response"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-include="#fieldset-restrictions"
|
||||||
|
hx-on::before-request="console.log('[restrictions] sending checked=' + this.checked + ' POST keys will include all #fieldset-restrictions inputs')"
|
||||||
|
hx-on::after-request="console.log('[restrictions] response received')">
|
||||||
|
<span>
|
||||||
|
<strong>Activer la restriction d'accès</strong><br>
|
||||||
|
<small>Pour les TFE de type "Interne", masquer les fichiers et exiger une demande d'accès par email. Les métadonnées et le résumé restent visibles publiquement.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="restrictions-response" aria-live="polite"></div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<h3 id="acces-fichiers-title">Demandes d'accès aux fichiers</h3>
|
||||||
|
|
||||||
<div class="access-req-stats">
|
<div class="access-req-stats">
|
||||||
<div class="access-req-stat-card">
|
<div class="access-req-stat-card">
|
||||||
|
|||||||
@@ -85,33 +85,6 @@
|
|||||||
<section aria-labelledby="form-settings-title">
|
<section aria-labelledby="form-settings-title">
|
||||||
<h2 id="form-settings-title">Paramètres du Formulaire</h2>
|
<h2 id="form-settings-title">Paramètres du Formulaire</h2>
|
||||||
|
|
||||||
<fieldset id="fieldset-restrictions">
|
|
||||||
<legend>Restrictions d'accès aux fichiers</legend>
|
|
||||||
|
|
||||||
<div class="param-form">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
|
||||||
<input type="hidden" name="section" value="formulaire_restrictions">
|
|
||||||
|
|
||||||
<label class="param-checkbox">
|
|
||||||
<input type="checkbox" name="restricted_files_enabled" value="1"
|
|
||||||
<?= ($siteSettings['restricted_files_enabled'] ?? '0') === '1' ? 'checked' : '' ?>
|
|
||||||
hx-post="/admin/actions/settings.php"
|
|
||||||
hx-trigger="change"
|
|
||||||
hx-target="#restrictions-response"
|
|
||||||
hx-swap="innerHTML"
|
|
||||||
hx-include="#fieldset-restrictions"
|
|
||||||
hx-on::before-request="console.log('[restrictions] sending checked=' + this.checked + ' POST keys will include all #fieldset-restrictions inputs')"
|
|
||||||
hx-on::after-request="console.log('[restrictions] response received')">
|
|
||||||
<span>
|
|
||||||
<strong>Activer la restriction d'accès</strong><br>
|
|
||||||
<small>Pour les TFE de type "Interne", masquer les fichiers et exiger une demande d'accès par email. Les métadonnées et le résumé restent visibles publiquement.</small>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="restrictions-response" aria-live="polite"></div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset id="fieldset-acces">
|
<fieldset id="fieldset-acces">
|
||||||
<legend>Degré d'ouverture</legend>
|
<legend>Degré d'ouverture</legend>
|
||||||
<p>Options de visibilité disponibles dans le formulaire d'ajout de TFE.</p>
|
<p>Options de visibilité disponibles dans le formulaire d'ajout de TFE.</p>
|
||||||
|
|||||||
@@ -78,7 +78,9 @@
|
|||||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||||
<input type="hidden" name="section" value="smtp">
|
<input type="hidden" name="section" value="smtp">
|
||||||
|
|
||||||
<div class="param-grid">
|
<fieldset class="param-grid">
|
||||||
|
|
||||||
|
<legend>Paramètres email</legend>
|
||||||
<div>
|
<div>
|
||||||
<label for="smtp_host">Hôte SMTP</label>
|
<label for="smtp_host">Hôte SMTP</label>
|
||||||
<input type="text" id="smtp_host" name="smtp_host"
|
<input type="text" id="smtp_host" name="smtp_host"
|
||||||
@@ -146,7 +148,7 @@
|
|||||||
placeholder="admin@example.com">
|
placeholder="admin@example.com">
|
||||||
<small>Reçoit les notifications (demandes d'accès, etc.). Si vide, utilise l'adresse d'expédition.</small>
|
<small>Reçoit les notifications (demandes d'accès, etc.). Si vide, utilise l'adresse d'expédition.</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</fieldset>
|
||||||
|
|
||||||
<button type="submit" class="btn btn--primary">Enregistrer</button>
|
<button type="submit" class="btn btn--primary">Enregistrer</button>
|
||||||
</form>
|
</form>
|
||||||
@@ -182,10 +184,6 @@
|
|||||||
Intégration avec une instance PeerTube pour l'hébergement des vidéos et fichiers audio.
|
Intégration avec une instance PeerTube pour l'hébergement des vidéos et fichiers audio.
|
||||||
Les fichiers sont uploadés via l'API PeerTube et intégrés comme lecteurs embarqués sur la page du TFE.
|
Les fichiers sont uploadés via l'API PeerTube et intégrés comme lecteurs embarqués sur la page du TFE.
|
||||||
</p>
|
</p>
|
||||||
<p class="param-note">
|
|
||||||
⚠ L'activation nécessite un quota d'upload suffisant sur l'instance PeerTube.
|
|
||||||
Laissez désactivé jusqu'à obtention du quota.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="param-smtp-status">
|
<div class="param-smtp-status">
|
||||||
<?php if ($peerTubeConfigured): ?>
|
<?php if ($peerTubeConfigured): ?>
|
||||||
@@ -213,12 +211,14 @@
|
|||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
||||||
|
<fieldset class="param-grid">
|
||||||
|
<legend>Paramètres Peertube</legend>
|
||||||
<p class="param-note">
|
<p class="param-note">
|
||||||
ℹ L'authentification PeerTube utilise les mêmes identifiants que le
|
ℹ L'authentification PeerTube utilise les mêmes identifiants que le
|
||||||
<strong>relay SMTP</strong> configuré ci-dessus.
|
<strong>relay SMTP</strong> configuré ci-dessus.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="param-grid">
|
|
||||||
<div>
|
<div>
|
||||||
<label for="peertube_instance_url">URL de l'instance PeerTube</label>
|
<label for="peertube_instance_url">URL de l'instance PeerTube</label>
|
||||||
<input type="url" id="peertube_instance_url" name="peertube_instance_url"
|
<input type="url" id="peertube_instance_url" name="peertube_instance_url"
|
||||||
@@ -243,7 +243,7 @@
|
|||||||
<option value="3" <?= (int)$peerTubeSettings['privacy'] === 3 ? 'selected' : '' ?>>Privée</option>
|
<option value="3" <?= (int)$peerTubeSettings['privacy'] === 3 ? 'selected' : '' ?>>Privée</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</fieldset>
|
||||||
|
|
||||||
<button type="submit" class="btn btn--primary">Enregistrer</button>
|
<button type="submit" class="btn btn--primary">Enregistrer</button>
|
||||||
<button type="button" class="btn btn--secondary" id="peertube-test-btn"
|
<button type="button" class="btn btn--secondary" id="peertube-test-btn"
|
||||||
|
|||||||
Reference in New Issue
Block a user