Main.php

PHP wanda 1 Vues Taille : 45.18 KB Date : Jan 15, 26 @ 3:12 PM
  1. 1<?php
  2. 2/*
  3. 3 * paste.lesalkodiques.info
  4. 4 * Fichier : /theme/default/main.php
  5. 5 * Licence : GPL-3.0-or-later (voir LICENCE)
  6. 6 */
  7. 7
  8. 8$cap_e = $_SESSION['cap_e'] ?? 'off'; // Define $cap_e to avoid PHP errors
  9. 9$captcha_mode = $_SESSION['captcha_mode'] ?? 'none'; // 'recaptcha' (v2 checkbox), 'recaptcha_v3', 'turnstile', 'internal', 'none'
  10. 10$main_sitekey = $_SESSION['captcha'] ?? ''; // sitekey for this main form (set in index during GET)
  11. 11
  12. 12$nonce = $GLOBALS['csp_nonce'] ?? '';
  13. 13?>
  14. 14
  15. 15<div class="container-xxl my-4">
  16. 16 <div class="row">
  17. 17 <?php if (isset($privatesite) && $privatesite === "on"): ?>
  18. 18 <div class="col-lg-12">
  19. 19 <?php if (!isset($_SESSION['username'])): ?>
  20. 20 <div class="card">
  21. 21 <div class="card-body">
  22. 22 <div class="alert alert-warning">
  23. 23 <?php echo htmlspecialchars($lang['login_required'] ?? 'Vous devez être connecté pour créer un paste.', ENT_QUOTES, 'UTF-8'); ?>
  24. 24 <a href="<?php echo htmlspecialchars($baseurl . 'login.php', ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-primary mt-2">
  25. 25 <?php echo htmlspecialchars($lang['login'] ?? 'Connexion', ENT_QUOTES, 'UTF-8'); ?>
  26. 26 </a>
  27. 27 </div>
  28. 28 </div>
  29. 29 </div>
  30. 30 <?php else: ?>
  31. 31 <div class="card">
  32. 32 <div class="card-header">
  33. 33 <h1><?php echo htmlspecialchars($lang['newpaste'] ?? 'Nouveau paste', ENT_QUOTES, 'UTF-8'); ?></h1>
  34. 34 <?php
  35. 35 // Quick diff
  36. 36 $diffQuickUrl = rtrim($baseurl ?? '/', '/') . '/diff.php?a=oldpaste&b=newpaste';
  37. 37 ?>
  38. 38 </div>
  39. 39 <div class="card-body">
  40. 40 <?php if (!empty($flash_error)): ?>
  41. 41 <div class="alert alert-danger"><?php echo htmlspecialchars($flash_error, ENT_QUOTES, 'UTF-8'); ?></div>
  42. 42 <?php elseif (isset($_GET['error'])): ?>
  43. 43 <div class="alert alert-warning"><?php echo htmlspecialchars($_GET['error'], ENT_QUOTES, 'UTF-8'); ?></div>
  44. 44 <?php elseif (isset($_GET['success'])): ?>
  45. 45 <div class="alert alert-success"><?php echo htmlspecialchars($_GET['success'], ENT_QUOTES, 'UTF-8'); ?></div>
  46. 46 <?php elseif (isset($error)): ?>
  47. 47 <div class="alert alert-warning"><?php echo htmlspecialchars($error, ENT_QUOTES, 'UTF-8'); ?></div>
  48. 48 <?php endif; ?>
  49. 49
  50. 50 <form class="form-horizontal" name="mainForm" id="mainForm" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="POST">
  51. 51 <div class="row mb-3 g-3">
  52. 52 <div class="col-sm-4">
  53. 53 <div class="input-group">
  54. 54 <span class="input-group-text"><i class="bi bi-fonts"></i></span>
  55. 55 <input type="text" class="form-control" name="title"
  56. 56 placeholder="<?php echo htmlspecialchars($lang['pastetitle'] ?? 'Titre du paste', ENT_QUOTES, 'UTF-8'); ?>">
  57. 57 </div>
  58. 58 </div>
  59. 59
  60. 60 <div class="col-sm-4">
  61. 61 <select class="form-select" name="format" id="format">
  62. 62 <?php
  63. 63 $geshiformats = $geshiformats ?? [];
  64. 64 $popular_formats = $popular_formats ?? [];
  65. 65
  66. 66 // Format sélectionné logic
  67. 67 if (isset($_POST['format']) && $_POST['format'] !== '') {
  68. 68 $selectedCode = (string) $_POST['format'];
  69. 69 } elseif (!empty($paste_data) && !empty($p_code)) {
  70. 70 $selectedCode = (string) $p_code;
  71. 71 } else {
  72. 72 $selectedCode = 'text';
  73. 73 }
  74. 74
  75. 75 // sécurité : si le code n'est pas connu, on revient à text
  76. 76 if ($selectedCode !== 'text' && $selectedCode !== 'autodetect' && !array_key_exists($selectedCode, $geshiformats)) {
  77. 77 $selectedCode = 'text';
  78. 78 }
  79. 79
  80. 80 $isSel = function ($code) use ($selectedCode) {
  81. 81 return ($selectedCode === $code) ? ' selected="selected"' : '';
  82. 82 };
  83. 83
  84. 84 // 1) Plain Text
  85. 85 echo '<option value="text"' . $isSel('text') . '>Plain Text</option>';
  86. 86 // 2) Autodetect
  87. 87 echo '<option value="autodetect"' . $isSel('autodetect') . '>Autodetect Language</option>';
  88. 88 // Séparateur
  89. 89 echo '<option disabled="disabled">-------------------------------------</option>';
  90. 90
  91. 91 // 3) Populaires
  92. 92 foreach ($geshiformats as $code => $name) {
  93. 93 if ($code === 'text' || $code === 'autodetect') continue;
  94. 94 if (in_array($code, $popular_formats, true)) {
  95. 95 echo '<option value="' . htmlspecialchars($code, ENT_QUOTES, 'UTF-8') . '"' . $isSel($code) . '>'
  96. 96 . htmlspecialchars($name, ENT_QUOTES, 'UTF-8')
  97. 97 . '</option>';
  98. 98 }
  99. 99 }
  100. 100
  101. 101 // 4) Le reste
  102. 102 foreach ($geshiformats as $code => $name) {
  103. 103 if ($code === 'text' || $code === 'autodetect') continue;
  104. 104 if (!in_array($code, $popular_formats, true)) {
  105. 105 echo '<option value="' . htmlspecialchars($code, ENT_QUOTES, 'UTF-8') . '"' . $isSel($code) . '>'
  106. 106 . htmlspecialchars($name, ENT_QUOTES, 'UTF-8')
  107. 107 . '</option>';
  108. 108 }
  109. 109 }
  110. 110 ?>
  111. 111 </select>
  112. 112 </div>
  113. 113
  114. 114 <div class="col-sm-4 d-flex justify-content-end align-items-center gap-2">
  115. 115 <a class="btn btn-secondary btn-sm" href="<?php echo htmlspecialchars($diffQuickUrl, ENT_QUOTES, 'UTF-8'); ?>" title="<?php echo htmlspecialchars($lang['view_differences'] ?? 'Voir les différences', ENT_QUOTES, 'UTF-8'); ?>"><i class="bi bi-arrow-left-right"></i> .diff</a>
  116. 116
  117. 117 <button type="button" class="btn btn-outline-secondary" id="load_file_btn"
  118. 118 title="<?php echo htmlspecialchars($lang['load_file_no_upload'] ?? 'Charger un fichier dans l’éditeur (sans téléversement)', ENT_QUOTES, 'UTF-8'); ?>">
  119. 119 <i class="bi bi-upload"></i> <?php echo htmlspecialchars($lang['load'] ?? 'Charger', ENT_QUOTES, 'UTF-8'); ?>
  120. 120 </button>
  121. 121
  122. 122 <button type="button" class="btn btn-outline-secondary" id="clear_file_btn"
  123. 123 title="<?php echo htmlspecialchars($lang['clear_editor'] ?? 'Vider l’éditeur', ENT_QUOTES, 'UTF-8'); ?>">
  124. 124 <i class="bi bi-x-circle"></i> <?php echo htmlspecialchars($lang['clear'] ?? 'Vider', ENT_QUOTES, 'UTF-8'); ?>
  125. 125 </button>
  126. 126
  127. 127 <input type="file" id="code_file" class="visually-hidden"
  128. 128 accept=".txt,.md,.php,.js,.ts,.jsx,.tsx,.py,.rb,.java,.c,.cpp,.h,.cs,.go,.rs,.kt,.swift,.sh,.ps1,.sql,.html,.htm,.css,.scss,.json,.xml,.yml,.yaml,.ini,.conf,text/*">
  129. 129 </div>
  130. 130 </div>
  131. 131
  132. 132 <div id="file-announce" class="visually-hidden" aria-live="polite"></div>
  133. 133
  134. 134 <div class="mb-3">
  135. 135 <textarea class="form-control" rows="15" id="edit-code" name="paste_data"
  136. 136 placeholder="<?php echo htmlspecialchars($lang['paste_content'] ?? 'Contenu du paste', ENT_QUOTES, 'UTF-8'); ?>"
  137. 137 data-max-bytes="<?php echo 1024 * 1024 * ($pastelimit ?? 10); ?>"><?php echo htmlspecialchars($paste_data ?? '', ENT_QUOTES, 'UTF-8'); ?></textarea>
  138. 138 </div>
  139. 139
  140. 140 <div class="row mb-3">
  141. 141 <label class="col-sm-2 col-form-label"><?php echo htmlspecialchars($lang['expiration'] ?? 'Expiration', ENT_QUOTES, 'UTF-8'); ?></label>
  142. 142 <div class="col-sm-10">
  143. 143 <select class="form-select" name="paste_expire_date">
  144. 144 <option value="N" <?php echo ($paste_expire_date ?? 'N') == "N" ? 'selected' : ''; ?>>Jamais</option>
  145. 145 <option value="self" <?php echo ($paste_expire_date ?? 'N') == "self" ? 'selected' : ''; ?>>Voir 1 fois</option>
  146. 146 <option value="10M" <?php echo ($paste_expire_date ?? 'N') == "10M" ? 'selected' : ''; ?>>10 minutes</option>
  147. 147 <option value="1H" <?php echo ($paste_expire_date ?? 'N') == "1H" ? 'selected' : ''; ?>>1 heure</option>
  148. 148 <option value="1D" <?php echo ($paste_expire_date ?? 'N') == "1D" ? 'selected' : ''; ?>>1 jour</option>
  149. 149 <option value="1W" <?php echo ($paste_expire_date ?? 'N') == "1W" ? 'selected' : ''; ?>>1 semaine</option>
  150. 150 <option value="2W" <?php echo ($paste_expire_date ?? 'N') == "2W" ? 'selected' : ''; ?>>2 semaines</option>
  151. 151 <option value="1M" <?php echo ($paste_expire_date ?? 'N') == "1M" ? 'selected' : ''; ?>>1 mois</option>
  152. 152 </select>
  153. 153 </div>
  154. 154 </div>
  155. 155
  156. 156 <div class="row mb-3">
  157. 157 <label class="col-sm-2 col-form-label"><?php echo htmlspecialchars($lang['visibility'] ?? 'Visibilité', ENT_QUOTES, 'UTF-8'); ?></label>
  158. 158 <div class="col-sm-10">
  159. 159 <select class="form-select" name="visibility">
  160. 160 <option value="0" <?php echo ($p_visible ?? '1') == "0" ? 'selected' : ''; ?>>
  161. 161 <?php echo htmlspecialchars($lang['public'] ?? 'Public', ENT_QUOTES, 'UTF-8'); ?>
  162. 162 </option>
  163. 163 <option value="1" <?php echo ($p_visible ?? '1') == "1" ? 'selected' : ''; ?>>
  164. 164 <?php echo htmlspecialchars($lang['unlisted'] ?? 'Non listé', ENT_QUOTES, 'UTF-8'); ?>
  165. 165 </option>
  166. 166 <option value="2" <?php echo ($p_visible ?? '1') == "2" ? 'selected' : ''; ?>>
  167. 167 <?php echo htmlspecialchars($lang['private'] ?? 'Privé', ENT_QUOTES, 'UTF-8'); ?>
  168. 168 </option>
  169. 169 </select>
  170. 170 </div>
  171. 171 </div>
  172. 172
  173. 173 <div class="mb-3">
  174. 174 <div class="input-group">
  175. 175 <span class="input-group-text"><i class="bi bi-lock"></i></span>
  176. 176 <input type="text" class="form-control" name="pass" id="pass"
  177. 177 placeholder="<?php echo htmlspecialchars($lang['pwopt'] ?? 'Mot de passe (optionnel)', ENT_QUOTES, 'UTF-8'); ?>">
  178. 178 </div>
  179. 179 </div>
  180. 180
  181. 181 <div class="mb-3 form-check d-none" aria-hidden="true">
  182. 182 <input type="checkbox" class="form-check-input" id="client_encrypt" name="client_encrypt" value="0" disabled>
  183. 183 <label class="form-check-label" for="client_encrypt">
  184. 184 <?php echo htmlspecialchars($lang['client_encrypt_label'] ?? 'Activer le chiffrement côté client (AES-256-GCM)', ENT_QUOTES, 'UTF-8'); ?>
  185. 185 </label>
  186. 186 </div>
  187. 187
  188. 188 <input type="hidden" name="is_client_encrypted" id="is_client_encrypted" value="0">
  189. 189
  190. 190 <div class="modal fade d-none" id="encryptPassModal" tabindex="-1" aria-labelledby="encryptPassLabel" aria-hidden="true">
  191. 191 <div class="modal-dialog">
  192. 192 <div class="modal-content">
  193. 193 <div class="modal-header">
  194. 194 <h5 class="modal-title" id="encryptPassLabel">
  195. 195 <?php echo htmlspecialchars($lang['encrypt_modal_title'] ?? 'Définir la phrase de chiffrement', ENT_QUOTES, 'UTF-8'); ?>
  196. 196 </h5>
  197. 197 <button type="button" class="btn-close" data-bs-dismiss="modal"
  198. 198 aria-label="<?php echo htmlspecialchars($lang['close'] ?? 'Fermer', ENT_QUOTES, 'UTF-8'); ?>"></button>
  199. 199 </div>
  200. 200
  201. 201 <div class="modal-body">
  202. 202 <p><?php echo htmlspecialchars($lang['encrypt_modal_help'] ?? 'Saisissez une phrase secrète robuste (et gardez-la précieusement) :', ENT_QUOTES, 'UTF-8'); ?></p>
  203. 203
  204. 204 <div class="input-group mb-3">
  205. 205 <input type="password" class="form-control" id="encryptPassInput" autocomplete="new-password"
  206. 206 placeholder="<?php echo htmlspecialchars($lang['encrypt_pass_placeholder'] ?? 'Entrez la phrase secrète', ENT_QUOTES, 'UTF-8'); ?>">
  207. 207 <button type="button" class="btn btn-outline-secondary" id="toggleEncryptPass"
  208. 208 title="<?php echo htmlspecialchars($lang['show_hide_password'] ?? 'Afficher / masquer', ENT_QUOTES, 'UTF-8'); ?>">
  209. 209 <i class="bi bi-eye" id="encryptPassIcon"></i>
  210. 210 </button>
  211. 211 </div>
  212. 212
  213. 213 <div class="mt-2">
  214. 214 <div class="progress" style="--height: 5px;">
  215. 215 <div id="passStrengthBar" class="progress-bar" role="progressbar" style="width: 0%;"></div>
  216. 216 </div>
  217. 217 <small id="passStrengthText" class="text-muted">
  218. 218 <?php echo htmlspecialchars($lang['strength_weak'] ?? 'Force : faible', ENT_QUOTES, 'UTF-8'); ?>
  219. 219 </small>
  220. 220 </div>
  221. 221
  222. 222 <small class="text-muted d-block mt-1">
  223. 223 <?php echo htmlspecialchars($lang['encrypt_rules'] ?? '12 caractères minimum ; mélangez majuscules/minuscules, chiffres et symboles.', ENT_QUOTES, 'UTF-8'); ?>
  224. 224 </small>
  225. 225 <span class="ms-2">Besoin d'aide ?</span>
  226. 226 <a href="https://paste.lesalkodiques.info/generatepasswd.php" target="_blank" rel="noopener noreferrer" class="text-decoration-none">Générer une phrase solide</a>
  227. 227 </div>
  228. 228
  229. 229 <div class="modal-footer">
  230. 230 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
  231. 231 <?php echo htmlspecialchars($lang['cancel'] ?? 'Annuler', ENT_QUOTES, 'UTF-8'); ?>
  232. 232 </button>
  233. 233 <button type="button" class="btn btn-primary" id="encryptConfirm" disabled>
  234. 234 <?php echo htmlspecialchars($lang['encrypt_btn'] ?? 'Chiffrer', ENT_QUOTES, 'UTF-8'); ?>
  235. 235 </button>
  236. 236 </div>
  237. 237 </div>
  238. 238 </div>
  239. 239 </div>
  240. 240
  241. 241 <div class="row mb-3">
  242. 242 <p class="text-muted"><small><?php echo htmlspecialchars($lang['encrypt'] ?? 'Chiffrement', ENT_QUOTES, 'UTF-8'); ?></small></p>
  243. 243 </div>
  244. 244
  245. 245 <?php
  246. 246 // Debug CAPTCHA condition (console serveur uniquement)
  247. 247 $captcha_condition = $cap_e == "on" && !isset($_SESSION['username']) && (!isset($disableguest) || $disableguest !== "on");
  248. 248 error_log("main.php: Condition CAPTCHA : " . ($captcha_condition ? 'vrai' : 'faux'));
  249. 249 if ($captcha_condition): ?>
  250. 250 <?php if ($captcha_mode === "recaptcha"): ?>
  251. 251 <div class="g-recaptcha mb-3" data-theme="dark"
  252. 252 data-sitekey="<?php echo htmlspecialchars($main_sitekey, ENT_QUOTES, 'UTF-8'); ?>"
  253. 253 data-callback="onRecaptchaSuccess"></div>
  254. 254 <input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">
  255. 255 <?php elseif ($captcha_mode === "recaptcha_v3"): ?>
  256. 256 <input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">
  257. 257 <?php elseif ($captcha_mode === "turnstile"): ?>
  258. 258 <div id="turnstile-main" class="cf-turnstile mb-3"
  259. 259 data-sitekey="<?php echo htmlspecialchars($main_sitekey, ENT_QUOTES, 'UTF-8'); ?>"
  260. 260 data-callback="onTurnstileSuccess"
  261. 261 data-action="create_paste"
  262. 262 data-retry-interval="1000"></div>
  263. 263 <input type="hidden" name="cf-turnstile-response" id="cf-turnstile-response">
  264. 264 <?php else: ?>
  265. 265 <?php include __DIR__ . '/captcha_bootstrap.php'; ?>
  266. 266 <?php endif; ?>
  267. 267 <?php endif; ?>
  268. 268
  269. 269 <div class="row mb-3">
  270. 270 <div class="d-grid gap-2">
  271. 271 <input class="btn btn-primary paste-button" type="submit" id="submit" data-recaptcha-action="create_paste"
  272. 272 value="<?php echo htmlspecialchars($lang['createpaste'] ?? 'Créer le paste', ENT_QUOTES, 'UTF-8'); ?>">
  273. 273 </div>
  274. 274 </div>
  275. 275
  276. 276 </form>
  277. 277 </div>
  278. 278 </div>
  279. 279 <?php endif; ?>
  280. 280 </div>
  281. 281
  282. 282 <div class="col-lg-2 mt-4 mt-lg-0">
  283. 283 <?php
  284. 284 $__sidebar = __DIR__ . '/sidebar.php';
  285. 285 if (is_file($__sidebar)) {
  286. 286 include $__sidebar;
  287. 287 }
  288. 288 ?>
  289. 289 </div>
  290. 290 <?php else: ?>
  291. 291 <div class="col-lg-10">
  292. 292 <?php if (false): ?>
  293. 293 <div class="card guest-welcome text-center">
  294. 294 <div class="btn-group" role="group" aria-label="<?php echo htmlspecialchars($lang['download_paste'] ?? 'Télécharger Paste', ENT_QUOTES, 'UTF-8'); ?>">
  295. 295 <a href="https://sourceforge.net/projects/phpaste/files/latest/download" class="btn btn-success">
  296. 296 <?php echo htmlspecialchars($lang['get_paste'] ?? 'Télécharger Paste', ENT_QUOTES, 'UTF-8'); ?> <?=$currentversion?>
  297. 297 </a>
  298. 298 <a href="https://github.com/boxlabss/PASTE" class="btn btn-dark">
  299. 299 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">
  300. 300 <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"></path>
  301. 301 </svg>
  302. 302 GitHub
  303. 303 </a>
  304. 304 </div>
  305. 305 </div>
  306. 306 <?php endif; ?>
  307. 307
  308. 308 <?php if (!isset($_SESSION['username']) && ($disableguest === "on")): ?>
  309. 309 <div class="card">
  310. 310 <div class="card-body">
  311. 311 <div class="alert alert-warning">
  312. 312 <?php echo htmlspecialchars($lang['login_required'] ?? 'Vous devez être connecté pour créer un paste.', ENT_QUOTES, 'UTF-8'); ?>
  313. 313 <a href="<?php echo htmlspecialchars($baseurl . 'login.php', ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-primary mt-2">
  314. 314 <?php echo htmlspecialchars($lang['login'] ?? 'Connexion', ENT_QUOTES, 'UTF-8'); ?>
  315. 315 </a>
  316. 316 </div>
  317. 317 </div>
  318. 318 </div>
  319. 319 <?php else: ?>
  320. 320 <div class="card">
  321. 321 <div class="card-header">
  322. 322 <h1><?php echo htmlspecialchars($lang['newpaste'] ?? 'Nouveau paste', ENT_QUOTES, 'UTF-8'); ?></h1>
  323. 323 <?php
  324. 324 // Quick diff
  325. 325 $diffQuickUrl = rtrim($baseurl ?? '/', '/') . '/diff.php?a=oldpaste&b=newpaste';
  326. 326 ?>
  327. 327 </div>
  328. 328
  329. 329 <div class="card-body">
  330. 330 <?php if (!empty($flash_error)): ?>
  331. 331 <div class="alert alert-danger"><?php echo htmlspecialchars($flash_error, ENT_QUOTES, 'UTF-8'); ?></div>
  332. 332 <?php elseif (isset($_GET['error'])): ?>
  333. 333 <div class="alert alert-warning"><?php echo htmlspecialchars($_GET['error'], ENT_QUOTES, 'UTF-8'); ?></div>
  334. 334 <?php elseif (isset($_GET['success'])): ?>
  335. 335 <div class="alert alert-success"><?php echo htmlspecialchars($_GET['success'], ENT_QUOTES, 'UTF-8'); ?></div>
  336. 336 <?php elseif (isset($error)): ?>
  337. 337 <div class="alert alert-warning"><?php echo htmlspecialchars($error, ENT_QUOTES, 'UTF-8'); ?></div>
  338. 338 <?php endif; ?>
  339. 339
  340. 340 <form class="form-horizontal" name="mainForm" id="mainForm" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="POST">
  341. 341 <div class="row mb-3 g-3">
  342. 342 <div class="col-sm-4">
  343. 343 <div class="input-group">
  344. 344 <span class="input-group-text"><i class="bi bi-fonts"></i></span>
  345. 345 <input type="text" class="form-control" name="title"
  346. 346 placeholder="<?php echo htmlspecialchars($lang['pastetitle'] ?? 'Titre du paste', ENT_QUOTES, 'UTF-8'); ?>">
  347. 347 </div>
  348. 348 </div>
  349. 349
  350. 350 <div class="col-sm-4">
  351. 351 <select class="form-select" name="format" id="format">
  352. 352 <?php
  353. 353 $geshiformats = $geshiformats ?? [];
  354. 354 $popular_formats = $popular_formats ?? [];
  355. 355
  356. 356 // Logique formulaire public
  357. 357 if (isset($_POST['format']) && $_POST['format'] !== '') {
  358. 358 $selectedCode = (string) $_POST['format'];
  359. 359 } elseif (!empty($paste_data) && !empty($p_code)) {
  360. 360 $selectedCode = (string) $p_code;
  361. 361 } else {
  362. 362 $selectedCode = 'text';
  363. 363 }
  364. 364
  365. 365 if ($selectedCode !== 'text' && $selectedCode !== 'autodetect' && !array_key_exists($selectedCode, $geshiformats)) {
  366. 366 $selectedCode = 'text';
  367. 367 }
  368. 368
  369. 369 $isSel = function ($code) use ($selectedCode) {
  370. 370 return ($selectedCode === $code) ? ' selected="selected"' : '';
  371. 371 };
  372. 372
  373. 373 echo '<option value="text"' . $isSel('text') . '>Plain Text</option>';
  374. 374 echo '<option value="autodetect"' . $isSel('autodetect') . '>Autodetect Language</option>';
  375. 375 echo '<option disabled="disabled">-------------------------------------</option>';
  376. 376
  377. 377 foreach ($geshiformats as $code => $name) {
  378. 378 if ($code === 'text' || $code === 'autodetect') continue;
  379. 379 if (in_array($code, $popular_formats, true)) {
  380. 380 echo '<option value="' . htmlspecialchars($code, ENT_QUOTES, 'UTF-8') . '"' . $isSel($code) . '>'
  381. 381 . htmlspecialchars($name, ENT_QUOTES, 'UTF-8')
  382. 382 . '</option>';
  383. 383 }
  384. 384 }
  385. 385
  386. 386 foreach ($geshiformats as $code => $name) {
  387. 387 if ($code === 'text' || $code === 'autodetect') continue;
  388. 388 if (!in_array($code, $popular_formats, true)) {
  389. 389 echo '<option value="' . htmlspecialchars($code, ENT_QUOTES, 'UTF-8') . '"' . $isSel($code) . '>'
  390. 390 . htmlspecialchars($name, ENT_QUOTES, 'UTF-8')
  391. 391 . '</option>';
  392. 392 }
  393. 393 }
  394. 394 ?>
  395. 395 </select>
  396. 396 </div>
  397. 397
  398. 398 <div class="col-sm-4 d-flex justify-content-end align-items-center gap-2">
  399. 399 <a class="btn btn-secondary btn-lx" href="<?php echo htmlspecialchars($diffQuickUrl, ENT_QUOTES, 'UTF-8'); ?>" title="<?php echo htmlspecialchars($lang['view_differences'] ?? 'Voir les différences', ENT_QUOTES, 'UTF-8'); ?>"><i class="bi bi-arrow-left-right"></i> .diff</a>
  400. 400
  401. 401 <button type="button" class="btn btn-outline-secondary" id="load_file_btn"
  402. 402 title="<?php echo htmlspecialchars($lang['load_file'] ?? 'Charger un fichier dans l’éditeur', ENT_QUOTES, 'UTF-8'); ?>">
  403. 403 <i class="bi bi-upload"></i> <?php echo htmlspecialchars($lang['load'] ?? 'Charger', ENT_QUOTES, 'UTF-8'); ?>
  404. 404 </button>
  405. 405
  406. 406 <button type="button" class="btn btn-outline-secondary" id="clear_file_btn"
  407. 407 title="<?php echo htmlspecialchars($lang['clear_editor'] ?? 'Vider l’éditeur', ENT_QUOTES, 'UTF-8'); ?>">
  408. 408 <i class="bi bi-x-circle"></i> <?php echo htmlspecialchars($lang['clear'] ?? 'Vider', ENT_QUOTES, 'UTF-8'); ?>
  409. 409 </button>
  410. 410
  411. 411 <input type="file" id="code_file" class="visually-hidden"
  412. 412 accept=".txt,.md,.php,.js,.ts,.jsx,.tsx,.py,.rb,.java,.c,.cpp,.h,.cs,.go,.rs,.kt,.swift,.sh,.ps1,.sql,.html,.htm,.css,.scss,.json,.xml,.yml,.yaml,.ini,.conf,text/*">
  413. 413 </div>
  414. 414 </div>
  415. 415
  416. 416 <div id="file-announce" class="visually-hidden" aria-live="polite"></div>
  417. 417
  418. 418 <div class="mb-3">
  419. 419 <textarea class="form-control" rows="15" id="edit-code" name="paste_data"
  420. 420 placeholder="<?php echo htmlspecialchars($lang['paste_content'] ?? 'Contenu du paste', ENT_QUOTES, 'UTF-8'); ?>"
  421. 421 data-max-bytes="<?php echo 1024 * 1024 * ($pastelimit ?? 10); ?>"><?php echo htmlspecialchars($paste_data ?? '', ENT_QUOTES, 'UTF-8'); ?></textarea>
  422. 422 </div>
  423. 423
  424. 424 <div class="row mb-3">
  425. 425 <label class="col-sm-2 col-form-label"><?php echo htmlspecialchars($lang['expiration'] ?? 'Expiration', ENT_QUOTES, 'UTF-8'); ?></label>
  426. 426 <div class="col-sm-10">
  427. 427 <select class="form-select" name="paste_expire_date">
  428. 428 <option value="N" <?php echo ($paste_expire_date ?? 'N') == "N" ? 'selected' : ''; ?>>Jamais</option>
  429. 429 <option value="self" <?php echo ($paste_expire_date ?? 'N') == "self" ? 'selected' : ''; ?>>Voir 1 fois</option>
  430. 430 <option value="10M" <?php echo ($paste_expire_date ?? 'N') == "10M" ? 'selected' : ''; ?>>10 minutes</option>
  431. 431 <option value="1H" <?php echo ($paste_expire_date ?? 'N') == "1H" ? 'selected' : ''; ?>>1 heure</option>
  432. 432 <option value="1D" <?php echo ($paste_expire_date ?? 'N') == "1D" ? 'selected' : ''; ?>>1 jour</option>
  433. 433 <option value="1W" <?php echo ($paste_expire_date ?? 'N') == "1W" ? 'selected' : ''; ?>>1 semaine</option>
  434. 434 <option value="2W" <?php echo ($paste_expire_date ?? 'N') == "2W" ? 'selected' : ''; ?>>2 semaines</option>
  435. 435 <option value="1M" <?php echo ($paste_expire_date ?? 'N') == "1M" ? 'selected' : ''; ?>>1 mois</option>
  436. 436 </select>
  437. 437 </div>
  438. 438 </div>
  439. 439
  440. 440 <div class="row mb-3">
  441. 441 <label class="col-sm-2 col-form-label"><?php echo htmlspecialchars($lang['visibility'] ?? 'Visibilité', ENT_QUOTES, 'UTF-8'); ?></label>
  442. 442 <div class="col-sm-10">
  443. 443 <select class="form-select" name="visibility">
  444. 444 <option value="0" <?php echo ($p_visible ?? '1') == "0" ? 'selected' : ''; ?>>
  445. 445 <?php echo htmlspecialchars($lang['public'] ?? 'Public', ENT_QUOTES, 'UTF-8'); ?>
  446. 446 </option>
  447. 447 <option value="1" <?php echo ($p_visible ?? '1') == "1" ? 'selected' : ''; ?>>
  448. 448 <?php echo htmlspecialchars($lang['unlisted'] ?? 'Non listé', ENT_QUOTES, 'UTF-8'); ?>
  449. 449 </option>
  450. 450 <option value="2" <?php echo ($p_visible ?? '1') == "2" ? 'selected' : ''; ?>>
  451. 451 <?php echo htmlspecialchars($lang['private'] ?? 'Privé', ENT_QUOTES, 'UTF-8'); ?>
  452. 452 </option>
  453. 453 </select>
  454. 454 </div>
  455. 455 </div>
  456. 456
  457. 457 <div class="mb-3">
  458. 458 <div class="input-group">
  459. 459 <span class="input-group-text"><i class="bi bi-lock"></i></span>
  460. 460 <input type="text" class="form-control" name="pass" id="pass"
  461. 461 placeholder="<?php echo htmlspecialchars($lang['pwopt'] ?? 'Mot de passe (optionnel)', ENT_QUOTES, 'UTF-8'); ?>">
  462. 462 </div>
  463. 463 </div>
  464. 464
  465. 465 <div class="mb-3 form-check d-none" aria-hidden="true">
  466. 466 <input type="checkbox" class="form-check-input" id="client_encrypt" name="client_encrypt" value="0" disabled>
  467. 467 <label class="form-check-label" for="client_encrypt">
  468. 468 <?php echo htmlspecialchars($lang['client_encrypt_label'] ?? 'Activer le chiffrement côté client (AES-256-GCM)', ENT_QUOTES, 'UTF-8'); ?>
  469. 469 </label>
  470. 470 </div>
  471. 471
  472. 472 <input type="hidden" name="is_client_encrypted" id="is_client_encrypted" value="0">
  473. 473
  474. 474 <div class="modal fade d-none" id="encryptPassModal" tabindex="-1" aria-labelledby="encryptPassLabel" aria-hidden="true">
  475. 475 <div class="modal-dialog">
  476. 476 <div class="modal-content">
  477. 477 <div class="modal-header">
  478. 478 <h5 class="modal-title" id="encryptPassLabel">
  479. 479 <?php echo htmlspecialchars($lang['encrypt_modal_title'] ?? 'Définir la phrase de chiffrement', ENT_QUOTES, 'UTF-8'); ?>
  480. 480 </h5>
  481. 481 <button type="button" class="btn-close" data-bs-dismiss="modal"
  482. 482 aria-label="<?php echo htmlspecialchars($lang['close'] ?? 'Fermer', ENT_QUOTES, 'UTF-8'); ?>"></button>
  483. 483 </div>
  484. 484
  485. 485 <div class="modal-body">
  486. 486 <p><?php echo htmlspecialchars($lang['encrypt_modal_help'] ?? 'Saisissez une phrase secrète robuste (et gardez-la précieusement) :', ENT_QUOTES, 'UTF-8'); ?></p>
  487. 487
  488. 488 <div class="input-group mb-3">
  489. 489 <input type="password" class="form-control" id="encryptPassInput" autocomplete="new-password"
  490. 490 placeholder="<?php echo htmlspecialchars($lang['encrypt_pass_placeholder'] ?? 'Entrez la phrase secrète', ENT_QUOTES, 'UTF-8'); ?>">
  491. 491 <button type="button" class="btn btn-outline-secondary" id="toggleEncryptPass"
  492. 492 title="<?php echo htmlspecialchars($lang['show_hide_password'] ?? 'Afficher / masquer', ENT_QUOTES, 'UTF-8'); ?>">
  493. 493 <i class="bi bi-eye" id="encryptPassIcon"></i>
  494. 494 </button>
  495. 495 </div>
  496. 496
  497. 497 <div class="mt-2">
  498. 498 <div class="progress" style="--height: 5px;">
  499. 499 <div id="passStrengthBar" class="progress-bar" role="progressbar" style="width: 0%;"></div>
  500. 500 </div>
  501. 501 <small id="passStrengthText" class="text-muted">
  502. 502 <?php echo htmlspecialchars($lang['strength_weak'] ?? 'Force : faible', ENT_QUOTES, 'UTF-8'); ?>
  503. 503 </small>
  504. 504 </div>
  505. 505
  506. 506 <small class="text-muted d-block mt-1">
  507. 507 <?php echo htmlspecialchars($lang['encrypt_rules'] ?? '12 caractères minimum ; mélangez majuscules/minuscules, chiffres et symboles.', ENT_QUOTES, 'UTF-8'); ?>
  508. 508 </small>
  509. 509 <span class="ms-2">Besoin d'aide ?</span>
  510. 510 <a href="https://paste.lesalkodiques.info/generatepasswd.php" target="_blank" rel="noopener noreferrer" class="text-decoration-none">Générer une phrase solide</a>
  511. 511 </div>
  512. 512
  513. 513 <div class="modal-footer">
  514. 514 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
  515. 515 <?php echo htmlspecialchars($lang['cancel'] ?? 'Annuler', ENT_QUOTES, 'UTF-8'); ?>
  516. 516 </button>
  517. 517 <button type="button" class="btn btn-primary" id="encryptConfirm" disabled>
  518. 518 <?php echo htmlspecialchars($lang['encrypt_btn'] ?? 'Chiffrer', ENT_QUOTES, 'UTF-8'); ?>
  519. 519 </button>
  520. 520 </div>
  521. 521 </div>
  522. 522 </div>
  523. 523 </div>
  524. 524
  525. 525 <div class="row mb-3">
  526. 526 <p class="text-muted"><small><?php echo htmlspecialchars($lang['encrypt'] ?? 'Chiffrement', ENT_QUOTES, 'UTF-8'); ?></small></p>
  527. 527 </div>
  528. 528
  529. 529 <?php
  530. 530 // Debug CAPTCHA condition (console serveur uniquement)
  531. 531 $captcha_condition = $cap_e == "on" && !isset($_SESSION['username']) && (!isset($disableguest) || $disableguest !== "on");
  532. 532 error_log("main.php: Condition CAPTCHA : " . ($captcha_condition ? 'vrai' : 'faux'));
  533. 533 if ($captcha_condition): ?>
  534. 534 <?php if ($captcha_mode === "recaptcha"): ?>
  535. 535 <div class="g-recaptcha mb-3" data-theme="dark"
  536. 536 data-sitekey="<?php echo htmlspecialchars($main_sitekey, ENT_QUOTES, 'UTF-8'); ?>"
  537. 537 data-callback="onRecaptchaSuccess"></div>
  538. 538 <input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">
  539. 539 <?php elseif ($captcha_mode === "recaptcha_v3"): ?>
  540. 540 <input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">
  541. 541 <?php elseif ($captcha_mode === "turnstile"): ?>
  542. 542 <div class="cf-turnstile mb-3"
  543. 543 data-sitekey="<?php echo htmlspecialchars($main_sitekey, ENT_QUOTES, 'UTF-8'); ?>"
  544. 544 data-callback="onTurnstileSuccess"
  545. 545 data-action="create_paste"
  546. 546 data-appearance="execute"
  547. 547 data-retry-interval="1000"></div>
  548. 548 <input type="hidden" name="cf-turnstile-response" id="cf-turnstile-response">
  549. 549 <?php else: ?>
  550. 550 <?php include __DIR__ . '/captcha_bootstrap.php'; ?>
  551. 551 <?php endif; ?>
  552. 552 <?php endif; ?>
  553. 553
  554. 554 <div class="row mb-3">
  555. 555 <div class="d-grid gap-2">
  556. 556 <input class="btn btn-primary paste-button" type="submit" id="submit" data-recaptcha-action="create_paste"
  557. 557 value="<?php echo htmlspecialchars($lang['createpaste'] ?? 'Créer le paste', ENT_QUOTES, 'UTF-8'); ?>">
  558. 558 </div>
  559. 559 </div>
  560. 560
  561. 561 </form>
  562. 562 </div>
  563. 563 </div>
  564. 564 <?php endif; ?>
  565. 565 </div>
  566. 566
  567. 567 <div class="col-lg-2 mt-4 mt-lg-0">
  568. 568 <?php
  569. 569 $__sidebar = __DIR__ . '/sidebar.php';
  570. 570 if (is_file($__sidebar)) {
  571. 571 include $__sidebar;
  572. 572 }
  573. 573 ?>
  574. 574 </div>
  575. 575 <?php endif; ?>
  576. 576 </div>
  577. 577</div>
  578. 578
  579. 579
  580. 580<script nonce="<?php echo htmlspecialchars($nonce, ENT_QUOTES, 'UTF-8'); ?>">
  581. 581 // Chiffrement côté client temporairement désactivé (le temps de ré-implanter proprement).
  582. 582 document.addEventListener('DOMContentLoaded', function() {
  583. 583 var cb = document.getElementById('client_encrypt');
  584. 584 var hid = document.getElementById('is_client_encrypted');
  585. 585 if (cb) {
  586. 586 cb.checked = false;
  587. 587 cb.disabled = true;
  588. 588 }
  589. 589 if (hid) {
  590. 590 hid.value = '0';
  591. 591 }
  592. 592 });
  593. 593</script>
Commentaires 0
Connectez-vous pour publier un commentaire.
  • Aucun commentaire pour l’instant. Soyez le premier.
Connectez-vous pour publier un commentaire. Connexion ou inscription