@geekity/cms 0.35.0 → 0.37.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 (269) hide show
  1. package/admin/components/blocks.njk +250 -0
  2. package/admin/components/card.njk +4 -2
  3. package/admin/components/job-status.njk +15 -10
  4. package/admin/components/upload.njk +26 -0
  5. package/admin/pages/comments/all.njk +1 -1
  6. package/admin/pages/dashboard/home.njk +33 -32
  7. package/admin/pages/documents/editor.njk +34 -19
  8. package/admin/pages/federation/followers.njk +3 -2
  9. package/admin/pages/media/file.njk +5 -4
  10. package/admin/pages/media/library.njk +7 -3
  11. package/admin/pages/plugins/screen.njk +5 -35
  12. package/admin/pages/settings/general.njk +4 -1
  13. package/admin/pages/tools/export.njk +54 -51
  14. package/admin/pages/tools/maintenance.njk +2 -1
  15. package/admin/pages/users/edit.njk +3 -0
  16. package/admin/src/admin.css +1 -0
  17. package/admin/static/admin.css +374 -0
  18. package/admin/static/job-status.js +158 -0
  19. package/admin/static/upload-drop.js +225 -0
  20. package/dist/admin/blocks.d.ts +133 -0
  21. package/dist/admin/blocks.d.ts.map +1 -0
  22. package/dist/admin/blocks.js +454 -0
  23. package/dist/admin/blocks.js.map +1 -0
  24. package/dist/admin/core-widgets.d.ts +3 -0
  25. package/dist/admin/core-widgets.d.ts.map +1 -0
  26. package/dist/admin/core-widgets.js +17 -0
  27. package/dist/admin/core-widgets.js.map +1 -0
  28. package/dist/admin/documents.d.ts.map +1 -1
  29. package/dist/admin/documents.js +0 -2
  30. package/dist/admin/documents.js.map +1 -1
  31. package/dist/admin/engagement.d.ts +16 -0
  32. package/dist/admin/engagement.d.ts.map +1 -0
  33. package/dist/admin/engagement.js +38 -0
  34. package/dist/admin/engagement.js.map +1 -0
  35. package/dist/admin/federation.d.ts +2 -0
  36. package/dist/admin/federation.d.ts.map +1 -1
  37. package/dist/admin/federation.js +2 -1
  38. package/dist/admin/federation.js.map +1 -1
  39. package/dist/admin/formatting.d.ts +1 -0
  40. package/dist/admin/formatting.d.ts.map +1 -1
  41. package/dist/admin/formatting.js +18 -0
  42. package/dist/admin/formatting.js.map +1 -1
  43. package/dist/admin/index.d.ts +2 -2
  44. package/dist/admin/index.d.ts.map +1 -1
  45. package/dist/admin/index.js +2 -2
  46. package/dist/admin/index.js.map +1 -1
  47. package/dist/admin/job-status.d.ts +1 -0
  48. package/dist/admin/job-status.d.ts.map +1 -1
  49. package/dist/admin/job-status.js +1 -0
  50. package/dist/admin/job-status.js.map +1 -1
  51. package/dist/admin/media.d.ts +6 -9
  52. package/dist/admin/media.d.ts.map +1 -1
  53. package/dist/admin/media.js +85 -27
  54. package/dist/admin/media.js.map +1 -1
  55. package/dist/admin/posts-by-path.d.ts +11 -0
  56. package/dist/admin/posts-by-path.d.ts.map +1 -0
  57. package/dist/admin/posts-by-path.js +59 -0
  58. package/dist/admin/posts-by-path.js.map +1 -0
  59. package/dist/admin/routes.d.ts +0 -2
  60. package/dist/admin/routes.d.ts.map +1 -1
  61. package/dist/admin/routes.js +24 -12
  62. package/dist/admin/routes.js.map +1 -1
  63. package/dist/admin/templates.d.ts.map +1 -1
  64. package/dist/admin/templates.js +2 -0
  65. package/dist/admin/templates.js.map +1 -1
  66. package/dist/admin/tools.js +1 -1
  67. package/dist/admin/tools.js.map +1 -1
  68. package/dist/admin/uploads.d.ts +2 -1
  69. package/dist/admin/uploads.d.ts.map +1 -1
  70. package/dist/admin/uploads.js +5 -2
  71. package/dist/admin/uploads.js.map +1 -1
  72. package/dist/admin/widget-fediverse.d.ts +3 -0
  73. package/dist/admin/widget-fediverse.d.ts.map +1 -0
  74. package/dist/admin/widget-fediverse.js +49 -0
  75. package/dist/admin/widget-fediverse.js.map +1 -0
  76. package/dist/admin/widget-followers.d.ts +3 -0
  77. package/dist/admin/widget-followers.d.ts.map +1 -0
  78. package/dist/admin/widget-followers.js +37 -0
  79. package/dist/admin/widget-followers.js.map +1 -0
  80. package/dist/admin/widget-health.d.ts +3 -0
  81. package/dist/admin/widget-health.d.ts.map +1 -0
  82. package/dist/admin/widget-health.js +103 -0
  83. package/dist/admin/widget-health.js.map +1 -0
  84. package/dist/admin/widget-interactions.d.ts +4 -0
  85. package/dist/admin/widget-interactions.d.ts.map +1 -0
  86. package/dist/admin/widget-interactions.js +99 -0
  87. package/dist/admin/widget-interactions.js.map +1 -0
  88. package/dist/admin/widget-posting.d.ts +3 -0
  89. package/dist/admin/widget-posting.d.ts.map +1 -0
  90. package/dist/admin/widget-posting.js +111 -0
  91. package/dist/admin/widget-posting.js.map +1 -0
  92. package/dist/admin/widget-scheduled.d.ts +4 -0
  93. package/dist/admin/widget-scheduled.d.ts.map +1 -0
  94. package/dist/admin/widget-scheduled.js +30 -0
  95. package/dist/admin/widget-scheduled.js.map +1 -0
  96. package/dist/admin/widget-top-posts.d.ts +4 -0
  97. package/dist/admin/widget-top-posts.d.ts.map +1 -0
  98. package/dist/admin/widget-top-posts.js +55 -0
  99. package/dist/admin/widget-top-posts.js.map +1 -0
  100. package/dist/admin/widgets.d.ts +35 -0
  101. package/dist/admin/widgets.d.ts.map +1 -0
  102. package/dist/admin/widgets.js +103 -0
  103. package/dist/admin/widgets.js.map +1 -0
  104. package/dist/cms/app.d.ts.map +1 -1
  105. package/dist/cms/app.js +2 -1
  106. package/dist/cms/app.js.map +1 -1
  107. package/dist/cms/boot.d.ts.map +1 -1
  108. package/dist/cms/boot.js +3 -2
  109. package/dist/cms/boot.js.map +1 -1
  110. package/dist/cms/services.d.ts.map +1 -1
  111. package/dist/cms/services.js +19 -0
  112. package/dist/cms/services.js.map +1 -1
  113. package/dist/content/alt-text.d.ts +1 -0
  114. package/dist/content/alt-text.d.ts.map +1 -1
  115. package/dist/content/alt-text.js +26 -1
  116. package/dist/content/alt-text.js.map +1 -1
  117. package/dist/content/sqlite/catalog.d.ts.map +1 -1
  118. package/dist/content/sqlite/catalog.js +15 -2
  119. package/dist/content/sqlite/catalog.js.map +1 -1
  120. package/dist/content/store.d.ts +10 -0
  121. package/dist/content/store.d.ts.map +1 -1
  122. package/dist/content/store.js.map +1 -1
  123. package/dist/content/write.d.ts.map +1 -1
  124. package/dist/content/write.js +3 -1
  125. package/dist/content/write.js.map +1 -1
  126. package/dist/federation/backfill.d.ts +1 -1
  127. package/dist/federation/backfill.d.ts.map +1 -1
  128. package/dist/federation/backfill.js +5 -1
  129. package/dist/federation/backfill.js.map +1 -1
  130. package/dist/federation/follower-history.d.ts +16 -0
  131. package/dist/federation/follower-history.d.ts.map +1 -0
  132. package/dist/federation/follower-history.js +61 -0
  133. package/dist/federation/follower-history.js.map +1 -0
  134. package/dist/federation/inbox.d.ts.map +1 -1
  135. package/dist/federation/inbox.js +2 -1
  136. package/dist/federation/inbox.js.map +1 -1
  137. package/dist/federation/records.d.ts +1 -0
  138. package/dist/federation/records.d.ts.map +1 -1
  139. package/dist/federation/records.js +24 -6
  140. package/dist/federation/records.js.map +1 -1
  141. package/dist/files/data-files.d.ts +1 -0
  142. package/dist/files/data-files.d.ts.map +1 -1
  143. package/dist/files/data-files.js +6 -0
  144. package/dist/files/data-files.js.map +1 -1
  145. package/dist/jobs/queue.d.ts.map +1 -1
  146. package/dist/jobs/queue.js +5 -0
  147. package/dist/jobs/queue.js.map +1 -1
  148. package/dist/jobs/types.d.ts +7 -0
  149. package/dist/jobs/types.d.ts.map +1 -1
  150. package/dist/jobs/types.js.map +1 -1
  151. package/dist/media/library.d.ts +9 -0
  152. package/dist/media/library.d.ts.map +1 -1
  153. package/dist/media/library.js +25 -1
  154. package/dist/media/library.js.map +1 -1
  155. package/dist/plugin.d.ts +275 -21
  156. package/dist/plugin.d.ts.map +1 -1
  157. package/dist/plugin.js +9 -8
  158. package/dist/plugin.js.map +1 -1
  159. package/dist/plugins/fetch.d.ts +0 -5
  160. package/dist/plugins/fetch.d.ts.map +1 -1
  161. package/dist/plugins/fetch.js +31 -7
  162. package/dist/plugins/fetch.js.map +1 -1
  163. package/dist/plugins/host-api.d.ts +3 -0
  164. package/dist/plugins/host-api.d.ts.map +1 -0
  165. package/dist/plugins/host-api.js +8 -0
  166. package/dist/plugins/host-api.js.map +1 -0
  167. package/dist/plugins/install.d.ts.map +1 -1
  168. package/dist/plugins/install.js +4 -2
  169. package/dist/plugins/install.js.map +1 -1
  170. package/dist/plugins/page-tags.d.ts +8 -0
  171. package/dist/plugins/page-tags.d.ts.map +1 -0
  172. package/dist/plugins/page-tags.js +73 -0
  173. package/dist/plugins/page-tags.js.map +1 -0
  174. package/dist/plugins/registry.d.ts +4 -1
  175. package/dist/plugins/registry.d.ts.map +1 -1
  176. package/dist/plugins/registry.js +50 -9
  177. package/dist/plugins/registry.js.map +1 -1
  178. package/dist/plugins/site.js +1 -1
  179. package/dist/plugins/site.js.map +1 -1
  180. package/dist/store/admin-store.d.ts +2 -2
  181. package/dist/store/admin-store.d.ts.map +1 -1
  182. package/dist/store/admin-store.js.map +1 -1
  183. package/dist/store/comments.d.ts +7 -0
  184. package/dist/store/comments.d.ts.map +1 -1
  185. package/dist/store/comments.js +21 -0
  186. package/dist/store/comments.js.map +1 -1
  187. package/dist/store/deliveries.d.ts +1 -0
  188. package/dist/store/deliveries.d.ts.map +1 -1
  189. package/dist/store/deliveries.js +6 -0
  190. package/dist/store/deliveries.js.map +1 -1
  191. package/dist/store/inbox.d.ts +16 -0
  192. package/dist/store/inbox.d.ts.map +1 -1
  193. package/dist/store/inbox.js +62 -0
  194. package/dist/store/inbox.js.map +1 -1
  195. package/dist/store/queue-database.d.ts +6 -0
  196. package/dist/store/queue-database.d.ts.map +1 -1
  197. package/dist/store/queue-database.js +16 -1
  198. package/dist/store/queue-database.js.map +1 -1
  199. package/dist/store/webmentions.d.ts +1 -0
  200. package/dist/store/webmentions.d.ts.map +1 -1
  201. package/dist/store/webmentions.js +6 -0
  202. package/dist/store/webmentions.js.map +1 -1
  203. package/dist/web/env.d.ts +3 -0
  204. package/dist/web/env.d.ts.map +1 -1
  205. package/dist/web/feed-item.d.ts +4 -3
  206. package/dist/web/feed-item.d.ts.map +1 -1
  207. package/dist/web/feed-item.js +8 -2
  208. package/dist/web/feed-item.js.map +1 -1
  209. package/dist/web/listing-pages.d.ts.map +1 -1
  210. package/dist/web/listing-pages.js +7 -2
  211. package/dist/web/listing-pages.js.map +1 -1
  212. package/dist/web/page-tags.d.ts +4 -0
  213. package/dist/web/page-tags.d.ts.map +1 -0
  214. package/dist/web/page-tags.js +39 -0
  215. package/dist/web/page-tags.js.map +1 -0
  216. package/dist/web/render.d.ts +2 -0
  217. package/dist/web/render.d.ts.map +1 -1
  218. package/dist/web/render.js +14 -0
  219. package/dist/web/render.js.map +1 -1
  220. package/dist/web/routes.d.ts +2 -1
  221. package/dist/web/routes.d.ts.map +1 -1
  222. package/dist/web/routes.js +3 -1
  223. package/dist/web/routes.js.map +1 -1
  224. package/package.json +6 -1
  225. package/themes/default/layouts/base.njk +6 -4
  226. package/dist/comments/routes.d.ts +0 -65
  227. package/dist/comments/routes.d.ts.map +0 -1
  228. package/dist/comments/routes.js +0 -235
  229. package/dist/comments/routes.js.map +0 -1
  230. package/dist/content/media.d.ts +0 -85
  231. package/dist/content/media.d.ts.map +0 -1
  232. package/dist/content/media.js +0 -237
  233. package/dist/content/media.js.map +0 -1
  234. package/dist/content/read-form.d.ts +0 -31
  235. package/dist/content/read-form.d.ts.map +0 -1
  236. package/dist/content/read-form.js +0 -157
  237. package/dist/content/read-form.js.map +0 -1
  238. package/dist/content/read.d.ts +0 -29
  239. package/dist/content/read.d.ts.map +0 -1
  240. package/dist/content/read.js +0 -82
  241. package/dist/content/read.js.map +0 -1
  242. package/dist/export/export-archives.d.ts +0 -29
  243. package/dist/export/export-archives.d.ts.map +0 -1
  244. package/dist/export/export-archives.js +0 -88
  245. package/dist/export/export-archives.js.map +0 -1
  246. package/dist/federation/mount.d.ts +0 -53
  247. package/dist/federation/mount.d.ts.map +0 -1
  248. package/dist/federation/mount.js +0 -344
  249. package/dist/federation/mount.js.map +0 -1
  250. package/dist/mail/credentials.d.ts +0 -62
  251. package/dist/mail/credentials.d.ts.map +0 -1
  252. package/dist/mail/credentials.js +0 -86
  253. package/dist/mail/credentials.js.map +0 -1
  254. package/dist/site/setting-rows.d.ts +0 -45
  255. package/dist/site/setting-rows.d.ts.map +0 -1
  256. package/dist/site/setting-rows.js +0 -361
  257. package/dist/site/setting-rows.js.map +0 -1
  258. package/dist/site/settings-form.d.ts +0 -30
  259. package/dist/site/settings-form.d.ts.map +0 -1
  260. package/dist/site/settings-form.js +0 -54
  261. package/dist/site/settings-form.js.map +0 -1
  262. package/dist/site/site-json.d.ts +0 -38
  263. package/dist/site/site-json.d.ts.map +0 -1
  264. package/dist/site/site-json.js +0 -69
  265. package/dist/site/site-json.js.map +0 -1
  266. package/dist/webmention/routes.d.ts +0 -37
  267. package/dist/webmention/routes.d.ts.map +0 -1
  268. package/dist/webmention/routes.js +0 -75
  269. package/dist/webmention/routes.js.map +0 -1
