feat: social media aggregator (YouTube, Instagram, TikTok, WordPress)

This commit is contained in:
2026-05-18 17:49:23 +04:00
parent 18cf71a7da
commit 5c3b35cb3c
10 changed files with 1679 additions and 906 deletions
+32 -92
View File
@@ -181,107 +181,47 @@ function validateCSRFToken($token) {
* Applique des en-têtes de sécurité HTTP
*/
function setSecurityHeaders() {
// Protection contre le clickjacking (permettre les iframes du même site)
header('X-Frame-Options: SAMEORIGIN');
// Protection contre le MIME sniffing
header('X-Content-Type-Options: nosniff');
// Protection XSS basique
header('X-XSS-Protection: 1; mode=block');
// Politique de référent
header('Referrer-Policy: strict-origin-when-cross-origin');
// Content Security Policy avec support Mastodon et PeerTube
$mastodonDomain = '';
$peertubeDomain = '';
// Extraire le domaine Mastodon si configuré
if (defined('MASTODON_INSTANCE_URL')) {
$mastodonParsed = parse_url(MASTODON_INSTANCE_URL);
if ($mastodonParsed && isset($mastodonParsed['host'])) {
$mastodonDomain = $mastodonParsed['scheme'] . '://' . $mastodonParsed['host'];
}
}
// Extraire le domaine PeerTube si configuré
if (defined('PEERTUBE_URL')) {
$peertubeParsed = parse_url(PEERTUBE_URL);
if ($peertubeParsed && isset($peertubeParsed['host'])) {
$peertubeDomain = $peertubeParsed['scheme'] . '://' . $peertubeParsed['host'];
}
}
// Détecter si on est en développement local
$isLocalDev = in_array($_SERVER['HTTP_HOST'] ?? '', ['127.0.0.1:8080', '127.0.0.1:8001', 'localhost:8080', 'localhost:8001', '127.0.0.1', 'localhost']);
$csp = "default-src 'self'; ";
$isLocalDev = in_array(
$_SERVER['HTTP_HOST'] ?? '',
['127.0.0.1:8080', '127.0.0.1:8001', 'localhost:8080', 'localhost:8001', '127.0.0.1', 'localhost']
);
// Domaines des 5 plateformes sociales
$fbScripts = 'https://connect.facebook.net';
$fbFrames = 'https://www.facebook.com https://staticxx.facebook.com https://www.facebook.net';
$xScripts = 'https://platform.twitter.com';
$xFrames = 'https://platform.twitter.com https://syndication.twitter.com https://cdn.syndication.twimg.com';
$igScripts = 'https://www.instagram.com';
$igFrames = 'https://www.instagram.com';
$ttScripts = 'https://www.tiktok.com https://lf16-tiktok-web.ttwstatic.com';
$ttFrames = 'https://www.tiktok.com';
$ytImages = 'https://i.ytimg.com https://yt3.ggpht.com';
$csp = "default-src 'self'; ";
$csp .= "style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; ";
$csp .= "script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://plausible.io; "; // PLAUSIBLE UPDATED
// Images : autoriser les domaines externes plus HTTPS général en dev
$imgSrc = "'self' data: " . ($mastodonDomain ? $mastodonDomain : '') . " " . ($peertubeDomain ? $peertubeDomain : '');
if ($isLocalDev) {
$imgSrc .= " https: http:";
} else {
$imgSrc .= " https:";
}
$csp .= "img-src " . $imgSrc . "; ";
$csp .= "font-src 'self' https://cdnjs.cloudflare.com; ";
// Frames : autoriser PeerTube et HTTPS général
$frameSrc = "'self' " . ($peertubeDomain ? $peertubeDomain : '');
if ($isLocalDev) {
$frameSrc .= " https: http:";
} else {
$frameSrc .= " https:";
}
$csp .= "frame-src " . $frameSrc . "; ";
// Connexions : autoriser Mastodon et PeerTube
$connectSrc = "'self' https://plausible.io " . ($mastodonDomain ? $mastodonDomain : '') . " " . ($peertubeDomain ? $peertubeDomain : '');
if ($isLocalDev) {
$connectSrc .= " ws: wss:"; // WebSockets pour le dev
}
$csp .= "connect-src " . $connectSrc . "; ";
// Médias : toujours autoriser 'self', Mastodon et PeerTube
$mediaSrc = "'self'";
// Ajouter l'instance Mastodon (pour les médias stockés sur l'instance)
if ($mastodonDomain) {
$mediaSrc .= " " . $mastodonDomain;
}
// Ajouter PeerTube
if ($peertubeDomain) {
$mediaSrc .= " " . $peertubeDomain;
}
// Ajouter l'URL S3 Mastodon si configurée (pour les médias externalisés)
if (defined('MASTODON_S3_MEDIA_URL') && !empty(MASTODON_S3_MEDIA_URL)) {
$s3Parsed = parse_url(MASTODON_S3_MEDIA_URL);
if ($s3Parsed && isset($s3Parsed['host'])) {
$s3Domain = $s3Parsed['scheme'] . '://' . $s3Parsed['host'];
$mediaSrc .= " " . $s3Domain;
}
}
if ($isLocalDev) {
$mediaSrc .= " https: http:";
} else {
$mediaSrc .= " https:";
}
$csp .= "media-src " . $mediaSrc . "; ";
$csp .= "script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://plausible.io "
. "{$fbScripts} {$xScripts} {$igScripts} {$ttScripts}; ";
$csp .= "img-src 'self' data: {$ytImages} https://www.facebook.com https://pbs.twimg.com https://abs.twimg.com"
. ($isLocalDev ? " https: http:" : " https:") . "; ";
$csp .= "frame-src 'self' {$fbFrames} {$xFrames} {$igFrames} {$ttFrames} https://www.youtube.com"
. ($isLocalDev ? " http:" : "") . "; ";
$csp .= "connect-src 'self' https://plausible.io https://www.googleapis.com https://www.youtube.com "
. "https://www.facebook.com https://graph.facebook.com https://connect.facebook.net "
. "https://platform.twitter.com https://syndication.twitter.com https://cdn.syndication.twimg.com https://api.twitter.com "
. "https://www.instagram.com https://www.tiktok.com"
. ($isLocalDev ? " ws: wss:" : "") . "; ";
$csp .= "media-src 'self' https:; ";
$csp .= "object-src 'none'; ";
$csp .= "base-uri 'self';";
header('Content-Security-Policy: ' . $csp);
// HTTPS strict transport security (seulement si HTTPS)
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
}