@geekity/cms 0.15.0 → 0.16.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.
- package/README.md +107 -0
- package/admin/pages/documents/editor.njk +51 -0
- package/admin/pages/documents/syndication.njk +110 -0
- package/admin/pages/federation/followers.njk +7 -0
- package/admin/static/admin.css +11 -0
- package/dist/admin/documents.d.ts +101 -0
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +199 -67
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/federation.d.ts +15 -0
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +19 -0
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +3 -0
- package/dist/admin/menu.js.map +1 -1
- package/dist/admin/photo-field.d.ts +39 -0
- package/dist/admin/photo-field.d.ts.map +1 -0
- package/dist/admin/photo-field.js +91 -0
- package/dist/admin/photo-field.js.map +1 -0
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +6 -1
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +4 -0
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/syndication-targets.d.ts +57 -0
- package/dist/admin/syndication-targets.d.ts.map +1 -0
- package/dist/admin/syndication-targets.js +266 -0
- package/dist/admin/syndication-targets.js.map +1 -0
- package/dist/admin/templates.d.ts +1 -0
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +1 -0
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/uploads.d.ts +6 -0
- package/dist/admin/uploads.d.ts.map +1 -1
- package/dist/admin/uploads.js +1 -1
- package/dist/admin/uploads.js.map +1 -1
- package/dist/content/citation.d.ts +36 -0
- package/dist/content/citation.d.ts.map +1 -0
- package/dist/content/citation.js +31 -0
- package/dist/content/citation.js.map +1 -0
- package/dist/content/index.d.ts +2 -0
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +1 -0
- package/dist/content/index.js.map +1 -1
- package/dist/content/photo.d.ts +45 -0
- package/dist/content/photo.d.ts.map +1 -0
- package/dist/content/photo.js +55 -0
- package/dist/content/photo.js.map +1 -0
- package/dist/content/post-type.d.ts +20 -8
- package/dist/content/post-type.d.ts.map +1 -1
- package/dist/content/post-type.js +17 -0
- package/dist/content/post-type.js.map +1 -1
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +59 -5
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/citations.d.ts +38 -0
- package/dist/federation/citations.d.ts.map +1 -0
- package/dist/federation/citations.js +98 -0
- package/dist/federation/citations.js.map +1 -0
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +79 -31
- package/dist/federation/delivery.js.map +1 -1
- package/dist/images/alt-text.d.ts +6 -0
- package/dist/images/alt-text.d.ts.map +1 -1
- package/dist/images/alt-text.js +10 -0
- package/dist/images/alt-text.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -1
- package/dist/indieauth/bearer.d.ts +6 -1
- package/dist/indieauth/bearer.d.ts.map +1 -1
- package/dist/indieauth/bearer.js +39 -12
- package/dist/indieauth/bearer.js.map +1 -1
- package/dist/indieauth/discovery.d.ts +9 -4
- package/dist/indieauth/discovery.d.ts.map +1 -1
- package/dist/indieauth/discovery.js +18 -7
- package/dist/indieauth/discovery.js.map +1 -1
- package/dist/micropub/create.d.ts +56 -0
- package/dist/micropub/create.d.ts.map +1 -0
- package/dist/micropub/create.js +200 -0
- package/dist/micropub/create.js.map +1 -0
- package/dist/micropub/endpoint.d.ts +21 -0
- package/dist/micropub/endpoint.d.ts.map +1 -0
- package/dist/micropub/endpoint.js +353 -0
- package/dist/micropub/endpoint.js.map +1 -0
- package/dist/micropub/media.d.ts +14 -0
- package/dist/micropub/media.d.ts.map +1 -0
- package/dist/micropub/media.js +93 -0
- package/dist/micropub/media.js.map +1 -0
- package/dist/micropub/update.d.ts +44 -0
- package/dist/micropub/update.d.ts.map +1 -0
- package/dist/micropub/update.js +133 -0
- package/dist/micropub/update.js.map +1 -0
- package/dist/web/context.d.ts +42 -3
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +41 -1
- package/dist/web/context.js.map +1 -1
- package/dist/web/render.d.ts +15 -0
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +16 -0
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.js +2 -2
- package/dist/webmention/index.d.ts +2 -0
- package/dist/webmention/index.d.ts.map +1 -1
- package/dist/webmention/index.js +1 -0
- package/dist/webmention/index.js.map +1 -1
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +96 -18
- package/dist/webmention/service.js.map +1 -1
- package/dist/webmention/syndication.d.ts +135 -0
- package/dist/webmention/syndication.d.ts.map +1 -0
- package/dist/webmention/syndication.js +337 -0
- package/dist/webmention/syndication.js.map +1 -0
- package/package.json +1 -1
- package/themes/default/README.md +40 -9
- package/themes/default/layouts/post.njk +19 -6
- package/themes/default/partials/citations.njk +17 -0
- package/themes/default/partials/jsonld.njk +12 -1
- package/themes/default/partials/photos.njk +10 -0
- package/themes/default/partials/post-list.njk +7 -0
- package/themes/default/src/style.css +9 -0
- package/themes/default/static/style.css +16 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/micropub/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Hono, MiddlewareHandler } from 'hono';
|
|
2
|
+
import type { BearerEnv } from '../indieauth/bearer.ts';
|
|
3
|
+
import type { GeekityEnv } from '../env.ts';
|
|
4
|
+
import type { Scope } from '../indieauth/request.ts';
|
|
5
|
+
/**
|
|
6
|
+
* The bearer guard for a token bound to this site, the resource its protected
|
|
7
|
+
* resource metadata names, or bound to none, as Micropub clients' tokens are
|
|
8
|
+
* (decision-24), and granted `scope` when one is named. Built per request
|
|
9
|
+
* because the base URL is a setting.
|
|
10
|
+
*/
|
|
11
|
+
export declare function requireSiteToken(scope?: Scope): MiddlewareHandler<BearerEnv>;
|
|
12
|
+
/**
|
|
13
|
+
* The Micropub endpoint: the queries a client asks before it posts (TASK-163)
|
|
14
|
+
* and `q=source` (TASK-167), which any live token of this site's may ask
|
|
15
|
+
* whatever its scopes, and the create (TASK-164), update, delete and undelete
|
|
16
|
+
* (TASK-167), each needing its own scope. A token bound to another resource
|
|
17
|
+
* is refused either way (decision-24). Behind the maintenance gate, like the
|
|
18
|
+
* IndieAuth endpoints beside it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mountMicropub(app: Hono<GeekityEnv>): void;
|
|
21
|
+
//# sourceMappingURL=endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../../src/micropub/endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAe7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAgJrD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAM5E;AAqND;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAkCzD"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { listUsers } from '../admin/accounts.js';
|
|
2
|
+
import { moveDocumentFile, POST_KIND, writeDocument } from '../admin/documents.js';
|
|
3
|
+
import { deleteUpload } from '../admin/media.js';
|
|
4
|
+
import { refusedUpload, storeUpload } from '../admin/uploads.js';
|
|
5
|
+
import { readSiteSettings } from '../admin/settings.js';
|
|
6
|
+
import { isTrashedPath } from '../content/store.js';
|
|
7
|
+
import { insufficientScope, requireBearer } from '../indieauth/bearer.js';
|
|
8
|
+
import { MICROPUB_MEDIA_PATH, MICROPUB_PATH, siteBaseUrl } from '../indieauth/discovery.js';
|
|
9
|
+
import { absoluteUrl } from '../web/negotiate.js';
|
|
10
|
+
import { removeImageVariants } from '../images/variants.js';
|
|
11
|
+
import { UPLOAD_ASSET_PREFIX } from '../web/assets.js';
|
|
12
|
+
import { userForAuthor } from '../web/authors.js';
|
|
13
|
+
import { syndicationTargetsReader } from '../webmention/syndication.js';
|
|
14
|
+
import { createForm, fromForm, fromJson } from './create.js';
|
|
15
|
+
import { parseChanges, sourceProperties, updateForm } from './update.js';
|
|
16
|
+
/**
|
|
17
|
+
* The name a client shows for each post type the site accepts, in the order
|
|
18
|
+
* it offers them. A record, so a new {@link PostType} cannot go unoffered.
|
|
19
|
+
*/
|
|
20
|
+
const POST_TYPE_NAMES = {
|
|
21
|
+
note: 'Note',
|
|
22
|
+
article: 'Article',
|
|
23
|
+
reply: 'Reply',
|
|
24
|
+
photo: 'Photo',
|
|
25
|
+
like: 'Like',
|
|
26
|
+
repost: 'Repost',
|
|
27
|
+
bookmark: 'Bookmark',
|
|
28
|
+
};
|
|
29
|
+
/** Each `q` the endpoint answers. */
|
|
30
|
+
const QUERY_NAMES = ['config', 'syndicate-to', 'category', 'source'];
|
|
31
|
+
/**
|
|
32
|
+
* How the endpoint answers each `q`, or the {@link Refusal} it answers
|
|
33
|
+
* instead.
|
|
34
|
+
*/
|
|
35
|
+
const QUERIES = {
|
|
36
|
+
config: ({ baseUrl, targets }) => ({
|
|
37
|
+
'media-endpoint': `${baseUrl}${MICROPUB_MEDIA_PATH}`,
|
|
38
|
+
'syndicate-to': offered(targets),
|
|
39
|
+
'post-types': Object.entries(POST_TYPE_NAMES).map(([type, name]) => ({ type, name })),
|
|
40
|
+
q: QUERY_NAMES,
|
|
41
|
+
}),
|
|
42
|
+
'syndicate-to': ({ targets }) => ({ 'syndicate-to': offered(targets) }),
|
|
43
|
+
category: ({ store, filter }) => ({ categories: categories(store, filter) }),
|
|
44
|
+
source: ({ baseUrl, targets, properties, post }) => {
|
|
45
|
+
const document = post();
|
|
46
|
+
if (document instanceof Refusal)
|
|
47
|
+
return document;
|
|
48
|
+
const all = sourceProperties(document, { baseUrl, targets });
|
|
49
|
+
// Asked for by name, the answer is the properties alone, as the spec has it.
|
|
50
|
+
if (properties.length === 0)
|
|
51
|
+
return { type: ['h-entry'], properties: all };
|
|
52
|
+
return {
|
|
53
|
+
properties: Object.fromEntries(Object.entries(all).filter(([name]) => properties.includes(name))),
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
/** An error answer: Micropub's `error` code and what went wrong. */
|
|
58
|
+
class Refusal {
|
|
59
|
+
status;
|
|
60
|
+
error;
|
|
61
|
+
description;
|
|
62
|
+
constructor(status, error, description) {
|
|
63
|
+
this.status = status;
|
|
64
|
+
this.error = error;
|
|
65
|
+
this.description = description;
|
|
66
|
+
}
|
|
67
|
+
answer(c) {
|
|
68
|
+
c.header('cache-control', 'no-store');
|
|
69
|
+
return c.json({ error: this.error, error_description: this.description }, this.status);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function invalid(description) {
|
|
73
|
+
return new Refusal(400, 'invalid_request', description);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The post `url` names, when it is one of this site's posts, trashed ones
|
|
77
|
+
* included so they can be undeleted, and `user` may change it. A post its
|
|
78
|
+
* front matter attributes to another user is theirs; one attributed to nobody
|
|
79
|
+
* the site knows is anybody's, as it is in the editor.
|
|
80
|
+
*/
|
|
81
|
+
function postAt(url, site) {
|
|
82
|
+
if (url === undefined || url === '')
|
|
83
|
+
return invalid('A url is required.');
|
|
84
|
+
const root = absoluteUrl('/', site.baseUrl);
|
|
85
|
+
let address;
|
|
86
|
+
try {
|
|
87
|
+
address = new URL(url);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return invalid(`${url} is not a URL.`);
|
|
91
|
+
}
|
|
92
|
+
const document = address.href.startsWith(root)
|
|
93
|
+
? site.store.getByPermalink(`/${address.pathname.slice(new URL(root).pathname.length)}`)
|
|
94
|
+
: undefined;
|
|
95
|
+
if (document?.type !== 'post')
|
|
96
|
+
return invalid(`${url} is not a post on this site.`);
|
|
97
|
+
const author = userForAuthor(site.users, document.author);
|
|
98
|
+
if (author !== undefined && author.id !== site.user.id) {
|
|
99
|
+
return new Refusal(403, 'forbidden', `${url} is not your post.`);
|
|
100
|
+
}
|
|
101
|
+
return document;
|
|
102
|
+
}
|
|
103
|
+
/** The site's targets as a client offers them: a target's id is its uid (decision-26). */
|
|
104
|
+
function offered(targets) {
|
|
105
|
+
return targets.map(({ id, name }) => ({ uid: id, name }));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Every tag and category on a published post, once each, alphabetically
|
|
109
|
+
* whatever the case, keeping those containing `filter` when one is given.
|
|
110
|
+
*/
|
|
111
|
+
function categories(store, filter) {
|
|
112
|
+
const terms = new Set([
|
|
113
|
+
...store.listTags().map(({ tag }) => tag),
|
|
114
|
+
...store.listCategories().map(({ category }) => category),
|
|
115
|
+
]);
|
|
116
|
+
const needle = filter?.toLowerCase() ?? '';
|
|
117
|
+
return [...terms]
|
|
118
|
+
.filter((term) => term.toLowerCase().includes(needle))
|
|
119
|
+
.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
|
|
120
|
+
}
|
|
121
|
+
function isQuery(q) {
|
|
122
|
+
return QUERY_NAMES.includes(q);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The bearer guard for a token bound to this site, the resource its protected
|
|
126
|
+
* resource metadata names, or bound to none, as Micropub clients' tokens are
|
|
127
|
+
* (decision-24), and granted `scope` when one is named. Built per request
|
|
128
|
+
* because the base URL is a setting.
|
|
129
|
+
*/
|
|
130
|
+
export function requireSiteToken(scope) {
|
|
131
|
+
return async (c, next) => await requireBearer({
|
|
132
|
+
audience: { resource: siteBaseUrl(c), acceptsUnbound: true },
|
|
133
|
+
...(scope === undefined ? {} : { scope }),
|
|
134
|
+
})(c, next);
|
|
135
|
+
}
|
|
136
|
+
/** The scope each action needs. */
|
|
137
|
+
const ACTION_SCOPES = {
|
|
138
|
+
create: 'create',
|
|
139
|
+
update: 'update',
|
|
140
|
+
delete: 'delete',
|
|
141
|
+
undelete: 'delete',
|
|
142
|
+
};
|
|
143
|
+
function isAction(action) {
|
|
144
|
+
return typeof action === 'string' && Object.hasOwn(ACTION_SCOPES, action);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The request body as a {@link MicropubPost}, or why it is not one. A form
|
|
148
|
+
* carries a create, a delete or an undelete; an update is JSON only, as the
|
|
149
|
+
* spec has it.
|
|
150
|
+
*/
|
|
151
|
+
async function micropubPost(c) {
|
|
152
|
+
const type = c.req.header('content-type') ?? '';
|
|
153
|
+
if (/^(application\/x-www-form-urlencoded|multipart\/form-data)\b/i.test(type)) {
|
|
154
|
+
const form = await c.req.formData();
|
|
155
|
+
const action = form.get('action');
|
|
156
|
+
if (action === null)
|
|
157
|
+
return { action: 'create', request: fromForm(form) };
|
|
158
|
+
if (action === 'update')
|
|
159
|
+
return invalid('An update is sent as JSON.');
|
|
160
|
+
if (action !== 'delete' && action !== 'undelete')
|
|
161
|
+
return unsupported(action);
|
|
162
|
+
const url = form.get('url');
|
|
163
|
+
return { action, url: typeof url === 'string' ? url : undefined };
|
|
164
|
+
}
|
|
165
|
+
if (/^application\/json\b/i.test(type)) {
|
|
166
|
+
let body;
|
|
167
|
+
try {
|
|
168
|
+
body = await c.req.json();
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return invalid('The request body is not JSON.');
|
|
172
|
+
}
|
|
173
|
+
const fields = typeof body === 'object' && body !== null && !Array.isArray(body)
|
|
174
|
+
? body
|
|
175
|
+
: {};
|
|
176
|
+
const { action, url } = fields;
|
|
177
|
+
if (action === undefined) {
|
|
178
|
+
const request = fromJson(body);
|
|
179
|
+
return 'error' in request ? invalid(request.error) : { action: 'create', request };
|
|
180
|
+
}
|
|
181
|
+
if (!isAction(action) || action === 'create')
|
|
182
|
+
return unsupported(action);
|
|
183
|
+
const named = typeof url === 'string' ? url : undefined;
|
|
184
|
+
if (action !== 'update')
|
|
185
|
+
return { action, url: named };
|
|
186
|
+
const changes = parseChanges(fields);
|
|
187
|
+
return 'error' in changes ? invalid(changes.error) : { action, url: named, changes };
|
|
188
|
+
}
|
|
189
|
+
return invalid('A request is form-encoded, multipart or JSON.');
|
|
190
|
+
}
|
|
191
|
+
function unsupported(action) {
|
|
192
|
+
return invalid(`This endpoint does not support action=${JSON.stringify(action)}.`);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* The create's form with each photo file stored in the media library, the way
|
|
196
|
+
* the media endpoint stores one, and the addresses stored. Nothing is kept
|
|
197
|
+
* when a file is refused.
|
|
198
|
+
*/
|
|
199
|
+
async function storePhotos(created, config) {
|
|
200
|
+
const stored = [];
|
|
201
|
+
const photos = [...created.form.photos];
|
|
202
|
+
for (const { row, file } of created.uploads) {
|
|
203
|
+
const upload = await storeUpload(file, config, { imagesOnly: true });
|
|
204
|
+
if (refusedUpload(upload)) {
|
|
205
|
+
await removeUploads(stored, config);
|
|
206
|
+
return { error: `photo: ${upload.error}` };
|
|
207
|
+
}
|
|
208
|
+
stored.push(upload.url);
|
|
209
|
+
photos[row] = { url: upload.url, alt: photos[row]?.alt ?? '' };
|
|
210
|
+
}
|
|
211
|
+
return { form: { ...created.form, photos }, stored };
|
|
212
|
+
}
|
|
213
|
+
/** Take uploads stored for a create that was then refused back out, variants and all. */
|
|
214
|
+
async function removeUploads(urls, config) {
|
|
215
|
+
for (const url of urls) {
|
|
216
|
+
await deleteUpload({
|
|
217
|
+
contentDir: config.contentDir,
|
|
218
|
+
path: url.slice(UPLOAD_ASSET_PREFIX.length),
|
|
219
|
+
removeDerived: async (source) => {
|
|
220
|
+
await removeImageVariants(config, source);
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** Each action, once its scope has been checked. */
|
|
226
|
+
const ACTIONS = {
|
|
227
|
+
create: async (c, { request }) => {
|
|
228
|
+
const { store, config, announce, bearer } = c.var;
|
|
229
|
+
const timezone = readSiteSettings(config.contentDir).timezone;
|
|
230
|
+
const created = createForm(request, {
|
|
231
|
+
author: bearer.user.username,
|
|
232
|
+
timezone,
|
|
233
|
+
now: store.now(),
|
|
234
|
+
baseUrl: siteBaseUrl(c),
|
|
235
|
+
targets: syndicationTargetsReader(config.contentDir)(),
|
|
236
|
+
});
|
|
237
|
+
if ('errors' in created)
|
|
238
|
+
return invalid(created.errors.join(' ')).answer(c);
|
|
239
|
+
const photos = await storePhotos(created, config);
|
|
240
|
+
if ('error' in photos)
|
|
241
|
+
return invalid(photos.error).answer(c);
|
|
242
|
+
const written = await writeDocument({ store, config, announce, writer: bearer.user.username }, { kind: POST_KIND, document: undefined, ...created, form: photos.form });
|
|
243
|
+
if (written.outcome === 'refused') {
|
|
244
|
+
await removeUploads(photos.stored, config);
|
|
245
|
+
return invalid(written.message).answer(c);
|
|
246
|
+
}
|
|
247
|
+
if (written.outcome === 'conflict')
|
|
248
|
+
throw new Error('A new post has no file to conflict with.');
|
|
249
|
+
c.header('cache-control', 'no-store');
|
|
250
|
+
c.header('location', absoluteUrl(written.saved.permalink, siteBaseUrl(c)));
|
|
251
|
+
return c.body(null, 201);
|
|
252
|
+
},
|
|
253
|
+
// Through the editor's write path with the hash the post was read with, so
|
|
254
|
+
// it is stamped updated, federates an Update and sends webmentions as an
|
|
255
|
+
// editor save does, and an editor holding the older hash sees a conflict.
|
|
256
|
+
update: async (c, { url, changes }) => {
|
|
257
|
+
const document = postFor(c, url);
|
|
258
|
+
if (document instanceof Refusal)
|
|
259
|
+
return document.answer(c);
|
|
260
|
+
const { store, config, announce, bearer } = c.var;
|
|
261
|
+
const updated = updateForm(document, changes, {
|
|
262
|
+
timezone: readSiteSettings(config.contentDir).timezone,
|
|
263
|
+
now: store.now(),
|
|
264
|
+
baseUrl: siteBaseUrl(c),
|
|
265
|
+
targets: syndicationTargetsReader(config.contentDir)(),
|
|
266
|
+
});
|
|
267
|
+
if ('errors' in updated)
|
|
268
|
+
return invalid(updated.errors.join(' ')).answer(c);
|
|
269
|
+
const written = await writeDocument({ store, config, announce, writer: bearer.user.username }, { kind: POST_KIND, document, ...updated });
|
|
270
|
+
if (written.outcome === 'refused')
|
|
271
|
+
return invalid(written.message).answer(c);
|
|
272
|
+
if (written.outcome === 'conflict') {
|
|
273
|
+
return new Refusal(409, 'conflict', `${url ?? ''} changed on disk; read it again.`).answer(c);
|
|
274
|
+
}
|
|
275
|
+
c.header('cache-control', 'no-store');
|
|
276
|
+
if (written.saved.permalink === document.permalink)
|
|
277
|
+
return c.body(null, 204);
|
|
278
|
+
c.header('location', absoluteUrl(written.saved.permalink, siteBaseUrl(c)));
|
|
279
|
+
return c.body(null, 201);
|
|
280
|
+
},
|
|
281
|
+
delete: async (c, { url }) => await moved(c, url, 'trash'),
|
|
282
|
+
undelete: async (c, { url }) => await moved(c, url, 'restore'),
|
|
283
|
+
};
|
|
284
|
+
function postFor(c, url) {
|
|
285
|
+
const { store, config, bearer } = c.var;
|
|
286
|
+
return postAt(url, {
|
|
287
|
+
store,
|
|
288
|
+
baseUrl: siteBaseUrl(c),
|
|
289
|
+
users: listUsers(config.dataDir),
|
|
290
|
+
user: bearer.user,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Delete and undelete: the editor's move into the trash and back out, so the
|
|
295
|
+
* post leaves and rejoins the site, its feeds and search, and federates a
|
|
296
|
+
* Delete, as it does from the editor. A post already where it was asked to go
|
|
297
|
+
* is left there.
|
|
298
|
+
*/
|
|
299
|
+
async function moved(c, url, action) {
|
|
300
|
+
const document = postFor(c, url);
|
|
301
|
+
if (document instanceof Refusal)
|
|
302
|
+
return document.answer(c);
|
|
303
|
+
c.header('cache-control', 'no-store');
|
|
304
|
+
if (isTrashedPath(document.path) === (action === 'trash'))
|
|
305
|
+
return c.body(null, 204);
|
|
306
|
+
const { store, config, announce } = c.var;
|
|
307
|
+
const done = await moveDocumentFile({ store, contentDir: config.contentDir, announce }, document, action);
|
|
308
|
+
if (done === undefined)
|
|
309
|
+
return invalid(`Could not move ${document.path}.`).answer(c);
|
|
310
|
+
return c.body(null, 204);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* The Micropub endpoint: the queries a client asks before it posts (TASK-163)
|
|
314
|
+
* and `q=source` (TASK-167), which any live token of this site's may ask
|
|
315
|
+
* whatever its scopes, and the create (TASK-164), update, delete and undelete
|
|
316
|
+
* (TASK-167), each needing its own scope. A token bound to another resource
|
|
317
|
+
* is refused either way (decision-24). Behind the maintenance gate, like the
|
|
318
|
+
* IndieAuth endpoints beside it.
|
|
319
|
+
*/
|
|
320
|
+
export function mountMicropub(app) {
|
|
321
|
+
app.post(MICROPUB_PATH, requireSiteToken(), async (c) => {
|
|
322
|
+
const post = await micropubPost(c);
|
|
323
|
+
if (post instanceof Refusal)
|
|
324
|
+
return post.answer(c);
|
|
325
|
+
const scope = ACTION_SCOPES[post.action];
|
|
326
|
+
if (!c.var.bearer.token.scopes.includes(scope))
|
|
327
|
+
return insufficientScope(c, scope);
|
|
328
|
+
const handle = ACTIONS[post.action];
|
|
329
|
+
return await handle(c, post);
|
|
330
|
+
});
|
|
331
|
+
app.get(MICROPUB_PATH, requireSiteToken(), (c) => {
|
|
332
|
+
const q = c.req.query('q');
|
|
333
|
+
if (!isQuery(q)) {
|
|
334
|
+
const description = q === undefined || q === ''
|
|
335
|
+
? 'A q parameter is required.'
|
|
336
|
+
: `This endpoint does not answer q=${q}.`;
|
|
337
|
+
return invalid(description).answer(c);
|
|
338
|
+
}
|
|
339
|
+
const answer = QUERIES[q]({
|
|
340
|
+
baseUrl: siteBaseUrl(c),
|
|
341
|
+
store: c.var.store,
|
|
342
|
+
targets: syndicationTargetsReader(c.var.config.contentDir)(),
|
|
343
|
+
filter: c.req.query('filter'),
|
|
344
|
+
properties: c.req.queries('properties[]') ?? c.req.queries('properties') ?? [],
|
|
345
|
+
post: () => postFor(c, c.req.query('url')),
|
|
346
|
+
});
|
|
347
|
+
if (answer instanceof Refusal)
|
|
348
|
+
return answer.answer(c);
|
|
349
|
+
c.header('cache-control', 'no-store');
|
|
350
|
+
return c.json(answer);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../src/micropub/endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Hono } from 'hono';
|
|
2
|
+
import type { GeekityEnv } from '../env.ts';
|
|
3
|
+
/** Each user's most recent upload, relative to `dataDir`. */
|
|
4
|
+
export declare const LAST_UPLOADS_FILE = "micropub-media.json";
|
|
5
|
+
/**
|
|
6
|
+
* The Micropub media endpoint (TASK-165). A `file` part is stored through
|
|
7
|
+
* {@link storeUpload}, the media library's own rules and directory, so a
|
|
8
|
+
* client's photo is a library file like any other with its variants derived
|
|
9
|
+
* (decision-10). Every refusal is Micropub's 400 `invalid_request` rather
|
|
10
|
+
* than the admin's 413 or 415. `q=last` answers the token's user's last
|
|
11
|
+
* upload, which Quill and other clients offer as the photo of the next post.
|
|
12
|
+
*/
|
|
13
|
+
export declare function mountMicropubMedia(app: Hono<GeekityEnv>): void;
|
|
14
|
+
//# sourceMappingURL=media.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/micropub/media.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAW,IAAI,EAAqB,MAAM,MAAM,CAAC;AAW7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAQ5C,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAuDvD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAsC9D"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { resolveUpload } from '../admin/media.js';
|
|
4
|
+
import { largestUploadLimit, refusedUpload, storeUpload, tooLargeMessage, UPLOAD_ENVELOPE_BYTES, UPLOAD_FIELD, } from '../admin/uploads.js';
|
|
5
|
+
import { readFileIfPresentSync, updateFileAtomically } from '../files/atomic.js';
|
|
6
|
+
import { MICROPUB_MEDIA_PATH, siteBaseUrl } from '../indieauth/discovery.js';
|
|
7
|
+
import { UPLOAD_ASSET_PREFIX } from '../web/assets.js';
|
|
8
|
+
import { absoluteUrl } from '../web/negotiate.js';
|
|
9
|
+
import { requireSiteToken } from './endpoint.js';
|
|
10
|
+
/** Each user's most recent upload, relative to `dataDir`. */
|
|
11
|
+
export const LAST_UPLOADS_FILE = 'micropub-media.json';
|
|
12
|
+
function lastUploadsFile(dataDir) {
|
|
13
|
+
return path.join(dataDir, LAST_UPLOADS_FILE);
|
|
14
|
+
}
|
|
15
|
+
function readLastUploads(dataDir) {
|
|
16
|
+
const text = readFileIfPresentSync(lastUploadsFile(dataDir));
|
|
17
|
+
return text === undefined ? { last: {} } : JSON.parse(text);
|
|
18
|
+
}
|
|
19
|
+
async function recordLastUpload(dataDir, userId, url) {
|
|
20
|
+
await updateFileAtomically(lastUploadsFile(dataDir), (current) => {
|
|
21
|
+
const uploads = current === undefined ? { last: {} } : JSON.parse(current);
|
|
22
|
+
return `${JSON.stringify({ last: { ...uploads.last, [String(userId)]: url } }, null, 2)}\n`;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The user's last upload while it is still in the library: a file deleted
|
|
27
|
+
* from the media screen since is no upload to offer.
|
|
28
|
+
*/
|
|
29
|
+
function lastUpload(contentDir, dataDir, userId) {
|
|
30
|
+
const url = readLastUploads(dataDir).last[String(userId)];
|
|
31
|
+
if (url === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
const file = resolveUpload(contentDir, url.slice(UPLOAD_ASSET_PREFIX.length));
|
|
34
|
+
return file !== undefined && existsSync(file) ? url : undefined;
|
|
35
|
+
}
|
|
36
|
+
function invalidRequest(c, description) {
|
|
37
|
+
c.header('cache-control', 'no-store');
|
|
38
|
+
return c.json({ error: 'invalid_request', error_description: description }, 400);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Refuse a body whose declared length is over the upload limit before anything
|
|
42
|
+
* reads it. It runs ahead of the bearer guard because the guard parses a form
|
|
43
|
+
* body for an `access_token`, which reads the whole file, as the admin's
|
|
44
|
+
* `refuseOversizedUpload` explains.
|
|
45
|
+
*/
|
|
46
|
+
const refuseOversizedMedia = async (c, next) => {
|
|
47
|
+
const declared = Number(c.req.header('content-length') ?? '');
|
|
48
|
+
const limit = largestUploadLimit(c.var.config);
|
|
49
|
+
if (Number.isFinite(declared) && declared > limit + UPLOAD_ENVELOPE_BYTES) {
|
|
50
|
+
return invalidRequest(c, tooLargeMessage(limit));
|
|
51
|
+
}
|
|
52
|
+
await next();
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The Micropub media endpoint (TASK-165). A `file` part is stored through
|
|
56
|
+
* {@link storeUpload}, the media library's own rules and directory, so a
|
|
57
|
+
* client's photo is a library file like any other with its variants derived
|
|
58
|
+
* (decision-10). Every refusal is Micropub's 400 `invalid_request` rather
|
|
59
|
+
* than the admin's 413 or 415. `q=last` answers the token's user's last
|
|
60
|
+
* upload, which Quill and other clients offer as the photo of the next post.
|
|
61
|
+
*/
|
|
62
|
+
export function mountMicropubMedia(app) {
|
|
63
|
+
app.post(MICROPUB_MEDIA_PATH, refuseOversizedMedia, requireSiteToken('media'), async (c) => {
|
|
64
|
+
const { config, bearer } = c.var;
|
|
65
|
+
let body;
|
|
66
|
+
try {
|
|
67
|
+
body = await c.req.parseBody();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return invalidRequest(c, 'An upload is a multipart/form-data body with a file part.');
|
|
71
|
+
}
|
|
72
|
+
const stored = await storeUpload(body[UPLOAD_FIELD], config);
|
|
73
|
+
if (refusedUpload(stored))
|
|
74
|
+
return invalidRequest(c, stored.error);
|
|
75
|
+
await recordLastUpload(config.dataDir, bearer.user.id, stored.url);
|
|
76
|
+
c.header('cache-control', 'no-store');
|
|
77
|
+
c.header('location', absoluteUrl(stored.url, siteBaseUrl(c)));
|
|
78
|
+
return c.body(null, 201);
|
|
79
|
+
});
|
|
80
|
+
app.get(MICROPUB_MEDIA_PATH, requireSiteToken(), (c) => {
|
|
81
|
+
const q = c.req.query('q');
|
|
82
|
+
if (q !== 'last') {
|
|
83
|
+
return invalidRequest(c, q === undefined || q === ''
|
|
84
|
+
? 'A q parameter is required.'
|
|
85
|
+
: `This endpoint does not answer q=${q}.`);
|
|
86
|
+
}
|
|
87
|
+
const { config, bearer } = c.var;
|
|
88
|
+
const url = lastUpload(config.contentDir, config.dataDir, bearer.user.id);
|
|
89
|
+
c.header('cache-control', 'no-store');
|
|
90
|
+
return c.json(url === undefined ? {} : { url: absoluteUrl(url, siteBaseUrl(c)) });
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/micropub/media.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EditorForm } from '../admin/documents.ts';
|
|
2
|
+
import type { Document } from '../content/document.ts';
|
|
3
|
+
import type { CreateSite } from './create.ts';
|
|
4
|
+
/**
|
|
5
|
+
* A post's properties as `q=source` answers them: the create mapping
|
|
6
|
+
* (decision-27) read backwards, so a client can send them back as they came.
|
|
7
|
+
* A property the post does not have is left out. `mp-syndicate-to` holds
|
|
8
|
+
* only the targets the site declares, the ones a client can offer; an id the
|
|
9
|
+
* file lists that names none stays in the file, as it does through an editor
|
|
10
|
+
* save.
|
|
11
|
+
*/
|
|
12
|
+
export declare function sourceProperties(document: Document, site: Pick<CreateSite, 'baseUrl' | 'targets'>): Record<string, unknown[]>;
|
|
13
|
+
/**
|
|
14
|
+
* One change an update asks for. A `delete` without values takes the whole
|
|
15
|
+
* property away.
|
|
16
|
+
*/
|
|
17
|
+
export type Change = {
|
|
18
|
+
readonly op: 'replace' | 'add';
|
|
19
|
+
readonly property: string;
|
|
20
|
+
readonly values: readonly unknown[];
|
|
21
|
+
} | {
|
|
22
|
+
readonly op: 'delete';
|
|
23
|
+
readonly property: string;
|
|
24
|
+
readonly values: readonly unknown[] | undefined;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The `replace`, `add` and `delete` of a JSON update as {@link Change}s, in
|
|
28
|
+
* that order, or what is wrong with them.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseChanges(body: Readonly<Record<string, unknown>>): readonly Change[] | {
|
|
31
|
+
readonly error: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The editor form an update leaves the post with: the form the editor would
|
|
35
|
+
* load, with only the fields the changed properties own taken from the create
|
|
36
|
+
* mapping (decision-27), so whatever Micropub cannot see stays as it is.
|
|
37
|
+
*/
|
|
38
|
+
export declare function updateForm(document: Document, changes: readonly Change[], site: Omit<CreateSite, 'author'>): {
|
|
39
|
+
readonly form: EditorForm;
|
|
40
|
+
readonly draft: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
readonly errors: string[];
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/micropub/update.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAuB9C;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAuB3B;AAED;;;GAGG;AACH,MAAM,MAAM,MAAM,GACd;IACE,QAAQ,CAAC,EAAE,EAAE,SAAS,GAAG,KAAK,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;CACrC,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CAAC;CACjD,CAAC;AAEN;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtC,SAAS,MAAM,EAAE,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqBhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAyBxF"}
|