@geekity/cms 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. package/README.md +2091 -214
  2. package/admin/components/fields.njk +165 -0
  3. package/admin/layouts/base.njk +1 -1
  4. package/admin/layouts/settings-page.njk +26 -0
  5. package/admin/layouts/shell.njk +17 -3
  6. package/admin/pages/account/forgot.njk +47 -0
  7. package/admin/pages/account/login.njk +26 -0
  8. package/admin/pages/account/reset.njk +38 -0
  9. package/admin/pages/account/setup.njk +28 -0
  10. package/admin/pages/appearance/themes.njk +69 -0
  11. package/admin/pages/comments/all.njk +133 -0
  12. package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
  13. package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
  14. package/admin/pages/documents/editor.njk +196 -0
  15. package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
  16. package/admin/pages/documents/taxonomy.njk +95 -0
  17. package/admin/pages/federation/followers.njk +238 -0
  18. package/admin/pages/media/library.njk +160 -0
  19. package/admin/pages/messages/all.njk +110 -0
  20. package/admin/{layouts → pages}/placeholder.njk +5 -1
  21. package/admin/pages/settings/discussion.njk +99 -0
  22. package/admin/pages/settings/email.njk +203 -0
  23. package/admin/pages/settings/federation.njk +75 -0
  24. package/admin/pages/settings/general.njk +29 -0
  25. package/admin/pages/settings/permalinks.njk +50 -0
  26. package/admin/pages/settings/reading.njk +72 -0
  27. package/admin/pages/users/edit.njk +239 -0
  28. package/admin/pages/users/list.njk +48 -0
  29. package/admin/pages/users/new.njk +41 -0
  30. package/admin/static/admin.css +498 -3
  31. package/admin/static/copy.js +52 -0
  32. package/admin/static/editor.js +16 -16
  33. package/admin/static/slug.js +61 -0
  34. package/dist/admin/accounts.d.ts +413 -0
  35. package/dist/admin/accounts.d.ts.map +1 -0
  36. package/dist/admin/accounts.js +680 -0
  37. package/dist/admin/accounts.js.map +1 -0
  38. package/dist/admin/appearance.d.ts +80 -0
  39. package/dist/admin/appearance.d.ts.map +1 -0
  40. package/dist/admin/appearance.js +136 -0
  41. package/dist/admin/appearance.js.map +1 -0
  42. package/dist/admin/comments.d.ts +90 -0
  43. package/dist/admin/comments.d.ts.map +1 -0
  44. package/dist/admin/comments.js +244 -0
  45. package/dist/admin/comments.js.map +1 -0
  46. package/dist/admin/credentials.d.ts +26 -2
  47. package/dist/admin/credentials.d.ts.map +1 -1
  48. package/dist/admin/credentials.js +35 -2
  49. package/dist/admin/credentials.js.map +1 -1
  50. package/dist/admin/documents.d.ts +127 -10
  51. package/dist/admin/documents.d.ts.map +1 -1
  52. package/dist/admin/documents.js +360 -41
  53. package/dist/admin/documents.js.map +1 -1
  54. package/dist/admin/federation.d.ts +151 -50
  55. package/dist/admin/federation.d.ts.map +1 -1
  56. package/dist/admin/federation.js +225 -93
  57. package/dist/admin/federation.js.map +1 -1
  58. package/dist/admin/formatting.d.ts +20 -0
  59. package/dist/admin/formatting.d.ts.map +1 -0
  60. package/dist/admin/formatting.js +72 -0
  61. package/dist/admin/formatting.js.map +1 -0
  62. package/dist/admin/headers.d.ts +65 -0
  63. package/dist/admin/headers.d.ts.map +1 -0
  64. package/dist/admin/headers.js +104 -0
  65. package/dist/admin/headers.js.map +1 -0
  66. package/dist/admin/index.d.ts +38 -12
  67. package/dist/admin/index.d.ts.map +1 -1
  68. package/dist/admin/index.js +25 -7
  69. package/dist/admin/index.js.map +1 -1
  70. package/dist/admin/media.d.ts +168 -0
  71. package/dist/admin/media.d.ts.map +1 -0
  72. package/dist/admin/media.js +295 -0
  73. package/dist/admin/media.js.map +1 -0
  74. package/dist/admin/menu.d.ts +79 -0
  75. package/dist/admin/menu.d.ts.map +1 -0
  76. package/dist/admin/menu.js +126 -0
  77. package/dist/admin/menu.js.map +1 -0
  78. package/dist/admin/messages.d.ts +80 -0
  79. package/dist/admin/messages.d.ts.map +1 -0
  80. package/dist/admin/messages.js +152 -0
  81. package/dist/admin/messages.js.map +1 -0
  82. package/dist/admin/preview.d.ts.map +1 -1
  83. package/dist/admin/preview.js +31 -7
  84. package/dist/admin/preview.js.map +1 -1
  85. package/dist/admin/recovery.d.ts +92 -0
  86. package/dist/admin/recovery.d.ts.map +1 -0
  87. package/dist/admin/recovery.js +229 -0
  88. package/dist/admin/recovery.js.map +1 -0
  89. package/dist/admin/routes.d.ts +0 -20
  90. package/dist/admin/routes.d.ts.map +1 -1
  91. package/dist/admin/routes.js +155 -105
  92. package/dist/admin/routes.js.map +1 -1
  93. package/dist/admin/settings-discussion.d.ts +37 -0
  94. package/dist/admin/settings-discussion.d.ts.map +1 -0
  95. package/dist/admin/settings-discussion.js +117 -0
  96. package/dist/admin/settings-discussion.js.map +1 -0
  97. package/dist/admin/settings-email.d.ts +54 -0
  98. package/dist/admin/settings-email.d.ts.map +1 -0
  99. package/dist/admin/settings-email.js +189 -0
  100. package/dist/admin/settings-email.js.map +1 -0
  101. package/dist/admin/settings-federation.d.ts +39 -0
  102. package/dist/admin/settings-federation.d.ts.map +1 -0
  103. package/dist/admin/settings-federation.js +103 -0
  104. package/dist/admin/settings-federation.js.map +1 -0
  105. package/dist/admin/settings-general.d.ts +12 -0
  106. package/dist/admin/settings-general.d.ts.map +1 -0
  107. package/dist/admin/settings-general.js +48 -0
  108. package/dist/admin/settings-general.js.map +1 -0
  109. package/dist/admin/settings-page.d.ts +102 -0
  110. package/dist/admin/settings-page.d.ts.map +1 -0
  111. package/dist/admin/settings-page.js +126 -0
  112. package/dist/admin/settings-page.js.map +1 -0
  113. package/dist/admin/settings-pages.d.ts +19 -0
  114. package/dist/admin/settings-pages.d.ts.map +1 -0
  115. package/dist/admin/settings-pages.js +33 -0
  116. package/dist/admin/settings-pages.js.map +1 -0
  117. package/dist/admin/settings-permalinks.d.ts +16 -0
  118. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  119. package/dist/admin/settings-permalinks.js +32 -0
  120. package/dist/admin/settings-permalinks.js.map +1 -0
  121. package/dist/admin/settings-reading.d.ts +33 -0
  122. package/dist/admin/settings-reading.d.ts.map +1 -0
  123. package/dist/admin/settings-reading.js +48 -0
  124. package/dist/admin/settings-reading.js.map +1 -0
  125. package/dist/admin/settings.d.ts +325 -96
  126. package/dist/admin/settings.d.ts.map +1 -1
  127. package/dist/admin/settings.js +650 -308
  128. package/dist/admin/settings.js.map +1 -1
  129. package/dist/admin/store.d.ts +606 -152
  130. package/dist/admin/store.d.ts.map +1 -1
  131. package/dist/admin/store.js +863 -268
  132. package/dist/admin/store.js.map +1 -1
  133. package/dist/admin/taxonomy.d.ts +114 -0
  134. package/dist/admin/taxonomy.d.ts.map +1 -0
  135. package/dist/admin/taxonomy.js +289 -0
  136. package/dist/admin/taxonomy.js.map +1 -0
  137. package/dist/admin/templates.d.ts +44 -14
  138. package/dist/admin/templates.d.ts.map +1 -1
  139. package/dist/admin/templates.js +44 -14
  140. package/dist/admin/templates.js.map +1 -1
  141. package/dist/admin/throttle.d.ts +84 -0
  142. package/dist/admin/throttle.d.ts.map +1 -0
  143. package/dist/admin/throttle.js +143 -0
  144. package/dist/admin/throttle.js.map +1 -0
  145. package/dist/admin/uploads.d.ts +28 -2
  146. package/dist/admin/uploads.d.ts.map +1 -1
  147. package/dist/admin/uploads.js +43 -4
  148. package/dist/admin/uploads.js.map +1 -1
  149. package/dist/admin/users.d.ts +100 -13
  150. package/dist/admin/users.d.ts.map +1 -1
  151. package/dist/admin/users.js +412 -39
  152. package/dist/admin/users.js.map +1 -1
  153. package/dist/cache.d.ts +141 -0
  154. package/dist/cache.d.ts.map +1 -0
  155. package/dist/cache.js +207 -0
  156. package/dist/cache.js.map +1 -0
  157. package/dist/cli.d.ts +14 -2
  158. package/dist/cli.d.ts.map +1 -1
  159. package/dist/cli.js +424 -21
  160. package/dist/cli.js.map +1 -1
  161. package/dist/comments/akismet.d.ts +130 -0
  162. package/dist/comments/akismet.d.ts.map +1 -0
  163. package/dist/comments/akismet.js +274 -0
  164. package/dist/comments/akismet.js.map +1 -0
  165. package/dist/comments/conversation.d.ts +29 -0
  166. package/dist/comments/conversation.d.ts.map +1 -0
  167. package/dist/comments/conversation.js +60 -0
  168. package/dist/comments/conversation.js.map +1 -0
  169. package/dist/comments/form.d.ts +75 -0
  170. package/dist/comments/form.d.ts.map +1 -0
  171. package/dist/comments/form.js +64 -0
  172. package/dist/comments/form.js.map +1 -0
  173. package/dist/comments/index.d.ts +15 -0
  174. package/dist/comments/index.d.ts.map +1 -0
  175. package/dist/comments/index.js +9 -0
  176. package/dist/comments/index.js.map +1 -0
  177. package/dist/comments/markdown.d.ts +8 -0
  178. package/dist/comments/markdown.d.ts.map +1 -0
  179. package/dist/comments/markdown.js +85 -0
  180. package/dist/comments/markdown.js.map +1 -0
  181. package/dist/comments/moderate.d.ts +71 -0
  182. package/dist/comments/moderate.d.ts.map +1 -0
  183. package/dist/comments/moderate.js +88 -0
  184. package/dist/comments/moderate.js.map +1 -0
  185. package/dist/comments/policy.d.ts +57 -0
  186. package/dist/comments/policy.d.ts.map +1 -0
  187. package/dist/comments/policy.js +80 -0
  188. package/dist/comments/policy.js.map +1 -0
  189. package/dist/comments/records.d.ts +266 -0
  190. package/dist/comments/records.d.ts.map +1 -0
  191. package/dist/comments/records.js +487 -0
  192. package/dist/comments/records.js.map +1 -0
  193. package/dist/comments/routes.d.ts +58 -0
  194. package/dist/comments/routes.d.ts.map +1 -0
  195. package/dist/comments/routes.js +177 -0
  196. package/dist/comments/routes.js.map +1 -0
  197. package/dist/comments/submission.d.ts +263 -0
  198. package/dist/comments/submission.d.ts.map +1 -0
  199. package/dist/comments/submission.js +241 -0
  200. package/dist/comments/submission.js.map +1 -0
  201. package/dist/config.d.ts +190 -5
  202. package/dist/config.d.ts.map +1 -1
  203. package/dist/config.js +118 -6
  204. package/dist/config.js.map +1 -1
  205. package/dist/contact/delivery.d.ts +60 -0
  206. package/dist/contact/delivery.d.ts.map +1 -0
  207. package/dist/contact/delivery.js +87 -0
  208. package/dist/contact/delivery.js.map +1 -0
  209. package/dist/contact/form.d.ts +130 -0
  210. package/dist/contact/form.d.ts.map +1 -0
  211. package/dist/contact/form.js +163 -0
  212. package/dist/contact/form.js.map +1 -0
  213. package/dist/contact/index.d.ts +17 -0
  214. package/dist/contact/index.d.ts.map +1 -0
  215. package/dist/contact/index.js +13 -0
  216. package/dist/contact/index.js.map +1 -0
  217. package/dist/contact/records.d.ts +124 -0
  218. package/dist/contact/records.d.ts.map +1 -0
  219. package/dist/contact/records.js +218 -0
  220. package/dist/contact/records.js.map +1 -0
  221. package/dist/contact/routes.d.ts +17 -0
  222. package/dist/contact/routes.d.ts.map +1 -0
  223. package/dist/contact/routes.js +127 -0
  224. package/dist/contact/routes.js.map +1 -0
  225. package/dist/contact/submission.d.ts +103 -0
  226. package/dist/contact/submission.d.ts.map +1 -0
  227. package/dist/contact/submission.js +166 -0
  228. package/dist/contact/submission.js.map +1 -0
  229. package/dist/content/document.d.ts +7 -2
  230. package/dist/content/document.d.ts.map +1 -1
  231. package/dist/content/document.js +1 -0
  232. package/dist/content/document.js.map +1 -1
  233. package/dist/content/index.d.ts +7 -2
  234. package/dist/content/index.d.ts.map +1 -1
  235. package/dist/content/index.js +4 -1
  236. package/dist/content/index.js.map +1 -1
  237. package/dist/content/markdown.d.ts.map +1 -1
  238. package/dist/content/markdown.js +24 -2
  239. package/dist/content/markdown.js.map +1 -1
  240. package/dist/content/parser.d.ts.map +1 -1
  241. package/dist/content/parser.js +11 -4
  242. package/dist/content/parser.js.map +1 -1
  243. package/dist/content/save.d.ts +5 -0
  244. package/dist/content/save.d.ts.map +1 -1
  245. package/dist/content/save.js +44 -1
  246. package/dist/content/save.js.map +1 -1
  247. package/dist/content/schedule.d.ts +125 -0
  248. package/dist/content/schedule.d.ts.map +1 -0
  249. package/dist/content/schedule.js +207 -0
  250. package/dist/content/schedule.js.map +1 -0
  251. package/dist/content/search.d.ts +64 -0
  252. package/dist/content/search.d.ts.map +1 -0
  253. package/dist/content/search.js +136 -0
  254. package/dist/content/search.js.map +1 -0
  255. package/dist/content/store.d.ts +202 -7
  256. package/dist/content/store.d.ts.map +1 -1
  257. package/dist/content/store.js +374 -67
  258. package/dist/content/store.js.map +1 -1
  259. package/dist/content/sync.d.ts +7 -1
  260. package/dist/content/sync.d.ts.map +1 -1
  261. package/dist/content/sync.js +18 -10
  262. package/dist/content/sync.js.map +1 -1
  263. package/dist/content/time.d.ts +56 -0
  264. package/dist/content/time.d.ts.map +1 -0
  265. package/dist/content/time.js +141 -0
  266. package/dist/content/time.js.map +1 -0
  267. package/dist/content/writer.d.ts.map +1 -1
  268. package/dist/content/writer.js +3 -0
  269. package/dist/content/writer.js.map +1 -1
  270. package/dist/env.d.ts +58 -4
  271. package/dist/env.d.ts.map +1 -1
  272. package/dist/federation/actor.d.ts +95 -41
  273. package/dist/federation/actor.d.ts.map +1 -1
  274. package/dist/federation/actor.js +180 -53
  275. package/dist/federation/actor.js.map +1 -1
  276. package/dist/federation/article.d.ts +44 -17
  277. package/dist/federation/article.d.ts.map +1 -1
  278. package/dist/federation/article.js +98 -46
  279. package/dist/federation/article.js.map +1 -1
  280. package/dist/federation/delivery.d.ts +63 -15
  281. package/dist/federation/delivery.d.ts.map +1 -1
  282. package/dist/federation/delivery.js +154 -80
  283. package/dist/federation/delivery.js.map +1 -1
  284. package/dist/federation/federation.d.ts +22 -17
  285. package/dist/federation/federation.d.ts.map +1 -1
  286. package/dist/federation/federation.js +98 -77
  287. package/dist/federation/federation.js.map +1 -1
  288. package/dist/federation/followers.d.ts +3 -2
  289. package/dist/federation/followers.d.ts.map +1 -1
  290. package/dist/federation/followers.js +6 -5
  291. package/dist/federation/followers.js.map +1 -1
  292. package/dist/federation/import-wordpress.d.ts +128 -0
  293. package/dist/federation/import-wordpress.d.ts.map +1 -0
  294. package/dist/federation/import-wordpress.js +426 -0
  295. package/dist/federation/import-wordpress.js.map +1 -0
  296. package/dist/federation/inbox.d.ts +36 -13
  297. package/dist/federation/inbox.d.ts.map +1 -1
  298. package/dist/federation/inbox.js +120 -49
  299. package/dist/federation/inbox.js.map +1 -1
  300. package/dist/federation/index.d.ts +22 -10
  301. package/dist/federation/index.d.ts.map +1 -1
  302. package/dist/federation/index.js +13 -8
  303. package/dist/federation/index.js.map +1 -1
  304. package/dist/federation/keys.d.ts +98 -20
  305. package/dist/federation/keys.d.ts.map +1 -1
  306. package/dist/federation/keys.js +269 -39
  307. package/dist/federation/keys.js.map +1 -1
  308. package/dist/federation/mount.d.ts +42 -10
  309. package/dist/federation/mount.d.ts.map +1 -1
  310. package/dist/federation/mount.js +266 -26
  311. package/dist/federation/mount.js.map +1 -1
  312. package/dist/federation/paths.d.ts +23 -35
  313. package/dist/federation/paths.d.ts.map +1 -1
  314. package/dist/federation/paths.js +26 -39
  315. package/dist/federation/paths.js.map +1 -1
  316. package/dist/federation/records.d.ts +223 -0
  317. package/dist/federation/records.d.ts.map +1 -0
  318. package/dist/federation/records.js +506 -0
  319. package/dist/federation/records.js.map +1 -0
  320. package/dist/federation/relays.d.ts +114 -0
  321. package/dist/federation/relays.d.ts.map +1 -0
  322. package/dist/federation/relays.js +290 -0
  323. package/dist/federation/relays.js.map +1 -0
  324. package/dist/federation/replies.d.ts +80 -0
  325. package/dist/federation/replies.d.ts.map +1 -0
  326. package/dist/federation/replies.js +166 -0
  327. package/dist/federation/replies.js.map +1 -0
  328. package/dist/federation/wordpress.d.ts +131 -0
  329. package/dist/federation/wordpress.d.ts.map +1 -0
  330. package/dist/federation/wordpress.js +341 -0
  331. package/dist/federation/wordpress.js.map +1 -0
  332. package/dist/files/atomic.d.ts +103 -0
  333. package/dist/files/atomic.d.ts.map +1 -0
  334. package/dist/files/atomic.js +150 -0
  335. package/dist/files/atomic.js.map +1 -0
  336. package/dist/files/index.d.ts +3 -0
  337. package/dist/files/index.d.ts.map +1 -0
  338. package/dist/files/index.js +2 -0
  339. package/dist/files/index.js.map +1 -0
  340. package/dist/forms/protection.d.ts +85 -0
  341. package/dist/forms/protection.d.ts.map +1 -0
  342. package/dist/forms/protection.js +116 -0
  343. package/dist/forms/protection.js.map +1 -0
  344. package/dist/images/icons.d.ts +59 -0
  345. package/dist/images/icons.d.ts.map +1 -0
  346. package/dist/images/icons.js +131 -0
  347. package/dist/images/icons.js.map +1 -0
  348. package/dist/images/index.d.ts +7 -0
  349. package/dist/images/index.d.ts.map +1 -0
  350. package/dist/images/index.js +4 -0
  351. package/dist/images/index.js.map +1 -0
  352. package/dist/images/markup.d.ts +47 -0
  353. package/dist/images/markup.d.ts.map +1 -0
  354. package/dist/images/markup.js +175 -0
  355. package/dist/images/markup.js.map +1 -0
  356. package/dist/images/paths.d.ts +34 -0
  357. package/dist/images/paths.d.ts.map +1 -0
  358. package/dist/images/paths.js +41 -0
  359. package/dist/images/paths.js.map +1 -0
  360. package/dist/images/variants.d.ts +104 -0
  361. package/dist/images/variants.d.ts.map +1 -0
  362. package/dist/images/variants.js +320 -0
  363. package/dist/images/variants.js.map +1 -0
  364. package/dist/index.d.ts +123 -19
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +327 -25
  367. package/dist/index.js.map +1 -1
  368. package/dist/init.d.ts +18 -0
  369. package/dist/init.d.ts.map +1 -1
  370. package/dist/init.js +34 -3
  371. package/dist/init.js.map +1 -1
  372. package/dist/mail/brevo.d.ts +35 -0
  373. package/dist/mail/brevo.d.ts.map +1 -0
  374. package/dist/mail/brevo.js +85 -0
  375. package/dist/mail/brevo.js.map +1 -0
  376. package/dist/mail/credentials.d.ts +62 -0
  377. package/dist/mail/credentials.d.ts.map +1 -0
  378. package/dist/mail/credentials.js +86 -0
  379. package/dist/mail/credentials.js.map +1 -0
  380. package/dist/mail/index.d.ts +15 -0
  381. package/dist/mail/index.d.ts.map +1 -0
  382. package/dist/mail/index.js +8 -0
  383. package/dist/mail/index.js.map +1 -0
  384. package/dist/mail/memory.d.ts +35 -0
  385. package/dist/mail/memory.d.ts.map +1 -0
  386. package/dist/mail/memory.js +29 -0
  387. package/dist/mail/memory.js.map +1 -0
  388. package/dist/mail/provider.d.ts +80 -0
  389. package/dist/mail/provider.d.ts.map +1 -0
  390. package/dist/mail/provider.js +23 -0
  391. package/dist/mail/provider.js.map +1 -0
  392. package/dist/mail/service.d.ts +156 -0
  393. package/dist/mail/service.d.ts.map +1 -0
  394. package/dist/mail/service.js +265 -0
  395. package/dist/mail/service.js.map +1 -0
  396. package/dist/mail/smtp.d.ts +39 -0
  397. package/dist/mail/smtp.d.ts.map +1 -0
  398. package/dist/mail/smtp.js +58 -0
  399. package/dist/mail/smtp.js.map +1 -0
  400. package/dist/mail/templates.d.ts +91 -0
  401. package/dist/mail/templates.d.ts.map +1 -0
  402. package/dist/mail/templates.js +69 -0
  403. package/dist/mail/templates.js.map +1 -0
  404. package/dist/notifications/comments.d.ts +66 -0
  405. package/dist/notifications/comments.d.ts.map +1 -0
  406. package/dist/notifications/comments.js +151 -0
  407. package/dist/notifications/comments.js.map +1 -0
  408. package/dist/notifications/digest.d.ts +135 -0
  409. package/dist/notifications/digest.d.ts.map +1 -0
  410. package/dist/notifications/digest.js +287 -0
  411. package/dist/notifications/digest.js.map +1 -0
  412. package/dist/notifications/index.d.ts +13 -0
  413. package/dist/notifications/index.d.ts.map +1 -0
  414. package/dist/notifications/index.js +8 -0
  415. package/dist/notifications/index.js.map +1 -0
  416. package/dist/notifications/links.d.ts +60 -0
  417. package/dist/notifications/links.d.ts.map +1 -0
  418. package/dist/notifications/links.js +63 -0
  419. package/dist/notifications/links.js.map +1 -0
  420. package/dist/notifications/optouts.d.ts +48 -0
  421. package/dist/notifications/optouts.d.ts.map +1 -0
  422. package/dist/notifications/optouts.js +93 -0
  423. package/dist/notifications/optouts.js.map +1 -0
  424. package/dist/notifications/preferences.d.ts +158 -0
  425. package/dist/notifications/preferences.d.ts.map +1 -0
  426. package/dist/notifications/preferences.js +195 -0
  427. package/dist/notifications/preferences.js.map +1 -0
  428. package/dist/notifications/routes.d.ts +28 -0
  429. package/dist/notifications/routes.d.ts.map +1 -0
  430. package/dist/notifications/routes.js +184 -0
  431. package/dist/notifications/routes.js.map +1 -0
  432. package/dist/notifications/tokens.d.ts +60 -0
  433. package/dist/notifications/tokens.d.ts.map +1 -0
  434. package/dist/notifications/tokens.js +125 -0
  435. package/dist/notifications/tokens.js.map +1 -0
  436. package/dist/notify.d.ts +84 -0
  437. package/dist/notify.d.ts.map +1 -0
  438. package/dist/notify.js +149 -0
  439. package/dist/notify.js.map +1 -0
  440. package/dist/web/archive.d.ts +49 -0
  441. package/dist/web/archive.d.ts.map +1 -0
  442. package/dist/web/archive.js +59 -0
  443. package/dist/web/archive.js.map +1 -0
  444. package/dist/web/assets.d.ts +6 -5
  445. package/dist/web/assets.d.ts.map +1 -1
  446. package/dist/web/assets.js +5 -7
  447. package/dist/web/assets.js.map +1 -1
  448. package/dist/web/authors.d.ts +143 -0
  449. package/dist/web/authors.d.ts.map +1 -0
  450. package/dist/web/authors.js +178 -0
  451. package/dist/web/authors.js.map +1 -0
  452. package/dist/web/comments.d.ts +60 -0
  453. package/dist/web/comments.d.ts.map +1 -0
  454. package/dist/web/comments.js +207 -0
  455. package/dist/web/comments.js.map +1 -0
  456. package/dist/web/context.d.ts +162 -28
  457. package/dist/web/context.d.ts.map +1 -1
  458. package/dist/web/context.js +123 -26
  459. package/dist/web/context.js.map +1 -1
  460. package/dist/web/conversation.d.ts +209 -0
  461. package/dist/web/conversation.d.ts.map +1 -0
  462. package/dist/web/conversation.js +557 -0
  463. package/dist/web/conversation.js.map +1 -0
  464. package/dist/web/documents.d.ts +36 -6
  465. package/dist/web/documents.d.ts.map +1 -1
  466. package/dist/web/documents.js +52 -10
  467. package/dist/web/documents.js.map +1 -1
  468. package/dist/web/feed-atom.d.ts +22 -0
  469. package/dist/web/feed-atom.d.ts.map +1 -0
  470. package/dist/web/feed-atom.js +83 -0
  471. package/dist/web/feed-atom.js.map +1 -0
  472. package/dist/web/feed-item.d.ts +145 -0
  473. package/dist/web/feed-item.d.ts.map +1 -0
  474. package/dist/web/feed-item.js +120 -0
  475. package/dist/web/feed-item.js.map +1 -0
  476. package/dist/web/feed-json.d.ts +79 -0
  477. package/dist/web/feed-json.d.ts.map +1 -0
  478. package/dist/web/feed-json.js +53 -0
  479. package/dist/web/feed-json.js.map +1 -0
  480. package/dist/web/feed-rss.d.ts +26 -0
  481. package/dist/web/feed-rss.d.ts.map +1 -0
  482. package/dist/web/feed-rss.js +203 -0
  483. package/dist/web/feed-rss.js.map +1 -0
  484. package/dist/web/feed-source.d.ts +244 -0
  485. package/dist/web/feed-source.d.ts.map +1 -0
  486. package/dist/web/feed-source.js +201 -0
  487. package/dist/web/feed-source.js.map +1 -0
  488. package/dist/web/feed-xml.d.ts +63 -0
  489. package/dist/web/feed-xml.d.ts.map +1 -0
  490. package/dist/web/feed-xml.js +116 -0
  491. package/dist/web/feed-xml.js.map +1 -0
  492. package/dist/web/feeds.d.ts +31 -96
  493. package/dist/web/feeds.d.ts.map +1 -1
  494. package/dist/web/feeds.js +94 -198
  495. package/dist/web/feeds.js.map +1 -1
  496. package/dist/web/health.d.ts +31 -0
  497. package/dist/web/health.d.ts.map +1 -0
  498. package/dist/web/health.js +44 -0
  499. package/dist/web/health.js.map +1 -0
  500. package/dist/web/index.d.ts +30 -10
  501. package/dist/web/index.d.ts.map +1 -1
  502. package/dist/web/index.js +18 -7
  503. package/dist/web/index.js.map +1 -1
  504. package/dist/web/navigation.d.ts +73 -0
  505. package/dist/web/navigation.d.ts.map +1 -0
  506. package/dist/web/navigation.js +110 -0
  507. package/dist/web/navigation.js.map +1 -0
  508. package/dist/web/negotiate.d.ts +9 -0
  509. package/dist/web/negotiate.d.ts.map +1 -1
  510. package/dist/web/negotiate.js +6 -1
  511. package/dist/web/negotiate.js.map +1 -1
  512. package/dist/web/recent.d.ts +43 -0
  513. package/dist/web/recent.d.ts.map +1 -0
  514. package/dist/web/recent.js +37 -0
  515. package/dist/web/recent.js.map +1 -0
  516. package/dist/web/render.d.ts +197 -9
  517. package/dist/web/render.d.ts.map +1 -1
  518. package/dist/web/render.js +334 -17
  519. package/dist/web/render.js.map +1 -1
  520. package/dist/web/routes.d.ts +25 -8
  521. package/dist/web/routes.d.ts.map +1 -1
  522. package/dist/web/routes.js +845 -93
  523. package/dist/web/routes.js.map +1 -1
  524. package/dist/web/sanitize.d.ts +19 -0
  525. package/dist/web/sanitize.d.ts.map +1 -0
  526. package/dist/web/sanitize.js +272 -0
  527. package/dist/web/sanitize.js.map +1 -0
  528. package/dist/web/search.d.ts +79 -0
  529. package/dist/web/search.d.ts.map +1 -0
  530. package/dist/web/search.js +94 -0
  531. package/dist/web/search.js.map +1 -0
  532. package/dist/web/sitemap.d.ts +120 -0
  533. package/dist/web/sitemap.d.ts.map +1 -0
  534. package/dist/web/sitemap.js +199 -0
  535. package/dist/web/sitemap.js.map +1 -0
  536. package/dist/web/taxonomy.d.ts +152 -0
  537. package/dist/web/taxonomy.d.ts.map +1 -0
  538. package/dist/web/taxonomy.js +237 -0
  539. package/dist/web/taxonomy.js.map +1 -0
  540. package/dist/web/templates.d.ts +54 -16
  541. package/dist/web/templates.d.ts.map +1 -1
  542. package/dist/web/templates.js +109 -28
  543. package/dist/web/templates.js.map +1 -1
  544. package/dist/web/themes.d.ts +205 -0
  545. package/dist/web/themes.d.ts.map +1 -0
  546. package/dist/web/themes.js +277 -0
  547. package/dist/web/themes.js.map +1 -0
  548. package/dist/webmention/discovery.d.ts +51 -0
  549. package/dist/webmention/discovery.d.ts.map +1 -0
  550. package/dist/webmention/discovery.js +176 -0
  551. package/dist/webmention/discovery.js.map +1 -0
  552. package/dist/webmention/html.d.ts +71 -0
  553. package/dist/webmention/html.d.ts.map +1 -0
  554. package/dist/webmention/html.js +285 -0
  555. package/dist/webmention/html.js.map +1 -0
  556. package/dist/webmention/index.d.ts +12 -0
  557. package/dist/webmention/index.d.ts.map +1 -0
  558. package/dist/webmention/index.js +8 -0
  559. package/dist/webmention/index.js.map +1 -0
  560. package/dist/webmention/links.d.ts +18 -0
  561. package/dist/webmention/links.d.ts.map +1 -0
  562. package/dist/webmention/links.js +64 -0
  563. package/dist/webmention/links.js.map +1 -0
  564. package/dist/webmention/microformats.d.ts +93 -0
  565. package/dist/webmention/microformats.d.ts.map +1 -0
  566. package/dist/webmention/microformats.js +376 -0
  567. package/dist/webmention/microformats.js.map +1 -0
  568. package/dist/webmention/receive.d.ts +141 -0
  569. package/dist/webmention/receive.d.ts.map +1 -0
  570. package/dist/webmention/receive.js +264 -0
  571. package/dist/webmention/receive.js.map +1 -0
  572. package/dist/webmention/routes.d.ts +37 -0
  573. package/dist/webmention/routes.d.ts.map +1 -0
  574. package/dist/webmention/routes.js +75 -0
  575. package/dist/webmention/routes.js.map +1 -0
  576. package/dist/webmention/service.d.ts +94 -0
  577. package/dist/webmention/service.d.ts.map +1 -0
  578. package/dist/webmention/service.js +207 -0
  579. package/dist/webmention/service.js.map +1 -0
  580. package/package.json +11 -6
  581. package/templates/site/content/_data/site.json +1 -0
  582. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  583. package/templates/site/geekity.config.ts +11 -1
  584. package/templates/site/tsconfig.json +1 -1
  585. package/themes/default/README.md +1096 -50
  586. package/themes/default/layouts/404.njk +2 -3
  587. package/themes/default/layouts/author.njk +37 -0
  588. package/themes/default/layouts/base.njk +172 -31
  589. package/themes/default/layouts/category.njk +27 -0
  590. package/themes/default/layouts/front-page.njk +57 -0
  591. package/themes/default/layouts/home.njk +17 -1
  592. package/themes/default/layouts/page.njk +57 -5
  593. package/themes/default/layouts/post.njk +78 -19
  594. package/themes/default/layouts/search.njk +57 -0
  595. package/themes/default/layouts/tag.njk +3 -6
  596. package/themes/default/mail/comment-digest.html.njk +37 -0
  597. package/themes/default/mail/comment-digest.subject.njk +3 -0
  598. package/themes/default/mail/comment-digest.txt.njk +40 -0
  599. package/themes/default/mail/comment-pending.html.njk +27 -0
  600. package/themes/default/mail/comment-pending.subject.njk +2 -0
  601. package/themes/default/mail/comment-pending.txt.njk +24 -0
  602. package/themes/default/mail/comment-reply.html.njk +21 -0
  603. package/themes/default/mail/comment-reply.subject.njk +2 -0
  604. package/themes/default/mail/comment-reply.txt.njk +22 -0
  605. package/themes/default/mail/contact-message.html.njk +24 -0
  606. package/themes/default/mail/contact-message.subject.njk +5 -0
  607. package/themes/default/mail/contact-message.txt.njk +20 -0
  608. package/themes/default/mail/password-changed.html.njk +18 -0
  609. package/themes/default/mail/password-changed.subject.njk +2 -0
  610. package/themes/default/mail/password-changed.txt.njk +17 -0
  611. package/themes/default/mail/password-reset.html.njk +22 -0
  612. package/themes/default/mail/password-reset.subject.njk +2 -0
  613. package/themes/default/mail/password-reset.txt.njk +18 -0
  614. package/themes/default/mail/test.html.njk +14 -0
  615. package/themes/default/mail/test.subject.njk +2 -0
  616. package/themes/default/mail/test.txt.njk +12 -0
  617. package/themes/default/partials/archive.njk +27 -0
  618. package/themes/default/partials/bio.njk +77 -0
  619. package/themes/default/partials/comment-form.njk +109 -0
  620. package/themes/default/partials/contact-form.njk +88 -0
  621. package/themes/default/partials/conversation.njk +139 -0
  622. package/themes/default/partials/feeds.njk +26 -0
  623. package/themes/default/partials/jsonld.njk +120 -0
  624. package/themes/default/partials/pagination.njk +12 -6
  625. package/themes/default/partials/post-list.njk +51 -18
  626. package/themes/default/partials/search-form.njk +17 -0
  627. package/themes/default/partials/tags.njk +26 -5
  628. package/themes/default/static/highlight.js +4 -0
  629. package/themes/default/static/style.css +1119 -194
  630. package/themes/default/theme.json +5 -0
  631. package/admin/layouts/document-editor.njk +0 -167
  632. package/admin/layouts/federation.njk +0 -145
  633. package/admin/layouts/login.njk +0 -23
  634. package/admin/layouts/settings.njk +0 -116
  635. package/admin/layouts/setup.njk +0 -27
  636. package/admin/layouts/users.njk +0 -91
  637. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/admin/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAM7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAsB5C,kCAAkC;AAClC,eAAO,MAAM,UAAU,iBAA0B,CAAC;AAClD,sCAAsC;AACtC,eAAO,MAAM,UAAU,iBAA0B,CAAC;AAClD,mCAAmC;AACnC,eAAO,MAAM,WAAW,kBAA2B,CAAC;AACpD,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,uBAAgC,CAAC;AAE9D,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAOjD,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CA2RtD;AAKD;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,iBAAiB,CAAC,UAAU,CA+B/C,CAAC"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/admin/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAuC5C,kCAAkC;AAClC,eAAO,MAAM,UAAU,iBAA0B,CAAC;AAClD,sCAAsC;AACtC,eAAO,MAAM,UAAU,iBAA0B,CAAC;AAClD,mCAAmC;AACnC,eAAO,MAAM,WAAW,kBAA2B,CAAC;AAEpD,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAoUtD;AAKD;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,iBAAiB,CAAC,UAAU,CAwC/C,CAAC"}
