matrix-nodejs-homeserver 0.2.0 → 0.3.1
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 +29 -7
- package/dist/api/account.js +385 -351
- package/dist/api/admin.js +76 -60
- package/dist/api/appservice.js +37 -25
- package/dist/api/backup.js +73 -62
- package/dist/api/federation.js +172 -138
- package/dist/api/filters.js +4 -3
- package/dist/api/legacy.js +91 -78
- package/dist/api/media.js +70 -54
- package/dist/api/misc.js +46 -37
- package/dist/api/preview.js +4 -3
- package/dist/api/profile.js +108 -97
- package/dist/api/push.js +114 -99
- package/dist/api/relationships.js +64 -58
- package/dist/api/rooms.js +703 -580
- package/dist/api/rtc.d.ts +0 -1
- package/dist/api/rtc.js +48 -34
- package/dist/api/search.js +133 -127
- package/dist/api/slidingsync.js +41 -31
- package/dist/api/spaces.js +82 -77
- package/dist/api/sync.js +59 -50
- package/dist/api/threadsubs.js +72 -61
- package/dist/api/threepid.js +99 -66
- package/dist/api/uia.js +17 -16
- package/dist/api/user.js +221 -178
- package/dist/core/admin.d.ts +0 -1
- package/dist/core/admin.js +6 -5
- package/dist/core/adminroom.js +9 -8
- package/dist/core/appservices.d.ts +2 -1
- package/dist/core/appservices.js +5 -4
- package/dist/core/audit.d.ts +0 -1
- package/dist/core/authrules.js +26 -25
- package/dist/core/delayed.js +2 -1
- package/dist/core/events.js +11 -10
- package/dist/core/invitefilter.js +2 -1
- package/dist/core/keys.js +2 -1
- package/dist/core/m.d.ts +209 -0
- package/dist/core/m.js +182 -0
- package/dist/core/partialstate.js +2 -1
- package/dist/core/policy.js +4 -3
- package/dist/core/push.d.ts +0 -1
- package/dist/core/push.js +12 -11
- package/dist/core/pushrules.js +36 -35
- package/dist/core/rooms.js +76 -74
- package/dist/core/stateres.js +7 -6
- package/dist/federation/client.js +2 -1
- package/dist/federation/index.d.ts +1 -1
- package/dist/federation/index.js +30 -29
- package/dist/homeserver.d.ts +2 -1
- package/dist/homeserver.js +1 -0
- package/dist/http/handler.js +2 -23
- package/dist/http/input.js +2 -2
- package/dist/http/procedure.js +25 -0
- package/dist/http/router.d.ts +9 -26
- package/dist/http/router.js +10 -30
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/vendor/zod/LICENSE +21 -0
- package/dist/vendor/zod/v4/classic/errors.js +54 -0
- package/dist/vendor/zod/v4/classic/parse.js +17 -0
- package/dist/vendor/zod/v4/classic/schemas.js +865 -0
- package/dist/vendor/zod/v4/core/api.js +512 -0
- package/dist/vendor/zod/v4/core/checks.js +300 -0
- package/dist/vendor/zod/v4/core/core.js +109 -0
- package/dist/vendor/zod/v4/core/doc.js +35 -0
- package/dist/vendor/zod/v4/core/errors.js +118 -0
- package/dist/vendor/zod/v4/core/json-schema-processors.js +428 -0
- package/dist/vendor/zod/v4/core/memoizer.js +255 -0
- package/dist/vendor/zod/v4/core/parse.js +206 -0
- package/dist/vendor/zod/v4/core/regexes.js +73 -0
- package/dist/vendor/zod/v4/core/registries.js +48 -0
- package/dist/vendor/zod/v4/core/schemas.js +1378 -0
- package/dist/vendor/zod/v4/core/to-json-schema.js +448 -0
- package/dist/vendor/zod/v4/core/util.js +537 -0
- package/dist/vendor/zod/v4/core/versions.js +8 -0
- package/dist/vendor/zod/v4/locales/en.js +110 -0
- package/package.json +3 -5
- package/dist/core/pushrules.d.ts +0 -1
package/dist/api/legacy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { toClientEvent } from "../core/events.js";
|
|
2
2
|
import { errors } from "../core/errors.js";
|
|
3
3
|
import { isValidRoomId } from "../core/ids.js";
|
|
4
|
+
import { procedure } from "../http/procedure.js";
|
|
4
5
|
import { paginate, visibleState } from "./rooms.js";
|
|
5
6
|
//#region src/api/legacy.ts
|
|
6
7
|
const viewerOf = (s) => ({
|
|
@@ -83,88 +84,100 @@ async function eventsSince(hs, s, roomIds, from, limit) {
|
|
|
83
84
|
return all.sort((a, b) => a.stream - b.stream).slice(0, limit);
|
|
84
85
|
}
|
|
85
86
|
function registerLegacyRoutes(r) {
|
|
86
|
-
r.client("GET", "/initialSync",
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
87
|
+
r.client("GET", "/initialSync", procedure({
|
|
88
|
+
auth: "user",
|
|
89
|
+
handler: async (ctx) => {
|
|
90
|
+
const s = ctx.session;
|
|
91
|
+
const hs = ctx.hs;
|
|
92
|
+
const limit = Math.min(Math.max(Number.parseInt(ctx.query.get("limit") ?? "10", 10) || 10, 0), 100);
|
|
93
|
+
const memberships = [
|
|
94
|
+
"join",
|
|
95
|
+
"invite",
|
|
96
|
+
...ctx.query.get("archived") === "true" ? ["leave", "ban"] : []
|
|
97
|
+
];
|
|
98
|
+
const rooms = [];
|
|
99
|
+
for (const membership of memberships) for (const roomId of await hs.rooms.roomsForUser(s.userId, membership)) {
|
|
100
|
+
if (membership === "invite") {
|
|
101
|
+
const invite = await hs.rooms.membershipEvent(roomId, s.userId);
|
|
102
|
+
rooms.push({
|
|
103
|
+
room_id: roomId,
|
|
104
|
+
membership,
|
|
105
|
+
...invite ? { invite: hs.rooms.formatEvent(invite, viewerOf(s)) } : {}
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
rooms.push(await roomInfo(hs, s, roomId, limit));
|
|
111
|
+
} catch {}
|
|
105
112
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
const account = await hs.db.findMany("account_data", { where: [{
|
|
114
|
+
field: "user_id",
|
|
115
|
+
value: s.userId
|
|
116
|
+
}, {
|
|
117
|
+
field: "room_id",
|
|
118
|
+
value: ""
|
|
119
|
+
}] });
|
|
120
|
+
return {
|
|
121
|
+
end: `s${await hs.streams.position()}`,
|
|
122
|
+
rooms,
|
|
123
|
+
presence: [],
|
|
124
|
+
account_data: account.map((a) => ({
|
|
125
|
+
type: a.type,
|
|
126
|
+
content: a.content
|
|
127
|
+
}))
|
|
128
|
+
};
|
|
109
129
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const end = events.length ? events[events.length - 1].stream : Math.max(from, await hs.streams.position());
|
|
159
|
-
return {
|
|
160
|
-
start: `s${from}`,
|
|
161
|
-
end: `s${end}`,
|
|
162
|
-
chunk: events.map((e) => hs.rooms.formatEvent(e, viewerOf(s), { includeRoomId: true }))
|
|
163
|
-
};
|
|
130
|
+
}));
|
|
131
|
+
r.client("GET", "/rooms/:roomId/initialSync", procedure({
|
|
132
|
+
auth: "user",
|
|
133
|
+
handler: async (ctx) => {
|
|
134
|
+
const s = ctx.session;
|
|
135
|
+
if (!isValidRoomId(ctx.params.roomId)) throw errors.invalidParam("Invalid room ID");
|
|
136
|
+
const limit = Math.min(Math.max(Number.parseInt(ctx.query.get("limit") ?? "10", 10) || 10, 0), 100);
|
|
137
|
+
return roomInfo(ctx.hs, s, ctx.params.roomId, limit);
|
|
138
|
+
}
|
|
139
|
+
}));
|
|
140
|
+
r.client("GET", "/events/:eventId", procedure({
|
|
141
|
+
auth: "user",
|
|
142
|
+
handler: async (ctx) => {
|
|
143
|
+
const s = ctx.session;
|
|
144
|
+
const ev = await ctx.hs.rooms.getEvent(ctx.params.eventId);
|
|
145
|
+
if (!ev || !(await ctx.hs.rooms.filterVisible(s.userId, ev.pdu.room_id, [ev])).length) throw errors.notFound("Event not found");
|
|
146
|
+
return ctx.hs.rooms.formatEvent(ev, viewerOf(s), { includeRoomId: true });
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
149
|
+
r.client("GET", "/events", procedure({
|
|
150
|
+
auth: "user",
|
|
151
|
+
handler: async (ctx) => {
|
|
152
|
+
const s = ctx.session;
|
|
153
|
+
const hs = ctx.hs;
|
|
154
|
+
const now = await hs.streams.position();
|
|
155
|
+
const from = parseStreamToken(ctx.query.get("from"), now);
|
|
156
|
+
const timeout = Math.min(Math.max(Number(ctx.query.get("timeout") ?? 3e4) || 0, 0), hs.config.maxSyncTimeoutMs);
|
|
157
|
+
const peekRoom = ctx.query.get("room_id");
|
|
158
|
+
let roomIds;
|
|
159
|
+
if (peekRoom !== null) {
|
|
160
|
+
if (!isValidRoomId(peekRoom)) throw errors.invalidParam("Invalid room ID");
|
|
161
|
+
const { joined, worldReadable } = await hs.rooms.canPeek(peekRoom, s.userId);
|
|
162
|
+
if (!joined && !worldReadable) throw errors.forbidden("You cannot peek into this room");
|
|
163
|
+
roomIds = [peekRoom];
|
|
164
|
+
} else roomIds = await hs.rooms.roomsForUser(s.userId);
|
|
165
|
+
const deadline = Date.now() + timeout;
|
|
166
|
+
for (;;) {
|
|
167
|
+
const events = await eventsSince(hs, s, roomIds, from, 100);
|
|
168
|
+
const remaining = deadline - Date.now();
|
|
169
|
+
if (events.length || remaining <= 0 || ctx.request.signal.aborted) {
|
|
170
|
+
const end = events.length ? events[events.length - 1].stream : Math.max(from, await hs.streams.position());
|
|
171
|
+
return {
|
|
172
|
+
start: `s${from}`,
|
|
173
|
+
end: `s${end}`,
|
|
174
|
+
chunk: events.map((e) => hs.rooms.formatEvent(e, viewerOf(s), { includeRoomId: true }))
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
await Promise.race([hs.notifier.wait(s.userId, remaining, ctx.request.signal), new Promise((resolve) => setTimeout(resolve, Math.min(remaining, peekRoom !== null ? 1e3 : remaining)).unref?.())]);
|
|
164
178
|
}
|
|
165
|
-
await Promise.race([hs.notifier.wait(s.userId, remaining, ctx.request.signal), new Promise((resolve) => setTimeout(resolve, Math.min(remaining, peekRoom !== null ? 1e3 : remaining)).unref?.())]);
|
|
166
179
|
}
|
|
167
|
-
});
|
|
180
|
+
}));
|
|
168
181
|
}
|
|
169
182
|
//#endregion
|
|
170
183
|
export { registerLegacyRoutes };
|
package/dist/api/media.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { randomString } from "../core/crypto.js";
|
|
2
|
+
import { M } from "../core/m.js";
|
|
2
3
|
import { MatrixError, errors } from "../core/errors.js";
|
|
4
|
+
import { procedure } from "../http/procedure.js";
|
|
3
5
|
//#region src/api/media.ts
|
|
4
6
|
const DEFAULT_MAX_UPLOAD = 52428800;
|
|
5
7
|
const INLINE_TYPES = /^(image\/(png|jpeg|gif|webp|avif|apng)|video\/(mp4|webm|ogg)|audio\/(mpeg|ogg|wav|webm|mp4|aac|flac)|text\/plain)$/;
|
|
@@ -183,19 +185,25 @@ async function thumbnail(ctx) {
|
|
|
183
185
|
});
|
|
184
186
|
}
|
|
185
187
|
function registerMediaRoutes(r) {
|
|
186
|
-
const config = (ctx) => ({
|
|
187
|
-
r.get("/_matrix/media/v3/config",
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
});
|
|
188
|
+
const config = (ctx) => ({ [M.UPLOAD.SIZE]: maxUpload(ctx.hs) });
|
|
189
|
+
r.get("/_matrix/media/v3/config", procedure({
|
|
190
|
+
auth: "user",
|
|
191
|
+
handler: async (ctx) => {
|
|
192
|
+
return config(ctx);
|
|
193
|
+
}
|
|
194
|
+
}));
|
|
195
|
+
r.get("/_matrix/media/r0/config", procedure({
|
|
196
|
+
auth: "user",
|
|
197
|
+
handler: async (ctx) => {
|
|
198
|
+
return config(ctx);
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
201
|
+
r.get("/_matrix/client/v1/media/config", procedure({
|
|
202
|
+
auth: "user",
|
|
203
|
+
handler: async (ctx) => {
|
|
204
|
+
return config(ctx);
|
|
205
|
+
}
|
|
206
|
+
}));
|
|
199
207
|
const upload = async (ctx) => {
|
|
200
208
|
await ctx.auth();
|
|
201
209
|
await ctx.rateLimit("upload");
|
|
@@ -203,53 +211,61 @@ function registerMediaRoutes(r) {
|
|
|
203
211
|
await storeUpload(ctx, mediaId);
|
|
204
212
|
return { content_uri: `mxc://${ctx.hs.serverName}/${mediaId}` };
|
|
205
213
|
};
|
|
206
|
-
r.post("/_matrix/media/v3/upload", upload);
|
|
207
|
-
r.post("/_matrix/media/r0/upload", upload);
|
|
208
|
-
r.post("/_matrix/media/v1/create",
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
214
|
+
r.post("/_matrix/media/v3/upload", procedure({ handler: upload }));
|
|
215
|
+
r.post("/_matrix/media/r0/upload", procedure({ handler: upload }));
|
|
216
|
+
r.post("/_matrix/media/v1/create", procedure({
|
|
217
|
+
auth: "user",
|
|
218
|
+
handler: async (ctx) => {
|
|
219
|
+
const s = ctx.session;
|
|
220
|
+
const mediaId = randomString(24);
|
|
221
|
+
await ctx.hs.db.create("media", {
|
|
222
|
+
media_id: mediaId,
|
|
223
|
+
content_type: null,
|
|
224
|
+
filename: null,
|
|
225
|
+
size: 0,
|
|
226
|
+
uploader: s.userId,
|
|
227
|
+
created_ts: Date.now(),
|
|
228
|
+
pending: true
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
content_uri: `mxc://${ctx.hs.serverName}/${mediaId}`,
|
|
232
|
+
unused_expires_at: Date.now() + 864e5
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}));
|
|
236
|
+
r.put("/_matrix/media/v3/upload/:serverName/:mediaId", procedure({
|
|
237
|
+
auth: "user",
|
|
238
|
+
handler: async (ctx) => {
|
|
239
|
+
const s = ctx.session;
|
|
240
|
+
if (ctx.params.serverName !== ctx.hs.serverName) throw errors.notFound("Unknown media");
|
|
241
|
+
const meta = await ctx.hs.db.findOne("media", [{
|
|
242
|
+
field: "media_id",
|
|
243
|
+
value: ctx.params.mediaId
|
|
244
|
+
}]);
|
|
245
|
+
if (!meta) throw errors.notFound("Unknown media");
|
|
246
|
+
if (meta.uploader !== s.userId) throw errors.forbidden("You did not create this media ID");
|
|
247
|
+
if (!meta.pending) throw new MatrixError(409, "M_CANNOT_OVERWRITE_MEDIA", "Media already uploaded");
|
|
248
|
+
await storeUpload(ctx, ctx.params.mediaId);
|
|
249
|
+
return {};
|
|
250
|
+
}
|
|
251
|
+
}));
|
|
238
252
|
for (const prefix of ["/_matrix/media/v3", "/_matrix/media/r0"]) {
|
|
239
|
-
r.get(`${prefix}/download/:serverName/:mediaId`, download);
|
|
240
|
-
r.get(`${prefix}/download/:serverName/:mediaId/:fileName`, download);
|
|
241
|
-
r.get(`${prefix}/thumbnail/:serverName/:mediaId`, thumbnail);
|
|
253
|
+
r.get(`${prefix}/download/:serverName/:mediaId`, procedure({ handler: download }));
|
|
254
|
+
r.get(`${prefix}/download/:serverName/:mediaId/:fileName`, procedure({ handler: download }));
|
|
255
|
+
r.get(`${prefix}/thumbnail/:serverName/:mediaId`, procedure({ handler: thumbnail }));
|
|
242
256
|
}
|
|
243
257
|
const authed = async (ctx) => {
|
|
244
258
|
await ctx.auth();
|
|
245
259
|
return download(ctx);
|
|
246
260
|
};
|
|
247
|
-
r.get("/_matrix/client/v1/media/download/:serverName/:mediaId", authed);
|
|
248
|
-
r.get("/_matrix/client/v1/media/download/:serverName/:mediaId/:fileName", authed);
|
|
249
|
-
r.get("/_matrix/client/v1/media/thumbnail/:serverName/:mediaId",
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
261
|
+
r.get("/_matrix/client/v1/media/download/:serverName/:mediaId", procedure({ handler: authed }));
|
|
262
|
+
r.get("/_matrix/client/v1/media/download/:serverName/:mediaId/:fileName", procedure({ handler: authed }));
|
|
263
|
+
r.get("/_matrix/client/v1/media/thumbnail/:serverName/:mediaId", procedure({
|
|
264
|
+
auth: "user",
|
|
265
|
+
handler: async (ctx) => {
|
|
266
|
+
return thumbnail(ctx);
|
|
267
|
+
}
|
|
268
|
+
}));
|
|
253
269
|
}
|
|
254
270
|
//#endregion
|
|
255
271
|
export { registerMediaRoutes };
|
package/dist/api/misc.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { signJson } from "../core/crypto.js";
|
|
2
|
+
import { M, UNSTABLE } from "../core/m.js";
|
|
2
3
|
import { SUPPORTED_ROOM_VERSIONS } from "../core/events.js";
|
|
3
4
|
import { errors } from "../core/errors.js";
|
|
5
|
+
import { procedure } from "../http/procedure.js";
|
|
4
6
|
import { wellKnown } from "./account.js";
|
|
5
7
|
import { canonicalJsonResponse } from "../http/handler.js";
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
6
9
|
//#region src/api/misc.ts
|
|
10
|
+
const PACKAGE = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8"));
|
|
7
11
|
const SPEC_VERSIONS = [
|
|
8
12
|
"r0.0.1",
|
|
9
13
|
"r0.1.0",
|
|
@@ -26,48 +30,50 @@ const SPEC_VERSIONS = [
|
|
|
26
30
|
"v1.11"
|
|
27
31
|
];
|
|
28
32
|
function registerMiscRoutes(r) {
|
|
29
|
-
r.get("/_matrix/client/versions", () => ({
|
|
33
|
+
r.get("/_matrix/client/versions", procedure({ handler: () => ({
|
|
30
34
|
versions: SPEC_VERSIONS,
|
|
31
35
|
unstable_features: {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
[UNSTABLE.ORG.MATRIX.SIMPLIFIED_MSC3575]: true,
|
|
37
|
+
[UNSTABLE.ORG.MATRIX.MSC3916.STABLE]: true,
|
|
38
|
+
[UNSTABLE.ORG.MATRIX.MSC4140._]: true,
|
|
39
|
+
[UNSTABLE.ORG.MATRIX.MSC4143._]: true,
|
|
40
|
+
[UNSTABLE.ORG.MATRIX.MSC4222._]: true,
|
|
41
|
+
[UNSTABLE.ORG.MATRIX.MSC4306]: true
|
|
38
42
|
}
|
|
39
|
-
}));
|
|
40
|
-
r.get("/.well-known/matrix/client", (ctx) => {
|
|
43
|
+
}) }));
|
|
44
|
+
r.get("/.well-known/matrix/client", procedure({ handler: (ctx) => {
|
|
41
45
|
const wk = wellKnown(ctx.hs);
|
|
42
46
|
if (!wk) throw errors.notFound("No well-known configured");
|
|
43
47
|
return wk;
|
|
44
|
-
});
|
|
45
|
-
r.get("/.well-known/matrix/server", (ctx) => {
|
|
48
|
+
} }));
|
|
49
|
+
r.get("/.well-known/matrix/server", procedure({ handler: (ctx) => {
|
|
46
50
|
if (!ctx.hs.config.federationAddress) throw errors.notFound("No delegation configured");
|
|
47
|
-
return {
|
|
48
|
-
});
|
|
49
|
-
r.get("/.well-known/matrix/support", (ctx) => {
|
|
51
|
+
return { [M.SERVER]: ctx.hs.config.federationAddress };
|
|
52
|
+
} }));
|
|
53
|
+
r.get("/.well-known/matrix/support", procedure({ handler: (ctx) => {
|
|
50
54
|
if (!ctx.hs.config.support) throw errors.notFound("No support information configured");
|
|
51
55
|
return ctx.hs.config.support;
|
|
52
|
-
});
|
|
53
|
-
r.client("GET", "/capabilities",
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
} }));
|
|
57
|
+
r.client("GET", "/capabilities", procedure({
|
|
58
|
+
auth: "user",
|
|
59
|
+
handler: async (ctx) => {
|
|
60
|
+
const available = {};
|
|
61
|
+
for (const v of SUPPORTED_ROOM_VERSIONS) available[v] = /^\d+$/.test(v) ? "stable" : "unstable";
|
|
62
|
+
return { capabilities: {
|
|
63
|
+
[M.CHANGE_PASSWORD]: { enabled: !ctx.hs.oauth && ctx.hs.userAuth.passwordLoginEnabled },
|
|
64
|
+
[M.ROOM_VERSIONS]: {
|
|
65
|
+
default: ctx.hs.config.defaultRoomVersion,
|
|
66
|
+
available
|
|
67
|
+
},
|
|
68
|
+
[M.SET_DISPLAYNAME]: { enabled: true },
|
|
69
|
+
[M.SET_AVATAR_URL]: { enabled: true },
|
|
70
|
+
[M.PROFILE_FIELDS]: { enabled: true },
|
|
71
|
+
[M.THREEPID_CHANGES]: { enabled: ctx.hs.threepids.enabled && !ctx.hs.oauth },
|
|
72
|
+
[M.GET_LOGIN_TOKEN]: { enabled: ctx.hs.config.loginViaExistingSession && !ctx.hs.oauth }
|
|
73
|
+
} };
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
76
|
+
r.get("/_matrix/key/v2/server", procedure({ handler: (ctx) => {
|
|
71
77
|
const hs = ctx.hs;
|
|
72
78
|
const key = hs.signingKey;
|
|
73
79
|
return canonicalJsonResponse(signJson({
|
|
@@ -76,10 +82,13 @@ function registerMiscRoutes(r) {
|
|
|
76
82
|
verify_keys: { [`ed25519:${key.keyId}`]: { key: key.publicKeyBase64 } },
|
|
77
83
|
old_verify_keys: {}
|
|
78
84
|
}, hs.serverName, key));
|
|
79
|
-
});
|
|
80
|
-
r.get("/_matrix/federation/v1/version", (
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
} }));
|
|
86
|
+
r.get("/_matrix/federation/v1/version", procedure({ handler: (ctx) => {
|
|
87
|
+
if (!ctx.hs.federation.enabled) throw errors.unrecognized("Federation is disabled");
|
|
88
|
+
return { server: {
|
|
89
|
+
name: PACKAGE.name,
|
|
90
|
+
version: PACKAGE.version
|
|
91
|
+
} };
|
|
83
92
|
} }));
|
|
84
93
|
}
|
|
85
94
|
//#endregion
|
package/dist/api/preview.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomString } from "../core/crypto.js";
|
|
2
2
|
import { errors } from "../core/errors.js";
|
|
3
|
+
import { procedure } from "../http/procedure.js";
|
|
3
4
|
import { lookup } from "node:dns/promises";
|
|
4
5
|
import { BlockList, isIP } from "node:net";
|
|
5
6
|
//#region src/api/preview.ts
|
|
@@ -192,9 +193,9 @@ function registerPreviewRoutes(r) {
|
|
|
192
193
|
if (!url) throw errors.missingParam("Missing url");
|
|
193
194
|
return preview(ctx.hs, url);
|
|
194
195
|
};
|
|
195
|
-
r.get("/_matrix/media/v3/preview_url", handler);
|
|
196
|
-
r.get("/_matrix/media/r0/preview_url", handler);
|
|
197
|
-
r.get("/_matrix/client/v1/media/preview_url", handler);
|
|
196
|
+
r.get("/_matrix/media/v3/preview_url", procedure({ handler }));
|
|
197
|
+
r.get("/_matrix/media/r0/preview_url", procedure({ handler }));
|
|
198
|
+
r.get("/_matrix/client/v1/media/preview_url", procedure({ handler }));
|
|
198
199
|
}
|
|
199
200
|
//#endregion
|
|
200
201
|
export { imageSize, parseOpenGraph, registerPreviewRoutes };
|