@@ -1,88 +0,0 @@
1
- import { readdir, rm, stat } from 'node:fs/promises';
2
- import { EXPORTS, dataPath } from '../files/data-files.js';
3
- /**
4
- * The archives the admin's export job leaves in `data/exports/` for a
5
- * download (decision-55, section 4). Each holds actor keys, password hashes
6
- * and personal data, so only the newest is kept and it goes 24 hours after it
7
- * was written. Its age comes from the time in its name, which the site's
8
- * clock wrote.
9
- */
10
- export const EXPORT_LIFETIME_MS = 24 * 60 * 60 * 1000;
11
- const ARCHIVE = /^geekity-.+-(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z\.tar\.gz$/;
12
- function archiveOf(dataDir, name) {
13
- const match = ARCHIVE.exec(name);
14
- if (match === null)
15
- return undefined;
16
- const [, year, month, day, hour, minute, second] = match;
17
- const writtenAt = new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}Z`);
18
- return {
19
- name,
20
- path: dataPath(dataDir, EXPORTS, name),
21
- writtenAt,
22
- expiresAt: new Date(writtenAt.getTime() + EXPORT_LIFETIME_MS),
23
- };
24
- }
25
- async function namesIn(dataDir) {
26
- try {
27
- return await readdir(dataPath(dataDir, EXPORTS));
28
- }
29
- catch (error) {
30
- if (error.code === 'ENOENT')
31
- return [];
32
- throw error;
33
- }
34
- }
35
- /** Every archive in the folder, newest first. */
36
- async function archives(dataDir) {
37
- return (await namesIn(dataDir))
38
- .flatMap((name) => archiveOf(dataDir, name) ?? [])
39
- .sort((a, b) => b.writtenAt.getTime() - a.writtenAt.getTime());
40
- }
41
- function expired(archive, now) {
42
- return archive.expiresAt.getTime() <= now.getTime();
43
- }
44
- /** Delete the archives 24 hours old or older, and say how many went. */
45
- export async function expireExports(dataDir, now) {
46
- let deleted = 0;
47
- for (const archive of await archives(dataDir)) {
48
- if (expired(archive, now)) {
49
- await rm(archive.path, { force: true });
50
- deleted += 1;
51
- }
52
- }
53
- return deleted;
54
- }
55
- /** The archive a download serves: the newest, unless it has expired. Expired ones are deleted. */
56
- export async function currentExport(dataDir, now) {
57
- await expireExports(dataDir, now);
58
- const [newest] = await archives(dataDir);
59
- if (newest === undefined)
60
- return undefined;
61
- try {
62
- return { ...newest, size: (await stat(newest.path)).size };
63
- }
64
- catch (error) {
65
- if (error.code === 'ENOENT')
66
- return undefined;
67
- throw error;
68
- }
69
- }
70
- /**
71
- * Delete what an export a crash cut off left: everything that is not an
72
- * archive. Only one export job runs at a time, so no other writer's temporary
73
- * file is here.
74
- */
75
- export async function clearUnfinishedExports(dataDir) {
76
- for (const name of await namesIn(dataDir)) {
77
- if (!ARCHIVE.test(name))
78
- await rm(dataPath(dataDir, EXPORTS, name), { recursive: true, force: true });
79
- }
80
- }
81
- /** Empty the folder but for the archive just written. */
82
- export async function keepOnlyExport(dataDir, keep) {
83
- for (const name of await namesIn(dataDir)) {
84
- if (name !== keep)
85
- await rm(dataPath(dataDir, EXPORTS, name), { recursive: true, force: true });
86
- }
87
- }
88
- //# sourceMappingURL=export-archives.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export-archives.js","sourceRoot":"","sources":["../../src/export/export-archives.ts"],"names":[],"mappings":"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"}
@@ -1,53 +0,0 @@
1
- import type { Context, Hono, MiddlewareHandler } from 'hono';
2
- import type { GeekityEnv } from '../web/env.ts';
3
- import type { User } from '../site/users.ts';
4
- import type { FederationContextData, SiteFederation } from './federation.ts';
5
- /**
6
- * Put Fedify in front of the rest of the app.
7
- *
8
- * The middleware only answers the paths Fedify registered — the actor, its
9
- * collections, WebFinger and NodeInfo; everything else falls through to
10
- * `next()` and reaches the admin and the public site as before. That is why it
11
- * is mounted first: the public site claims every unmatched path in its
12
- * not-found handler, so anything registered after it never sees a request.
13
- *
14
- * A post's object is not one of Fedify's paths at all. decision-13 makes a
15
- * post's ActivityStreams id its permalink, so {@link activityStreamsDocument}
16
- * is what serves the `Article`: one URL, answering a browser with the page and
17
- * a peer with the object. The same handler answers at the `activitypub.id` a
18
- * migrated post's file names, and sends a browser from there to the permalink.
19
- *
20
- * The dispatchers are handed the stores off the Hono context rather than
21
- * closing over them, so one federation object could serve more than one CMS
22
- * and so a dispatcher is never reading a store the request did not come with.
23
- */
24
- export declare function mountFederation(app: Hono<GeekityEnv>, federation: SiteFederation, options?: MountFederationOptions): void;
25
- /** What {@link mountFederation} takes beyond the site's own federation. */
26
- export interface MountFederationOptions {
27
- /** The phase plugins answer federation requests in. */
28
- plugins?: MiddlewareHandler<GeekityEnv> | undefined;
29
- }
30
- /** Where WebFinger lives, which is defined on the host rather than under a site. */
31
- export declare const WEBFINGER_PATH = "/.well-known/webfinger";
32
- /** `acct:{username}@{host}`, the handle a person types into a search box. */
33
- export declare function acctOf(username: string, baseUrl: string): string;
34
- /**
35
- * The user a WebFinger `resource` asks about, or `undefined` for one this site
36
- * answers for nobody.
37
- *
38
- * Every spelling of a person resolves, and they are the ones decision-14 lists
39
- * as their aliases: the `acct:` handle, the author archive, `/@{username}` and
40
- * — for somebody who was published elsewhere first — the id they were
41
- * published under. Matching every one of them is what lets a peer that holds
42
- * any one URL for this person find the others, which is the whole job of
43
- * WebFinger, and it is how a server holding only `?author=2` discovers that
44
- * the account it follows is still here.
45
- *
46
- * Both sides of the comparison go through {@link canonicalResource} first, so
47
- * the spellings that differ only in how they were typed are one spelling by
48
- * the time they are matched, and no spelling needs a branch of its own.
49
- */
50
- export declare function webFingerSubject(c: Context<GeekityEnv>, resource: string): User | undefined;
51
- /** What the dispatchers are handed, off the Hono context. */
52
- export declare function contextData(c: Context<GeekityEnv>): FederationContextData;
53
- //# sourceMappingURL=mount.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/federation/mount.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAK7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAQ7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG7E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,UAAU,EAAE,cAAc,EAC1B,OAAO,GAAE,sBAA2B,GACnC,IAAI,CAuGN;AAED,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,uDAAuD;IACvD,OAAO,CAAC,EAAE,iBAAiB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;CACrD;AA+JD,oFAAoF;AACpF,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD,6EAA6E;AAC7E,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAa3F;AAoCD,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,qBAAqB,CAQzE"}
@@ -1,344 +0,0 @@
1
- import { respondWithObject } from '@fedify/fedify';
2
- import { federation as federationMiddleware } from '@fedify/hono';
3
- import { isGone, isFederatedDocument } from '../content/served.js';
4
- import { isTrashedPath } from '../content/store.js';
5
- import { listUsers } from '../site/users.js';
6
- import { absoluteUrl } from '../util/url.js';
7
- import { authorHref, parseAuthorPath, accountOf } from '../content/authors.js';
8
- import { goneDocumentAt, publicDocumentAt } from '../content/permalinks.js';
9
- import { prefersActivityStreams } from '../web/negotiate.js';
10
- import { notFound, requestPath } from '../web/request.js';
11
- import { actorAliases, actorId, userActor } from './actor.js';
12
- import { postObject, postTombstone } from './article.js';
13
- import { handleHref } from './paths.js';
14
- /**
15
- * Put Fedify in front of the rest of the app.
16
- *
17
- * The middleware only answers the paths Fedify registered — the actor, its
18
- * collections, WebFinger and NodeInfo; everything else falls through to
19
- * `next()` and reaches the admin and the public site as before. That is why it
20
- * is mounted first: the public site claims every unmatched path in its
21
- * not-found handler, so anything registered after it never sees a request.
22
- *
23
- * A post's object is not one of Fedify's paths at all. decision-13 makes a
24
- * post's ActivityStreams id its permalink, so {@link activityStreamsDocument}
25
- * is what serves the `Article`: one URL, answering a browser with the page and
26
- * a peer with the object. The same handler answers at the `activitypub.id` a
27
- * migrated post's file names, and sends a browser from there to the permalink.
28
- *
29
- * The dispatchers are handed the stores off the Hono context rather than
30
- * closing over them, so one federation object could serve more than one CMS
31
- * and so a dispatcher is never reading a store the request did not come with.
32
- */
33
- export function mountFederation(app, federation, options = {}) {
34
- // WebFinger is ours rather than Fedify's, and so has to be registered before
35
- // the middleware that would otherwise answer it. Fedify hard-codes the
36
- // `self` link to the dispatcher path and computes `aliases` from the
37
- // resource, neither of which can be added to, so an actor served under the
38
- // id it had elsewhere could never be discovered by it (doc-8). Owning the
39
- // route is a dozen lines and gives complete control of `subject`, `aliases`
40
- // and `links`.
41
- app.get(WEBFINGER_PATH, (c) => {
42
- const resource = c.req.query('resource') ?? '';
43
- const user = webFingerSubject(c, resource);
44
- if (user === undefined)
45
- return c.notFound();
46
- const context = federation.createContext(c.req.raw, contextData(c));
47
- const { baseUrl } = c.var.config;
48
- const aliases = actorAliases(context, user, baseUrl);
49
- return c.json({
50
- subject: acctOf(user.username, c.var.config.baseUrl),
51
- aliases: aliases.map((alias) => alias.href),
52
- links: [
53
- {
54
- rel: 'self',
55
- type: 'application/activity+json',
56
- href: actorId(context, user).href,
57
- },
58
- {
59
- rel: 'http://webfinger.net/rel/profile-page',
60
- type: 'text/html',
61
- href: absoluteUrl(authorHref(user.username), baseUrl),
62
- },
63
- ],
64
- }, 200, {
65
- // The media type RFC 7033 defines, and the header that lets a browser
66
- // application read the answer, which is what every other WebFinger
67
- // server sends.
68
- 'content-type': 'application/jrd+json; charset=utf-8',
69
- 'access-control-allow-origin': '*',
70
- });
71
- });
72
- // `/@ada`, the short URL WordPress publishes beside the author archive and
73
- // the one a person is most likely to type. It is an alias rather than a
74
- // second identity, so it goes where the identity is.
75
- app.get('/:handle{@.+}', async (c, next) => {
76
- // The pattern is a regex rather than `/@:username`, because Hono's path
77
- // parameters are whole segments: the `@` has to be matched inside one.
78
- const handle = (c.req.param('handle') ?? '').slice(1);
79
- // An alias is only an alias of somebody. The route used to send every
80
- // handle to `/author/<whatever was typed>/`, so a profile link with a
81
- // menu item's flag on the end of it — `https://shll.me/@a | me` — landed a
82
- // reader on `/author/a%20%7C%20me/` instead of saying there is no such
83
- // person (TASK-112). Spelled exactly, the way WebFinger matches: `Ada` and
84
- // `ada` are two accounts on a screen that can tell them apart, and only
85
- // one of them exists.
86
- const user = listUsers(c.var.config.dataDir).find((account) => account.username === handle);
87
- // The site's own not-found handler answers rather than a bare 404 here, so
88
- // a handle nobody has gets the theme's 404 page like any other URL that is
89
- // not there.
90
- if (user === undefined)
91
- return await next();
92
- return c.redirect(authorHref(user.username), 301);
93
- });
94
- // `@fedify/hono` types its context as the two properties it actually reads,
95
- // which is looser than Hono's own; the cast is what puts `c.var` back.
96
- const fedify = federationMiddleware(federation, (context) => {
97
- const c = context;
98
- return contextData(c);
99
- });
100
- // The one path where Fedify and the public site both have a claim: a user's
101
- // author archive is their actor id (decision-14), and Fedify answers a bare
102
- // `Accept: application/json` as an ActivityStreams request while doc-3 gives
103
- // that spelling the listing's own JSON. The CMS's rule decides, so a peer
104
- // asking for `activity+json` or `ld+json` gets the actor and everything else
105
- // — a browser, a reader, a feed tool — reaches the archive it asked for.
106
- // Every other Fedify path is left exactly as it was.
107
- const federationGate = async (c, next) => {
108
- const isArchive = parseAuthorPath(requestPath(c)) !== undefined;
109
- if (isArchive && !prefersActivityStreams(c.req.header('accept')))
110
- return await next();
111
- return await fedify(c, next);
112
- };
113
- app.use('*', federationGate);
114
- if (options.plugins !== undefined)
115
- app.use('*', options.plugins);
116
- // Named, and typed as a middleware, so the Hono context arrives with its
117
- // path parameters resolved rather than as `any`.
118
- const activityStreams = async (c, next) => {
119
- const response = (await activityStreamsActor(c, federation)) ?? (await activityStreamsDocument(c, federation));
120
- if (response !== undefined)
121
- return response;
122
- await next();
123
- };
124
- app.use('*', activityStreams);
125
- }
126
- /**
127
- * The person this request is about, when it asks at the id they were published
128
- * under somewhere else: the `Person` for a peer, a redirect to the author
129
- * archive for a browser, and `undefined` for everything else.
130
- *
131
- * The twin of {@link activityStreamsDocument}, and for the same reason
132
- * (decision-14): a stored actor id is identity. A follower's server keys the
133
- * account by the URL it first saw, so that URL has to keep answering with this
134
- * person's actor for as long as the account exists, or every follow out there
135
- * points at nothing.
136
- *
137
- * Fedify cannot serve it — its router matches paths, and a stored id is
138
- * commonly a query string on the site root (doc-8) — so it is served here,
139
- * ahead of the public site, exactly as a post's stored `activitypub.id` is.
140
- */
141
- async function activityStreamsActor(c, federation) {
142
- const user = storedActorAt(c);
143
- if (user === undefined)
144
- return undefined;
145
- if (!prefersActivityStreams(c.req.header('accept'))) {
146
- return c.redirect(authorHref(user.username), 301);
147
- }
148
- const context = federation.createContext(c.req.raw, contextData(c));
149
- const actor = await userActor(context, user, { baseUrl: c.var.config.baseUrl });
150
- return await respondWithObject(actor, { contextLoader: context.contextLoader });
151
- }
152
- /**
153
- * The user whose stored actor id is the URL this request asks for, or
154
- * `undefined`.
155
- *
156
- * Built the way {@link storedObjectAt} builds a post's candidate — the
157
- * request's path and query on the site's base URL, rather than `request.url`,
158
- * which behind a proxy is the internal address — and matched on the whole URL,
159
- * query string and all, which is what decision-14 asks for.
160
- *
161
- * A user whose stored id happens to be their author URL is not one of these:
162
- * the actor dispatcher has already answered for that URL, and answering again
163
- * here would only redirect a browser to where it already is.
164
- */
165
- function storedActorAt(c) {
166
- const { search } = new URL(c.req.url);
167
- const candidate = `${absoluteUrl(requestPath(c), c.var.config.baseUrl)}${search}`;
168
- const user = listUsers(c.var.config.dataDir).find((entry) => entry.actorId === candidate);
169
- if (user === undefined)
170
- return undefined;
171
- if (absoluteUrl(authorHref(user.username), c.var.config.baseUrl) === candidate)
172
- return undefined;
173
- return user;
174
- }
175
- /**
176
- * The post this request is about, when it is about one: the `Article` for a
177
- * peer, a redirect to the permalink for a browser at a stored id, and
178
- * `undefined` for everything else.
179
- *
180
- * Two URLs can name a post. Its permalink always does — that is the whole of
181
- * decision-13, and a peer that dereferences a link somebody shared lands on
182
- * the object rather than on a page it cannot read. The other is the
183
- * `activitypub.id` a migrated post's file carries: the name its followers,
184
- * its replies and, unless it sets a `guid`, its RSS subscribers already hold,
185
- * which has to keep answering or every copy out there points at nothing. A
186
- * browser that follows one of those old links is sent on to the permalink,
187
- * because that is the URL a person should end up at.
188
- *
189
- * Anything else — a browser at a permalink, a `.md` or `.json` request, a
190
- * page, a listing — gets `undefined` and falls through to the public site
191
- * untouched.
192
- */
193
- async function activityStreamsDocument(c, federation) {
194
- const wantsObject = prefersActivityStreams(c.req.header('accept'));
195
- if (wantsObject) {
196
- const atPermalink = publicDocumentAt(c.var.store, requestPath(c));
197
- if (atPermalink !== undefined && isFederatedDocument(atPermalink, c.var.store.now())) {
198
- return await article(c, federation, atPermalink);
199
- }
200
- }
201
- const stored = storedObjectAt(c);
202
- if (wantsObject) {
203
- const trashed = stored ?? goneDocumentAt(c.var.store, requestPath(c));
204
- if (trashed?.type === 'post' && isTrashedPath(trashed.path)) {
205
- return isGone(trashed, c.var.store.now())
206
- ? await tombstone(c, federation, trashed)
207
- : undefined;
208
- }
209
- }
210
- if (stored === undefined)
211
- return undefined;
212
- const now = c.var.store.now();
213
- if (!isFederatedDocument(stored, now) && !isGone(stored, now)) {
214
- return wantsObject ? notFound(c) : undefined;
215
- }
216
- if (wantsObject)
217
- return await article(c, federation, stored);
218
- // A renamed post's old URL is its stored id (decision-20). Once a new
219
- // document takes that URL over, a browser there is reading the new one; the
220
- // id keeps answering peers, who hold it as a name rather than a page.
221
- if (publicDocumentAt(c.var.store, requestPath(c)) !== undefined)
222
- return undefined;
223
- return c.redirect(stored.permalink, 301);
224
- }
225
- /**
226
- * The post whose `activitypub.id` is the URL this request asks for, or
227
- * `undefined`.
228
- *
229
- * The candidate is built the way the ids themselves are — the request's path
230
- * and query on the site's base URL — rather than taken from `request.url`,
231
- * which behind a proxy is the internal address. A post whose stored id is its
232
- * permalink is not one of these: the permalink lookup has already answered for
233
- * it, and answering again here would only invite a redirect to itself.
234
- */
235
- function storedObjectAt(c) {
236
- const { search } = new URL(c.req.url);
237
- const candidate = `${absoluteUrl(requestPath(c), c.var.config.baseUrl)}${search}`;
238
- const document = c.var.store.getByStoredObjectId(candidate);
239
- if (document === undefined || document.type !== 'post')
240
- return undefined;
241
- if (absoluteUrl(document.permalink, c.var.config.baseUrl) === candidate)
242
- return undefined;
243
- return document;
244
- }
245
- /**
246
- * One post as the ActivityStreams response a peer asked for.
247
- *
248
- * The object is built through the same {@link postObject} the outbox uses,
249
- * off a context Fedify makes for this request, so the object a peer fetches
250
- * and the one it is delivered cannot drift apart.
251
- */
252
- async function article(c, federation, document) {
253
- const context = federation.createContext(c.req.raw, contextData(c));
254
- if (listUsers(c.var.config.dataDir).length === 0)
255
- return notFound(c);
256
- return await respondWithObject(postObject(context, document), {
257
- contextLoader: context.contextLoader,
258
- });
259
- }
260
- async function tombstone(c, federation, document) {
261
- const context = federation.createContext(c.req.raw, contextData(c));
262
- const response = await respondWithObject(postTombstone(context, document), {
263
- contextLoader: context.contextLoader,
264
- });
265
- return new Response(response.body, { status: 410, headers: response.headers });
266
- }
267
- /** Where WebFinger lives, which is defined on the host rather than under a site. */
268
- export const WEBFINGER_PATH = '/.well-known/webfinger';
269
- /** `acct:{username}@{host}`, the handle a person types into a search box. */
270
- export function acctOf(username, baseUrl) {
271
- return `acct:${accountOf(username, baseUrl)}`;
272
- }
273
- /**
274
- * The user a WebFinger `resource` asks about, or `undefined` for one this site
275
- * answers for nobody.
276
- *
277
- * Every spelling of a person resolves, and they are the ones decision-14 lists
278
- * as their aliases: the `acct:` handle, the author archive, `/@{username}` and
279
- * — for somebody who was published elsewhere first — the id they were
280
- * published under. Matching every one of them is what lets a peer that holds
281
- * any one URL for this person find the others, which is the whole job of
282
- * WebFinger, and it is how a server holding only `?author=2` discovers that
283
- * the account it follows is still here.
284
- *
285
- * Both sides of the comparison go through {@link canonicalResource} first, so
286
- * the spellings that differ only in how they were typed are one spelling by
287
- * the time they are matched, and no spelling needs a branch of its own.
288
- */
289
- export function webFingerSubject(c, resource) {
290
- const wanted = canonicalResource(resource);
291
- if (wanted === '')
292
- return undefined;
293
- const { baseUrl } = c.var.config;
294
- return listUsers(c.var.config.dataDir).find((user) => [
295
- acctOf(user.username, baseUrl),
296
- absoluteUrl(authorHref(user.username), baseUrl),
297
- absoluteUrl(handleHref(user.username), baseUrl),
298
- ...(user.actorId === undefined ? [] : [user.actorId]),
299
- ].some((spelling) => canonicalResource(spelling) === wanted));
300
- }
301
- /**
302
- * One resource in the spelling every equivalent one reduces to.
303
- *
304
- * A host is case-insensitive — in DNS, in RFC 3986 and in RFC 7033 — so
305
- * `acct:ada@EXAMPLE.COM` names the same person as `acct:ada@example.com` and
306
- * has to find them. A username is not: Geekity compares one case sensitively
307
- * (see {@link User.username}), so the case is left exactly as it was asked
308
- * for and `acct:Ada@example.com` stays somebody this site does not have.
309
- *
310
- * A bare `user@host` is not what RFC 7033 asks for, but it is what enough
311
- * clients send that refusing it would only look like a missing account, and
312
- * the same goes for the leading `@` of `@ada@example.com`, which is how the
313
- * handle is written everywhere a person reads it. Both are spelled back out
314
- * as the `acct:` URI they meant.
315
- */
316
- function canonicalResource(resource) {
317
- const trimmed = resource.trim();
318
- // A URL carries its own rules, and `URL` applies them: the scheme and the
319
- // host come back lower-cased, the path untouched.
320
- if (/^[a-z][a-z\d+.-]*:\/\//i.test(trimmed)) {
321
- try {
322
- return new URL(trimmed).href;
323
- }
324
- catch {
325
- return trimmed;
326
- }
327
- }
328
- const handle = trimmed.replace(/^acct:/i, '').replace(/^@/, '');
329
- const at = handle.lastIndexOf('@');
330
- if (at <= 0)
331
- return handle;
332
- return `acct:${handle.slice(0, at)}@${handle.slice(at + 1).toLowerCase()}`;
333
- }
334
- /** What the dispatchers are handed, off the Hono context. */
335
- export function contextData(c) {
336
- return {
337
- admin: c.var.admin,
338
- store: c.var.store,
339
- config: c.var.config,
340
- actorProfiles: c.var.actorProfiles,
341
- cited: (url) => c.var.replyContexts.read(url),
342
- };
343
- }
344
- //# sourceMappingURL=mount.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/federation/mount.ts"],"names":[],"mappings":"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"}
@@ -1,62 +0,0 @@
1
- /**
2
- * What a site needs to prove it may send: `data/mail.json`.
3
- *
4
- * A credential, not a setting, so it lives where the Akismet key and the
5
- * password hashes live — under `data/` at mode `0600` — and never in
6
- * `content/_data/site.json`, which is public, in git and published with the
7
- * site. Which provider is in use, who mail is from and where a reply goes are
8
- * settings and are in `site.json`; the key and the SMTP password are here.
9
- *
10
- * Read on every send, like the Akismet key, so a credential pasted into the
11
- * settings screen sends the next message and one removed stops sending at
12
- * once, neither of them needing a restart.
13
- */
14
- /** Where the credentials live, under `dataDir`. */
15
- export declare const MAIL_CREDENTIALS_FILE = "mail.json";
16
- /** Brevo's half: one API key. */
17
- export interface BrevoCredential {
18
- /** The account's API key, `xkeysib-…`. */
19
- readonly apiKey: string;
20
- }
21
- /** SMTP's half: the whole connection, because all of it is a credential. */
22
- export interface SmtpCredential {
23
- /** The server's hostname. */
24
- readonly host: string;
25
- /** The port: 587 for submission with STARTTLS, 465 for implicit TLS. */
26
- readonly port: number;
27
- /** Whether the connection is TLS from the first byte, which is port 465. */
28
- readonly secure: boolean;
29
- /** The username. Empty for a server that wants no credentials. */
30
- readonly user: string;
31
- /** The password. */
32
- readonly password: string;
33
- }
34
- /**
35
- * The file's whole contents: at most one entry per provider.
36
- *
37
- * Both may be present at once, and that is deliberate — a site trying SMTP
38
- * after Brevo should be able to switch the `mailProvider` setting back without
39
- * having to paste a key in again.
40
- */
41
- export interface MailCredentials {
42
- /** Brevo's key, when the site has one. */
43
- readonly brevo?: BrevoCredential | undefined;
44
- /** The SMTP connection, when the site has one. */
45
- readonly smtp?: SmtpCredential | undefined;
46
- }
47
- /** Where one site's credential file is. */
48
- export declare function mailCredentialsPath(dataDir: string): string;
49
- /**
50
- * The stored credentials, or an empty object when the site has none.
51
- *
52
- * Read tolerantly and synchronously, like every other file this CMS treats as
53
- * truth: a file that will not parse, or an entry missing the one field that
54
- * makes it usable, is a site with no mail rather than a site that will not
55
- * boot.
56
- */
57
- export declare function readMailCredentials(dataDir: string): MailCredentials;
58
- /** Write the credentials, private to the account the site runs as. */
59
- export declare function writeMailCredentials(dataDir: string, credentials: MailCredentials): Promise<void>;
60
- /** Forget them, which is how a site stops sending mail entirely. */
61
- export declare function removeMailCredentials(dataDir: string): Promise<void>;
62
- //# sourceMappingURL=credentials.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/mail/credentials.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AAEH,mDAAmD;AACnD,eAAO,MAAM,qBAAqB,cAAc,CAAC;AAEjD,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,kDAAkD;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CAC5C;AAED,2CAA2C;AAC3C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAkBpE;AAED,sEAAsE;AACtE,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,eAAe,GAC3B,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,oEAAoE;AACpE,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E"}