chore: checkpoint initial — Zektyc dataset, avant humanisation

- site vitrine + fingerprint test + zmap + z-panel
- remplacement duckdns -> riricdev.tail5ea5cd.ts.net (canonical/og/alternates/docs)
- suppression du token DuckDNS (plus utilisé)
This commit is contained in:
riricdev 2026-09-06 13:03:25 +02:00
commit 8e7ec41f18
104 changed files with 19256 additions and 0 deletions

98
public/js/social.js Normal file
View file

@ -0,0 +1,98 @@
// Zektyc Social — Router v3 (CSP-safe)
(function() {
"use strict";
window._socialRender = function() {
switch (ZS.view) {
case "login": renderLogin(); break;
case "signup": renderSignup(); break;
case "privacy-choice": renderPrivacyChoice(); break;
case "profile": renderProfile(); break;
case "profile-view": renderProfileView(ZS.viewData); break;
case "settings": renderSettings(); break;
case "post": _renderNewPost(); break;
case "community": renderCommunity(); break;
case "messages": renderMessages(); break;
case "chat": renderChat(ZS.viewData); break;
case "notifications": renderNotifications(); break;
case "mod": renderMod(); break;
default: renderFeed(); break;
}
var nav = document.getElementById("socialHeaderNav");
if (nav) nav.classList.remove("open");
ZS._navOpen = false;
if (typeof _applyAvatarStyles === "function") _applyAvatarStyles();
};
function _renderNewPost() {
if (!ZS.user) { ZS.navigate("login"); return; }
var avatarHtml = ZS.user.avatarUrl
? '<div class="compose-avatar"><img src="' + ZS.esc(ZS.user.avatarUrl) + '" alt=""></div>'
: '<div class="compose-avatar">' + ZS.esc(ZS.user.username).charAt(0).toUpperCase() + '</div>';
var html = '<h2 class="mb-16">' + ZS.icon("pen") + ' ' + ZS.t("Nouvelle publication", "New post") + '</h2>' +
'<div class="compose-box">' +
'<div class="compose-row">' +
avatarHtml +
'<div class="compose-input-wrap">' +
'<textarea id="fullComposeText" placeholder="' + ZS.t("Quoi de neuf ?", "What's new?") + '" rows="4" maxlength="5000" class="auto-resize"></textarea>' +
'<div id="fullEmojiPicker" class="emoji-picker hidden">' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="😀">😀</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="😂">😂</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="❤️">❤️</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="🔥">🔥</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="👍">👍</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="👀">👀</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="💯">💯</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="🎉">🎉</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="🤔">🤔</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="😎">😎</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="🚀">🚀</span>' +
'<span class="emoji-pick" data-action="insertEmojiFull" data-arg1="💡">💡</span>' +
'</div>' +
'</div></div>' +
'<div class="compose-footer">' +
'<div class="compose-meta">' +
'<button type="button" class="compose-emoji-btn" data-action="toggleEmojiFull">' + ZS.icon("star") + '</button>' +
'<span class="compose-counter" id="fullComposeCounter">0/5000</span>' +
'<select class="compose-vis-select" id="fullComposeVis">' +
'<option value="public">' + ZS.icon("globe") + ' ' + ZS.t("Public", "Public") + '</option>' +
'<option value="connections_only">' + ZS.icon("users") + ' ' + ZS.t("Connexions", "Connections") + '</option>' +
'<option value="private">' + ZS.icon("lock") + ' ' + ZS.t("Privé", "Private") + '</option>' +
'</select></div>' +
'<button class="btn-primary btn-primary-sm" data-action="submitFullPost">' + ZS.icon("send") + ' ' + ZS.t("Publier", "Post") + '</button>' +
'</div></div>' +
'<div class="info-box mt-12">' + ZS.icon("note") + ' ' + ZS.t("Vérifié par un modérateur avant publication.", "Reviewed by a moderator before publishing.") + '</div>' +
'<p class="mt-12"><a href="#" class="text-sm" data-action="nav" data-arg1="feed">' + ZS.icon("arrowLeft") + ' ' + ZS.t("Retour au fil", "Back to feed") + '</a></p>';
ZS.renderShell(null, html, null);
document.getElementById("fullComposeVis").value = ZS.user.privacyLevel || "connections_only";
var ta = document.getElementById("fullComposeText");
if (ta) ta.focus();
}
window.submitFullPost = async function() {
var textarea = document.getElementById("fullComposeText");
if (!textarea || !textarea.value.trim()) return;
var vis = document.getElementById("fullComposeVis").value;
var data = await ZS.api("POST", "/api/social/posts", { content: textarea.value.trim(), visibility: vis });
if (data.error) { alert(data.error); return; }
ZS.navigate("feed");
};
// Init
window.addEventListener("popstate", function(e) {
var parsed = e.state && e.state.view ? e.state : ZS._parsePath();
ZS.view = parsed.view;
ZS.viewData = parsed.data;
if (window._socialRender) window._socialRender();
});
ZS.checkSession().then(function() {
var parsed = ZS._parsePath();
if (parsed.view !== "feed" || parsed.data) {
ZS.view = parsed.view;
ZS.viewData = parsed.data;
}
ZS.navigate(ZS.view, ZS.viewData);
});
})();