@@ -1,16 +1,22 @@
1
- import { contentFilePath, freeSlug, saveDocument } from '../content/save.js';
2
- import { defaultPermalink, slugify } from '../content/slug.js';
3
- import { normalizeBody } from '../content/writer.js';
1
+ import { countUsers, createUser, DuplicateUsernameError, findUserById, verifyUserPassword, } from './accounts.js';
2
+ import { mountAppearanceScreen } from './appearance.js';
4
3
  import { adminAssetResponse, ADMIN_ASSET_PREFIX } from './assets.js';
5
4
  import { credentialProblem } from './credentials.js';
6
5
  import { editorPath, mountDocumentScreens, PAGE_KIND, POST_KIND } from './documents.js';
7
6
  import { FEDERATION_PATH, mountFederationScreen } from './federation.js';
8
- import { flash, takeFlash } from './flash.js';
7
+ import { takeFlash } from './flash.js';
8
+ import { adminSecurityHeaders } from './headers.js';
9
+ import { COMMENTS_PATH, mountCommentsScreen, pendingComments } from './comments.js';
10
+ import { MEDIA_UPLOAD_PATH, mountMediaScreen } from './media.js';
11
+ import { adminMenu } from './menu.js';
12
+ import { MESSAGES_PATH, mountMessagesScreen, unreadMessages } from './messages.js';
9
13
  import { mountPreview } from './preview.js';
