mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-22 02:12:40 +01:00
test
This commit is contained in:
parent
9d6a3dc2a7
commit
a40dfcfaef
28
src/activitypub/routes/channel/#channel_id/followers.ts
Normal file
28
src/activitypub/routes/channel/#channel_id/followers.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { route } from "@spacebar/api";
|
||||
import { Config, Member } from "@spacebar/util";
|
||||
import { makeOrderedCollection } from "activitypub/util/OrderedCollection";
|
||||
import { Router } from "express";
|
||||
|
||||
const router = Router();
|
||||
export default router;
|
||||
|
||||
router.get("/", route({}), async (req, res) => {
|
||||
// TODO auth
|
||||
const { channel_id } = req.params;
|
||||
|
||||
const { webDomain } = Config.get().federation;
|
||||
|
||||
const ret = makeOrderedCollection(
|
||||
req,
|
||||
`https://${webDomain}/fed/channels/${channel_id}/followers`,
|
||||
() =>
|
||||
Member.count({
|
||||
where: { guild: { channels: { id: channel_id } } },
|
||||
}),
|
||||
async (before, after) => {
|
||||
return [];
|
||||
},
|
||||
);
|
||||
|
||||
return res.json(ret);
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
import { route } from "@spacebar/api";
|
||||
import { Config, Message, Snowflake } from "@spacebar/util";
|
||||
import { APOrderedCollection } from "activitypub-types";
|
||||
import { makeOrderedCollection } from "activitypub/util/OrderedCollection";
|
||||
import { Router } from "express";
|
||||
import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm";
|
||||
|
||||
@ -15,60 +15,36 @@ router.get("/", route({}), async (req, res) => {
|
||||
|
||||
const { webDomain } = Config.get().federation;
|
||||
|
||||
if (!page) {
|
||||
const ret: APOrderedCollection = {
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
id: `https://${webDomain}/fed/channel/${channel_id}/outbox`,
|
||||
type: "OrderedCollection",
|
||||
first: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
|
||||
last: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&min_id=0`,
|
||||
};
|
||||
return res.json(ret);
|
||||
}
|
||||
const ret = makeOrderedCollection(
|
||||
req,
|
||||
`https://${webDomain}/fed/channels/${channel_id}/outbox`,
|
||||
() => Message.count({ where: { channel_id } }),
|
||||
async (before, after) => {
|
||||
const query: FindManyOptions<Message> & {
|
||||
where: { id?: FindOperator<string> | FindOperator<string>[] };
|
||||
} = {
|
||||
order: { timestamp: "DESC" },
|
||||
take: 20,
|
||||
where: { channel_id: channel_id },
|
||||
relations: ["author"],
|
||||
};
|
||||
|
||||
const after = min_id ? `${min_id}` : undefined;
|
||||
const before = max_id ? `${max_id}` : undefined;
|
||||
if (after) {
|
||||
if (BigInt(after) > BigInt(Snowflake.generate())) return [];
|
||||
query.where.id = MoreThan(after);
|
||||
} else if (before) {
|
||||
if (BigInt(before) > BigInt(Snowflake.generate())) return [];
|
||||
query.where.id = LessThan(before);
|
||||
}
|
||||
|
||||
const query: FindManyOptions<Message> & {
|
||||
where: { id?: FindOperator<string> | FindOperator<string>[] };
|
||||
} = {
|
||||
order: { timestamp: "DESC" },
|
||||
take: 20,
|
||||
where: { channel_id: channel_id },
|
||||
relations: ["author"],
|
||||
};
|
||||
const messages = await Message.find(query);
|
||||
|
||||
if (after) {
|
||||
if (BigInt(after) > BigInt(Snowflake.generate()))
|
||||
return res.status(422);
|
||||
query.where.id = MoreThan(after);
|
||||
} else if (before) {
|
||||
if (BigInt(before) > BigInt(Snowflake.generate()))
|
||||
return res.status(422);
|
||||
query.where.id = LessThan(before);
|
||||
}
|
||||
|
||||
const messages = await Message.find(query);
|
||||
|
||||
// move this to like, Channel.createAPMessages or smth
|
||||
const apMessages = messages.map((message) => ({
|
||||
id: `https://${webDomain}/fed/channel/${message.channel_id}/messages/${message.id}`,
|
||||
type: "Announce",
|
||||
actor: `https://${webDomain}/fed/user/${message.author_id}`,
|
||||
published: message.timestamp,
|
||||
to: `https://${webDomain}/fed/channel/${message.channel_id}`,
|
||||
object: message.toAP(),
|
||||
}));
|
||||
|
||||
const ret: APOrderedCollection = {
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
id: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
|
||||
type: "OrderedCollection",
|
||||
first: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
|
||||
last: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&min_id=0`,
|
||||
totalItems: await Message.count({ where: { channel_id } }),
|
||||
items: apMessages,
|
||||
};
|
||||
return messages.map((x) => ({
|
||||
...x,
|
||||
toAP: () => x.toAnnounceAP(),
|
||||
}));
|
||||
},
|
||||
);
|
||||
|
||||
return res.json(ret);
|
||||
});
|
||||
|
41
src/activitypub/util/OrderedCollection.ts
Normal file
41
src/activitypub/util/OrderedCollection.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { APObject, APOrderedCollection } from "activitypub-types";
|
||||
import { Request } from "express";
|
||||
|
||||
interface ActivityPubable {
|
||||
toAP(): APObject;
|
||||
}
|
||||
|
||||
export const makeOrderedCollection = async <T extends ActivityPubable>(
|
||||
req: Request,
|
||||
id: string,
|
||||
getTotalElements: () => Promise<number>,
|
||||
getElements: (before?: string, after?: string) => Promise<T[]>,
|
||||
): Promise<APOrderedCollection> => {
|
||||
const { page, min_id, max_id } = req.query;
|
||||
|
||||
if (!page)
|
||||
return {
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
id: id,
|
||||
type: "OrderedCollection",
|
||||
first: `${id}page=true`,
|
||||
last: `${id}?page=true&min_id=0`,
|
||||
};
|
||||
|
||||
const after = min_id ? `${min_id}` : undefined;
|
||||
const before = max_id ? `${max_id}` : undefined;
|
||||
|
||||
const elems = await getElements(before, after);
|
||||
|
||||
const items = elems.map((elem) => elem.toAP());
|
||||
|
||||
return {
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
id: `${id}?page=true`,
|
||||
type: "OrderedCollection",
|
||||
first: `${id}?page=true`,
|
||||
last: `${id}?page=true&min_id=0`,
|
||||
totalItems: await getTotalElements(),
|
||||
items: items,
|
||||
};
|
||||
};
|
@ -16,7 +16,7 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type { APNote } from "activitypub-types";
|
||||
import type { APAnnounce, APNote } from "activitypub-types";
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
@ -243,6 +243,19 @@ export class Message extends BaseClass {
|
||||
};
|
||||
}
|
||||
|
||||
toAnnounceAP(): APAnnounce {
|
||||
const { webDomain } = Config.get().federation;
|
||||
|
||||
return {
|
||||
id: `https://${webDomain}/fed/channel/${this.channel_id}/messages/${this.id}`,
|
||||
type: "Announce",
|
||||
actor: `https://${webDomain}/fed/user/${this.author_id}`,
|
||||
published: this.timestamp,
|
||||
to: `https://${webDomain}/fed/channel/${this.channel_id}`,
|
||||
object: this.toAP(),
|
||||
};
|
||||
}
|
||||
|
||||
toAP(): APNote {
|
||||
const { webDomain } = Config.get().federation;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user