10
- import { AVATAR_PATH, mountSettings } from './settings.js';
14
+ import { FORGOT_PATH, mountRecovery, RESET_PATH } from './recovery.js';
15
+ import { mountSettings } from './settings-pages.js';
11
16
  import { ADMIN_PREFIX, clearSessionCookie, CSRF_FIELD, csrfTokenMatches, sessionIdFrom, setSessionCookie, } from './session.js';
12
- import { DuplicateUsernameError } from './store.js';
17
+ import { mountTaxonomyScreens, TAXONOMY_KINDS } from './taxonomy.js';
13
18
  import { ADMIN_TEMPLATES, createAdminTemplateEnvironment } from './templates.js';
19
+ import { clientAddress, createLoginThrottle, describeWait, loginKeys } from './throttle.js';
14
20
  import { mountUploads, refuseOversizedUpload, UPLOADS_PATH } from './uploads.js';
15
21
  import { mountUsers } from './users.js';
16
22
  /** Where the login form lives. */
@@ -19,24 +25,6 @@ export const LOGIN_PATH = `${ADMIN_PREFIX}/login`;
19
25
  export const SETUP_PATH = `${ADMIN_PREFIX}/setup`;
20
26
  /** Where the logout form posts. */
21
27
  export const LOGOUT_PATH = `${ADMIN_PREFIX}/logout`;
22
- /** Where the dashboard's quick draft form posts. */
23
- export const QUICK_DRAFT_PATH = `${ADMIN_PREFIX}/quick-draft`;
24
- /**
25
- * The sections of the admin, in the order doc-5 lists them.
26
- *
27
- * Every screen renders the same list and marks one of them, so a screen added
28
- * later only has to name its section. The screens behind most of these links
29
- * are still placeholders; the navigation is the shape of the whole admin, not
30
- * of the part that is built.
31
- */
32
- export const ADMIN_SECTIONS = [
33
- { section: 'dashboard', label: 'Dashboard', url: ADMIN_PREFIX },
34
- { section: 'posts', label: 'Posts', url: `${ADMIN_PREFIX}/posts` },
35
- { section: 'pages', label: 'Pages', url: `${ADMIN_PREFIX}/pages` },
36
- { section: 'settings', label: 'Settings', url: `${ADMIN_PREFIX}/settings` },
37
- { section: 'users', label: 'Users', url: `${ADMIN_PREFIX}/users` },
38
- { section: 'federation', label: 'Federation', url: `${ADMIN_PREFIX}/federation` },
39
- ];
40
28
  /** How many recent posts the dashboard lists. */
41
29
  export const DASHBOARD_RECENT_POSTS = 5;
42
30
  /** Where the editor for a post lives. */
@@ -64,13 +52,44 @@ export function mountAdmin(app) {
64
52
  environment ??= createAdminTemplateEnvironment({ noCache: c.var.config.watch });
65
53
  return environment;
66
54
  }
55
+ // One throttle for the whole mount, built on the first failed sign-in for
56
+ // the same reason: the limits and the clock are on the context. It holds
57
+ // nothing but recent failures, so it belongs to the process rather than to
58
+ // the database — a restart clears it, which is the right trade for state an
59
+ // anonymous caller can create.
60
+ let throttled;
61
+ function loginThrottle(config) {
62
+ throttled ??= createLoginThrottle({
63
+ attempts: config.loginAttempts,
64
+ lockoutSeconds: config.loginLockout,
65
+ now: config.now,
66
+ });
67
+ return throttled;
68
+ }
69
+ // A second throttle, on the same machinery and the same limits, for the
70
+ // forgot-password form (TASK-54). Deliberately not the login one: sharing it
71
+ // would let a stranger lock somebody out of signing in by asking for their
72
+ // password to be reset over and over, which would turn the recovery feature
73
+ // into a weapon against the person it exists for.
74
+ let recoveryThrottled;
75
+ function recoveryThrottle(config) {
76
+ recoveryThrottled ??= createLoginThrottle({
77
+ attempts: config.loginAttempts,
78
+ lockoutSeconds: config.loginLockout,
79
+ now: config.now,
80
+ });
81
+ return recoveryThrottled;
82
+ }
67
83
  /**
68
84
  * Render one admin template.
69
85
  *
70
86
  * Everything the chrome needs — who is signed in, the navigation, the CSRF
71
87
  * token, the queued flash messages — is put in the context here rather than
72
- * by each handler, so a new screen is a template and a `section` name.
73
- * Reading the flash is what clears it, so it shows on exactly this page.
88
+ * by each handler, so a new screen is a template and the pair of names that
89
+ * says where it is in the menu: its `section` and its `child`. A pair the
90
+ * registry does not hold throws rather than rendering a menu expanded around
91
+ * nothing. Reading the flash is what clears it, so it shows on exactly this
92
+ * page.
74
93
  */
75
94
  function render(c, template, context = {}) {
76
95
  const session = c.var.session;
@@ -80,15 +99,22 @@ export function mountAdmin(app) {
80
99
  adminUrl: ADMIN_PREFIX,
81
100
  siteUrl: '/',
82
101
  assetPrefix: ADMIN_ASSET_PREFIX,
83
- navigation: ADMIN_SECTIONS,
102
+ navigation: adminMenu({ section: name(context['section']), child: name(context['child']) }),
84
103
  logoutUrl: LOGOUT_PATH,
85
104
  csrfToken: session?.csrfToken ?? '',
86
- user: userId === null ? undefined : c.var.admin.getUserById(userId),
105
+ cspNonce: c.var.cspNonce ?? '',
106
+ user: userId === null ? undefined : findUserById(c.var.config.dataDir, userId),
87
107
  flash: takeFlash(c),
88
108
  ...context,
89
109
  });
90
110
  return c.html(html);
91
111
  }
112
+ // In front of everything, including the static files and the login form, so
113
+ // "every admin response" means every one of them rather than every one a
114
+ // handler happened to reach. It also mints the CSP nonce the editor's script
115
+ // tag carries, which is why it has to run before any template is rendered.
116
+ app.use(ADMIN_PREFIX, adminSecurityHeaders);
117
+ app.use(`${ADMIN_PREFIX}/*`, adminSecurityHeaders);
92
118
  // Registered before the guard, so the login page can load its stylesheet
93
119
  // while nobody is logged in. Nothing under it is secret.
94
120
  app.get(`${ADMIN_ASSET_PREFIX}*`, (c) => {
@@ -97,10 +123,11 @@ export function mountAdmin(app) {
97
123
  return response ?? c.notFound();
98
124
  });
99
125
  // In front of the guard, because the guard parses the form to find the CSRF
100
- // token and parsing a multipart form reads the whole file into memory. Both
101
- // multipart endpoints need it: the editor's uploads and the avatar's.
126
+ // token and parsing a multipart form reads the whole file into memory. Every
127
+ // multipart endpoint needs it: the editor's uploads and the media screen's
128
+ // own form.
102
129
  app.use(UPLOADS_PATH, refuseOversizedUpload);
103
- app.use(AVATAR_PATH, refuseOversizedUpload);
130
+ app.use(MEDIA_UPLOAD_PATH, refuseOversizedUpload);
104
131
  app.use(ADMIN_PREFIX, guard);
105
132
  app.use(`${ADMIN_PREFIX}/*`, guard);
106
133
  app.get(SETUP_PATH, (c) => {
@@ -117,7 +144,7 @@ export function mountAdmin(app) {
117
144
  return refuseSetup(c, username, problem);
118
145
  let user;
119
146
  try {
120
- user = c.var.admin.createUser({ username, password });
147
+ user = await createUser({ dataDir: c.var.config.dataDir, username, password });
121
148
  }
122
149
  catch (error) {
123
150
  if (error instanceof DuplicateUsernameError) {
@@ -131,24 +158,58 @@ export function mountAdmin(app) {
131
158
  });
132
159
  app.get(LOGIN_PATH, (c) => {
133
160
  anonymousSession(c);
134
- return render(c, ADMIN_TEMPLATES.login, { loginUrl: LOGIN_PATH, username: '' });
161
+ return render(c, ADMIN_TEMPLATES.login, {
162
+ loginUrl: LOGIN_PATH,
163
+ forgotUrl: FORGOT_PATH,
164
+ username: '',
165
+ });
135
166
  });
167
+ // Forgetting a password. Registered beside the login form, and named in the
168
+ // guard below, because both of its screens are reached by somebody who by
169
+ // definition cannot sign in.
170
+ mountRecovery(app, { render, anonymousSession, throttle: recoveryThrottle });
136
171
  app.post(LOGIN_PATH, async (c) => {
172
+ const config = c.var.config;
137
173
  const body = await c.req.parseBody();
138
174
  const username = text(body[USERNAME_FIELD]).trim();
139
175
  const password = text(body[PASSWORD_FIELD]);
140
- const user = c.var.admin.verifyPassword(username, password);
176
+ const address = clientAddress(c, config);
177
+ const keys = loginKeys(username, address);
178
+ // Checked before the password is verified, so a lockout refuses the right
179
+ // password too. An attacker who found the password on the last allowed
180
+ // guess would otherwise be let straight in.
181
+ const throttle = loginThrottle(config);
182
+ const wait = throttle.retryAfter(keys);
183
+ if (wait !== undefined) {
184
+ console.warn(`Refused a sign-in for ${JSON.stringify(username)} from ${address ?? 'an unknown address'}: locked out for another ${wait}s`);
185
+ anonymousSession(c);
186
+ c.status(429);
187
+ c.header('Retry-After', String(wait));
188
+ return render(c, ADMIN_TEMPLATES.login, {
189
+ loginUrl: LOGIN_PATH,
190
+ forgotUrl: FORGOT_PATH,
191
+ username,
192
+ // Says nothing about whether that username exists: an unknown one is
193
+ // counted and locked out exactly as a real one is.
194
+ error: `Too many sign-in attempts. Try again in ${describeWait(wait)}.`,
195
+ });
196
+ }
197
+ const user = verifyUserPassword(c.var.config.dataDir, username, password);
141
198
  if (user === undefined) {
199
+ throttle.fail(keys);
200
+ console.warn(`Failed sign-in for ${JSON.stringify(username)} from ${address ?? 'an unknown address'}`);
142
201
  // One message for both failures, so the form cannot be used to find out
143
202
  // which usernames exist.
144
203
  anonymousSession(c);
145
204
  c.status(401);
146
205
  return render(c, ADMIN_TEMPLATES.login, {
147
206
  loginUrl: LOGIN_PATH,
207
+ forgotUrl: FORGOT_PATH,
148
208
  username,
149
209
  error: 'That username and password do not match.',
150
210
  });
151
211
  }
212
+ throttle.succeed(keys);
152
213
  return logIn(c, user);
153
214
  });
154
215
  app.post(LOGOUT_PATH, (c) => {
@@ -162,6 +223,7 @@ export function mountAdmin(app) {
162
223
  const store = c.var.store;
163
224
  return render(c, ADMIN_TEMPLATES.dashboard, {
164
225
  section: 'dashboard',
226
+ child: 'home',
165
227
  counts: store.counts(),
166
228
  recent: store.listAll({ type: 'post', limit: DASHBOARD_RECENT_POSTS }).map((document) => ({
167
229
  title: document.title,
@@ -170,73 +232,49 @@ export function mountAdmin(app) {
170
232
  draft: document.draft,
171
233
  editUrl: postEditorPath(document.slug),
172
234
  })),
173
- quickDraftUrl: QUICK_DRAFT_PATH,
174
235
  // The one number on the dashboard that is not about the content
175
236
  // directory: it is what says whether publishing is reaching anybody.
176
237
  followers: c.var.admin.countFollowers(),
177
238
  federationUrl: FEDERATION_PATH,
239
+ // The other number that is not about the content directory: with no
240
+ // email in this milestone, the dashboard is how a moderator finds out
241
+ // that somebody is waiting (TASK-50).
242
+ pendingComments: pendingComments(c.var.admin),
243
+ commentsUrl: COMMENTS_PATH,
244
+ // And what the contact form has left waiting, which is the same kind of
245
+ // number for the same reason (TASK-56).
246
+ unreadMessages: unreadMessages(c.var.config.dataDir),
247
+ messagesUrl: MESSAGES_PATH,
178
248
  });
179
249
  });
180
- /**
181
- * The dashboard's quick draft: a title and a body, straight to a draft file.
182
- *
183
- * It writes a draft rather than a published post because the point of the box
184
- * is to catch an idea before it goes, and because the editor TASK-11 builds is
185
- * where the decision to publish belongs.
186
- */
187
- app.post(QUICK_DRAFT_PATH, async (c) => {
188
- const body = await c.req.parseBody();
189
- const title = text(body['title']).trim();
190
- if (title === '') {
191
- flash(c, 'error', 'A draft needs a title.');
192
- return c.redirect(ADMIN_PREFIX, 303);
193
- }
194
- const contentDir = c.var.config.contentDir;
195
- const store = c.var.store;
196
- const date = new Date().toISOString();
197
- const slug = await freeSlug({
198
- contentDir,
199
- store,
200
- type: 'post',
201
- slug: slugify(title) || 'untitled',
202
- date,
203
- });
204
- const document = await saveDocument({
205
- contentDir,
206
- store,
207
- path: contentFilePath({ type: 'post', slug, date }),
208
- content: {
209
- title,
210
- date,
211
- permalink: defaultPermalink({ type: 'post', slug, date }),
212
- tags: [],
213
- draft: true,
214
- extra: {},
215
- body: normalizeBody(text(body['body'])),
216
- },
217
- });
218
- await c.var.announce({
219
- type: 'created',
220
- path: document.path,
221
- previous: undefined,
222
- next: document,
223
- origin: 'admin',
224
- });
225
- flash(c, 'notice', `Draft saved: ${document.title}`);
226
- return c.redirect(postEditorPath(document.slug), 303);
227
- });
228
250
  // The listing and the editor. Posts and pages are the same screens over the
229
251
  // same store; the kind decides what a file is called and which fields the
230
252
  // form has.
231
253
  mountDocumentScreens(app, { kind: POST_KIND, render });
232
254
  mountDocumentScreens(app, { kind: PAGE_KIND, render });
255
+ // The terms themselves: what is in use, and the three things — rename,
256
+ // merge, delete — that rewrite every file carrying one.
257
+ for (const kind of TAXONOMY_KINDS)
258
+ mountTaxonomyScreens(app, { kind, render });
233
259
  // The two endpoints the editor talks to rather than navigates to. Both are
234
260
  // inside the guard, so both need the session's CSRF token like every other
235
261
  // POST in the admin.
236
262
  mountPreview(app);
237
263
  mountUploads(app);
238
- // The site's own settings: SQLite is the source, content/_data/site.json is
239
- // the mirror an Eleventy build of the same content reads.
264
+ // Everything under content/uploads: what is there, what links to it, and
265
+ // the upload form that stores a file by the same rules the editor does.
266
+ mountMediaScreen(app, { render });
267
+ // What the contact form on a page has collected, and the two things that can
268
+ // be done about one: mark it read, and delete it.
269
+ mountMessagesScreen(app, { render });
270
+ // What people have left on the site, and the four things that can be done
271
+ // about it: approve, spam, delete, reply.
272
+ mountCommentsScreen(app, { render });
273
+ // What the site is wearing: the themes on disk, and the one setting that
274
+ // says which of them (decision-15).
275
+ mountAppearanceScreen(app, { render });
276
+ // The site's own settings, which are content/_data/site.json itself: the
277
+ // screen reads that file and writes it back (decision-9).
240
278
  mountSettings(app, { render });
241
279
  // Who may sign in: the list, the add form, and the change-password form for
242
280
  // whoever is looking at it.
@@ -244,22 +282,6 @@ export function mountAdmin(app) {
244
282
  // The fediverse side: the actor, the followers, the inbox log, and what the
245
283
  // site sent to whom.
246
284
  mountFederationScreen(app, { render });
247
- const built = new Set([
248
- POST_KIND.section,
249
- PAGE_KIND.section,
250
- 'dashboard',
251
- 'settings',
252
- 'users',
253
- 'federation',
254
- ]);
255
- // The sections doc-5 lists but no task has built yet. They are registered so
256
- // the navigation goes somewhere: a link that 404s reads as a broken admin,
257
- // and the guard already keeps strangers out of all of them.
258
- for (const item of ADMIN_SECTIONS) {
259
- if (built.has(item.section))
260
- continue;
261
- app.get(item.url, (c) => render(c, ADMIN_TEMPLATES.placeholder, { section: item.section, heading: item.label }));
262
- }
263
285
  // `/admin/` is the same screen as `/admin`, and only one of them is the URL.
264
286
  app.get(`${ADMIN_PREFIX}/`, (c) => c.redirect(ADMIN_PREFIX, 301));
265
287
  /** The session to hang a CSRF token on, made on the spot if there is none. */
@@ -314,15 +336,19 @@ const PASSWORD_FIELD = 'password';
314
336
  */
315
337
  export const guard = async (c, next) => {
316
338
  const admin = c.var.admin;
339
+ const dataDir = c.var.config.dataDir;
317
340
  const pathname = new URL(c.req.url).pathname;
318
341
  // Reading a session prunes it when it has expired, so an expired session is
319
342
  // gone from here on, not merely ignored.
320
343
  const sessionId = sessionIdFrom(c);
321
- const session = sessionId === undefined ? undefined : admin.getSession(sessionId);
344
+ const session = liveSession(admin, dataDir, sessionId === undefined ? undefined : admin.getSession(sessionId));
322
345
  c.set('session', session);
323
346
  const isSetup = pathname === SETUP_PATH;
324
- const isLogin = pathname === LOGIN_PATH;
325
- if (admin.countUsers() === 0) {
347
+ // The three screens somebody with no login is allowed to reach: the login
348
+ // form, and the two halves of forgetting a password (TASK-54). Everything
349
+ // else under /admin redirects an anonymous visitor to the login form.
350
+ const isAnonymous = pathname === LOGIN_PATH || pathname === FORGOT_PATH || pathname === RESET_PATH;
351
+ if (countUsers(dataDir) === 0) {
326
352
  // Nobody can log in yet, so there is exactly one thing to do here.
327
353
  if (!isSetup)
328
354
  return c.redirect(SETUP_PATH, 302);
@@ -331,7 +357,7 @@ export const guard = async (c, next) => {
331
357
  // Setup is over. Offering the form again would be an open door.
332
358
  if (isSetup)
333
359
  return c.redirect(session?.userId == null ? LOGIN_PATH : ADMIN_PREFIX, 302);
334
- if (!isLogin && (session === undefined || session.userId === null)) {
360
+ if (!isAnonymous && (session === undefined || session.userId === null)) {
335
361
  return c.redirect(LOGIN_PATH, 302);
336
362
  }
337
363
  }
@@ -342,6 +368,26 @@ export const guard = async (c, next) => {
342
368
  }
343
369
  await next();
344
370
  };
371
+ /**
372
+ * The session a request really has: one whose user is still in `users.json`.
373
+ *
374
+ * `sessions.user_id` used to be a foreign key into the users table, so a user
375
+ * who was deleted took their logins with them and a session could never name
376
+ * somebody who was not there. The accounts are a file now and the sessions are
377
+ * a cache in a database that may be deleted, restored or rebuilt on its own,
378
+ * so the join is made here instead: a session naming a user the file does not
379
+ * hold is deleted, and the request is anonymous. That is exactly what makes a
380
+ * login survive a rebuilt database only as far as the file still holds the
381
+ * person it was made for.
382
+ */
383
+ function liveSession(admin, dataDir, session) {
384
+ if (session === undefined || session.userId === null)
385
+ return session;
386
+ if (findUserById(dataDir, session.userId) !== undefined)
387
+ return session;
388
+ admin.deleteSession(session.id);
389
+ return undefined;
390
+ }
345
391
  /** The CSRF token in the request body, if the body is a form at all. */
346
392
  async function submittedToken(c) {
347
393
  const contentType = c.req.header('content-type') ?? '';
@@ -365,6 +411,10 @@ function decodePath(pathname) {
365
411
  return pathname;
366
412
  }
367
413
  }
414
+ /** A `section` or a `child` off a render context, when the screen named one. */
415
+ function name(value) {
416
+ return typeof value === 'string' ? value : undefined;
417
+ }
368
418
  /** A form field as a string. A file upload, or a missing field, is the empty one. */
369
419
  function text(value) {
370
420
  return typeof value === 'string' ? value : '';
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/admin/routes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,kCAAkC;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,YAAY,QAAQ,CAAC;AAClD,sCAAsC;AACtC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,YAAY,QAAQ,CAAC;AAClD,mCAAmC;AACnC,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,YAAY,SAAS,CAAC;AACpD,oDAAoD;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,YAAY,cAAc,CAAC;AAY9D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,EAAE;IAC/D,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,QAAQ,EAAE;IAClE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,QAAQ,EAAE;IAClE,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,YAAY,WAAW,EAAE;IAC3E,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,QAAQ,EAAE;IAClE,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,YAAY,aAAa,EAAE;CAClF,CAAC;AAEF,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC,yCAAyC;AACzC,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,GAAqB;IAC9C,4EAA4E;IAC5E,oCAAoC;IACpC,IAAI,WAAoC,CAAC;IAEzC,SAAS,SAAS,CAAC,CAAsB;QACvC,WAAW,KAAK,8BAA8B,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAChF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,MAAM,CACb,CAAsB,EACtB,QAAgB,EAChB,OAAO,GAA4B,EAAE;QAErC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC;QAEvC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;YACzC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC3B,QAAQ,EAAE,YAAY;YACtB,OAAO,EAAE,GAAG;YACZ,WAAW,EAAE,kBAAkB;YAC/B,UAAU,EAAE,cAAc;YAC1B,SAAS,EAAE,WAAW;YACtB,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE;YACnC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;YACnE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YACnB,GAAG,OAAO;SACX,CAAC,CAAC;QACH,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,yEAAyE;IACzE,yDAAyD;IACzD,GAAG,CAAC,GAAG,CAAC,GAAG,kBAAkB,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;QACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QACzF,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,4EAA4E;IAC5E,sEAAsE;IACtE,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC;IAC7C,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAE5C,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC7B,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,IAAI,EAAE,KAAK,CAAC,CAAC;IAEpC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;QACxB,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAEzD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/D,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEpE,IAAI,IAAU,CAAC;QACf,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;gBAC5C,OAAO,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACjD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,0EAA0E;QAC1E,uDAAuD;QACvD,OAAO,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;QACxB,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAE5C,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC5D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,wEAAwE;YACxE,yBAAyB;YACzB,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACpB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,KAAK,EAAE;gBACtC,QAAQ,EAAE,UAAU;gBACpB,QAAQ;gBACR,KAAK,EAAE,0CAA0C;aAClD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC9B,IAAI,OAAO,KAAK,SAAS;YAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE;QAC1B,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,SAAS,EAAE;YAC1C,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACxF,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC;aACvC,CAAC,CAAC;YACH,aAAa,EAAE,gBAAgB;YAC/B,gEAAgE;YAChE,qEAAqE;YACrE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE;YACvC,aAAa,EAAE,eAAe;SAC/B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEzC,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,wBAAwB,CAAC,CAAC;YAC5C,OAAO,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;QAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC;YAC1B,UAAU;YACV,KAAK;YACL,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,UAAU;YAClC,IAAI;SACL,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC;YAClC,UAAU;YACV,KAAK;YACL,IAAI,EAAE,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACnD,OAAO,EAAE;gBACP,KAAK;gBACL,IAAI;gBACJ,SAAS,EAAE,gBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBACzD,IAAI,EAAE,EAAE;gBACR,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;aACxC;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;QAEH,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,gBAAgB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,0EAA0E;IAC1E,YAAY;IACZ,oBAAoB,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,oBAAoB,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAEvD,2EAA2E;IAC3E,2EAA2E;IAC3E,qBAAqB;IACrB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,YAAY,CAAC,GAAG,CAAC,CAAC;IAElB,4EAA4E;IAC5E,0DAA0D;IAC1D,aAAa,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAE/B,4EAA4E;IAC5E,4BAA4B;IAC5B,UAAU,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAE5B,4EAA4E;IAC5E,qBAAqB;IACrB,qBAAqB,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC;QACpB,SAAS,CAAC,OAAO;QACjB,SAAS,CAAC,OAAO;QACjB,WAAW;QACX,UAAU;QACV,OAAO;QACP,YAAY;KACb,CAAC,CAAC;IAEH,6EAA6E;IAC7E,2EAA2E;IAC3E,4DAA4D;IAC5D,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CACtB,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CACvF,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC;IAElE,8EAA8E;IAC9E,SAAS,gBAAgB,CAAC,CAAsB;QAC9C,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC/B,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAE5C,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC;YACxC,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe;SAC9C,CAAC,CAAC;QACH,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACxF,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+EAA+E;IAC/E,SAAS,WAAW,CAAC,CAAsB,EAAE,QAAgB,EAAE,KAAa;QAC1E,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;OAMG;IACH,SAAS,KAAK,CAAC,CAAsB,EAAE,IAAU;QAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAC1B,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC/B,IAAI,QAAQ,KAAK,SAAS;YAAE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7D,wEAAwE;QACxE,KAAK,CAAC,aAAa,EAAE,CAAC;QAEtB,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC;YAClC,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,eAAe,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe;SAC9C,CAAC,CAAC;QACH,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACxF,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,cAAc,GAAG,UAAU,CAAC;AAClC,MAAM,cAAc,GAAG,UAAU,CAAC;AAElC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAkC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;IACpE,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;IAC1B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IAE7C,4EAA4E;IAC5E,yCAAyC;IACzC,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAClF,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE1B,MAAM,OAAO,GAAG,QAAQ,KAAK,UAAU,CAAC;IACxC,MAAM,OAAO,GAAG,QAAQ,KAAK,UAAU,CAAC;IAExC,IAAI,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC;QAC7B,mEAAmE;QACnE,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,gEAAgE;QAChE,IAAI,OAAO;YAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACtD,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3F,OAAO,CAAC,CAAC,IAAI,CAAC,wEAAwE,EAAE,GAAG,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAED,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC;AAEF,wEAAwE;AACxE,KAAK,UAAU,cAAc,CAAC,CAAsB;IAClD,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IACvD,IACE,CAAC,WAAW,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QAC1D,CAAC,WAAW,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAC5C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,gFAAgF;IAChF,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IACrC,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,QAAgB;IAClC,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,SAAS,IAAI,CAAC,KAAc;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,iFAAiF;AACjF,SAAS,YAAY,CACnB,QAAgB,EAChB,QAAgB,EAChB,YAAoB;IAEpB,4EAA4E;IAC5E,oDAAoD;IACpD,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,iCAAiC,CAAC;IACxE,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/admin/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Discussion: what the site takes back from the people reading it.
3
+ *
4
+ * WordPress's own name for the comment settings. Webmentions are here because
5
+ * one arriving is a comment by another road, and the spam checker is here
6
+ * because it is what decides whether either is shown.
7
+ */
8
+ import type { SettingsPage } from './settings-page.ts';
9
+ /**
10
+ * Where the Akismet key's form and its Remove button post.
11
+ *
12
+ * Its own endpoint, for the reason the avatar has one: the key is a credential
13
+ * that lives in `data/akismet.json` rather than a setting that lives in
14
+ * `content/_data/site.json` (TASK-52), so it is not a field of the Discussion
15
+ * form, and a key Akismet will not take must not lose an edit to the closing
16
+ * window beside it.
17
+ */
18
+ export declare const AKISMET_PATH = "/admin/settings/akismet";
19
+ /** The fields those two forms submit. */
20
+ export declare const AKISMET_FIELDS: {
21
+ readonly key: 'akismet_key';
22
+ readonly action: 'action';
23
+ };
24
+ /** The {@link AKISMET_FIELDS.action} that forgets the key again. */
25
+ export declare const AKISMET_REMOVE = "remove";
26
+ /** The Discussion settings page. */
27
+ export declare const DISCUSSION_SETTINGS: SettingsPage;
28
+ /**
29
+ * What the page says about Akismet: connected, refused, unchecked, or off.
30
+ *
31
+ * The key itself never leaves this function. A settings screen that printed it
32
+ * back would put a credential in every browser cache and every screenshot; the
33
+ * last four characters are enough for somebody to recognise which key is in
34
+ * there without being handed it.
35
+ */
36
+ export declare function akismetPanel(dataDir: string): Record<string, unknown>;
37
+ //# sourceMappingURL=settings-discussion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-discussion.d.ts","sourceRoot":"","sources":["../../src/admin/settings-discussion.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,OAAO,KAAK,EAAwB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI7E;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,4BAA6B,CAAC;AAEvD,yCAAyC;AACzC,eAAO,MAAM,cAAc;aAAK,GAAG,EAAE,aAAa;aAAE,MAAM,EAAE,QAAQ;CAAW,CAAC;AAEhF,oEAAoE;AACpE,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,oCAAoC;AACpC,eAAO,MAAM,mBAAmB,EAAE,YAUjC,CAAC;AA0DF;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6BrE"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Discussion: what the site takes back from the people reading it.
3
+ *
4
+ * WordPress's own name for the comment settings. Webmentions are here because
5
+ * one arriving is a comment by another road, and the spam checker is here
6
+ * because it is what decides whether either is shown.
7
+ */
8
+ import { readAkismetKey, removeAkismetKey, verifyAkismetKey, writeAkismetKey, } from '../comments/akismet.js';
9
+ import { flash } from './flash.js';
10
+ import { bodyField, settingsPagePath } from './settings-page.js';
11
+ import { effectiveBaseUrl, readSiteSettings, SETTINGS_PATH } from './settings.js';
12
+ import { ADMIN_TEMPLATES } from './templates.js';
13
+ /**
14
+ * Where the Akismet key's form and its Remove button post.
15
+ *
16
+ * Its own endpoint, for the reason the avatar has one: the key is a credential
17
+ * that lives in `data/akismet.json` rather than a setting that lives in
18
+ * `content/_data/site.json` (TASK-52), so it is not a field of the Discussion
19
+ * form, and a key Akismet will not take must not lose an edit to the closing
20
+ * window beside it.
21
+ */
22
+ export const AKISMET_PATH = `${SETTINGS_PATH}/akismet`;
23
+ /** The fields those two forms submit. */
24
+ export const AKISMET_FIELDS = { key: 'akismet_key', action: 'action' };
25
+ /** The {@link AKISMET_FIELDS.action} that forgets the key again. */
26
+ export const AKISMET_REMOVE = 'remove';
27
+ /** The Discussion settings page. */
28
+ export const DISCUSSION_SETTINGS = {
29
+ child: 'discussion',
30
+ label: 'Discussion',
31
+ path: settingsPagePath('discussion'),
32
+ template: ADMIN_TEMPLATES.settingsDiscussion,
33
+ fields: ['comments', 'commentsCloseAfterDays', 'webmentionsSend', 'webmentionsReceive'],
34
+ panels: (c) => akismetPanel(c.var.config.dataDir),
35
+ endpoints: mountAkismet,
36
+ };
37
+ /**
38
+ * The Akismet key: one form saves it, a second forgets it.
39
+ *
40
+ * The key is checked with Akismet's own `verify-key` before it is stored, so a
41
+ * site is told about a typo now rather than by a queue that quietly stops being
42
+ * filtered. What comes back is stored beside the key, because it is what the
43
+ * screen reports and re-asking on every render would be a network call to draw
44
+ * a page.
45
+ *
46
+ * A key Akismet refuses is stored all the same, marked as refused. It does no
47
+ * harm — `comment-check` with a key Akismet does not know answers `invalid`,
48
+ * which this treats as no opinion, so comments queue exactly as they did — and
49
+ * storing it is what lets the screen say "Akismet does not recognise this key"
50
+ * instead of throwing away what somebody pasted.
51
+ */
52
+ function mountAkismet(app, _options) {
53
+ const here = DISCUSSION_SETTINGS.path;
54
+ app.post(AKISMET_PATH, async (c) => {
55
+ const body = await c.req.parseBody();
56
+ const { config } = c.var;
57
+ if (bodyField(body[AKISMET_FIELDS.action]) === AKISMET_REMOVE) {
58
+ await removeAkismetKey(config.dataDir);
59
+ flash(c, 'notice', 'The Akismet key is gone. Nothing is sent to Akismet any more.');
60
+ return c.redirect(here, 303);
61
+ }
62
+ const key = bodyField(body[AKISMET_FIELDS.key]).trim();
63
+ if (key === '') {
64
+ flash(c, 'error', 'An Akismet key cannot be empty. Use Remove key to turn Akismet off.');
65
+ return c.redirect(here, 303);
66
+ }
67
+ const blog = effectiveBaseUrl(config, readSiteSettings(config.contentDir));
68
+ const status = await verifyAkismetKey({ key, blog });
69
+ await writeAkismetKey(config.dataDir, {
70
+ key,
71
+ status,
72
+ checkedAt: config.now().toISOString(),
73
+ });
74
+ flash(c, status === 'valid' ? 'notice' : 'error', status === 'valid'
75
+ ? 'Akismet is connected. Comments and webmentions are checked from now on.'
76
+ : status === 'invalid'
77
+ ? 'The key is stored, but Akismet does not recognise it, so nothing it says will be believed.'
78
+ : 'The key is stored, but Akismet could not be reached to check it. Save it again to try.');
79
+ return c.redirect(here, 303);
80
+ });
81
+ }
82
+ /**
83
+ * What the page says about Akismet: connected, refused, unchecked, or off.
84
+ *
85
+ * The key itself never leaves this function. A settings screen that printed it
86
+ * back would put a credential in every browser cache and every screenshot; the
87
+ * last four characters are enough for somebody to recognise which key is in
88
+ * there without being handed it.
89
+ */
90
+ export function akismetPanel(dataDir) {
91
+ const stored = readAkismetKey(dataDir);
92
+ if (stored === undefined) {
93
+ return {
94
+ akismetUrl: AKISMET_PATH,
95
+ akismetFields: AKISMET_FIELDS,
96
+ akismetRemove: AKISMET_REMOVE,
97
+ akismetPresent: false,
98
+ akismetState: 'none',
99
+ akismetHint: 'Not connected: no key, so no comment is sent to Akismet.',
100
+ };
101
+ }
102
+ return {
103
+ akismetUrl: AKISMET_PATH,
104
+ akismetFields: AKISMET_FIELDS,
105
+ akismetRemove: AKISMET_REMOVE,
106
+ akismetPresent: true,
107
+ akismetState: stored.status,
108
+ akismetKeyHint: `…${stored.key.slice(-4)}`,
109
+ akismetCheckedAt: stored.checkedAt,
110
+ akismetHint: stored.status === 'valid'
111
+ ? 'Connected. Every comment and every incoming webmention is checked.'
112
+ : stored.status === 'invalid'
113
+ ? 'Akismet does not recognise this key, so nothing it says is believed and every comment queues as it would without one.'
114
+ : 'Akismet could not be reached the last time this key was checked. Save it again to try.',
115
+ };
116
+ }
117
+ //# sourceMappingURL=settings-discussion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-discussion.js","sourceRoot":"","sources":["../../src/admin/settings-discussion.ts"],"names":[],"mappings":"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"}