This commit is contained in:
Madeline
2023-08-14 13:51:11 +10:00
parent c560d58f68
commit a4db643bea
9 changed files with 93 additions and 89 deletions

BIN
package-lock.json generated

Binary file not shown.

View File

@@ -57,6 +57,7 @@
"@types/ws": "^8.5.5",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"activitypub-types": "^1.0.1",
"eslint": "^8.46.0",
"express": "^4.18.2",
"husky": "^8.0.3",
@@ -123,4 +124,4 @@
"nodemailer-sendgrid-transport": "github:Maria-Golomb/nodemailer-sendgrid-transport",
"sqlite3": "^5.1.6"
}
}
}

View File

@@ -1,5 +1,5 @@
import { route } from "@spacebar/api";
import { Channel, Config } from "@spacebar/util";
import { Channel } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
@@ -10,21 +10,5 @@ router.get("/", route({}), async (req: Request, res: Response) => {
const channel = await Channel.findOneOrFail({ where: { id } });
const { webDomain } = Config.get().federation;
return res.json({
"@context": "https://www.w3.org/ns/activitystreams",
type: "Group",
id: `https://${webDomain}/fed/channel/${channel.id}`,
name: channel.name,
preferredUsername: channel.name,
summary: channel.topic,
icon: undefined,
inbox: `https://${webDomain}/fed/channel/${channel.id}/inbox`,
outbox: `https://${webDomain}/fed/channel/${channel.id}/outbox`,
followers: `https://${webDomain}/fed/channel/${channel.id}/followers`,
following: `https://${webDomain}/fed/channel/${channel.id}/following`,
linked: `https://${webDomain}/fed/channel/${channel.id}/likeds`,
});
return res.json(channel.toAP());
});

View File

@@ -1,5 +1,6 @@
import { route } from "@spacebar/api";
import { Config, Message } from "@spacebar/util";
import { APAnnounce } from "activitypub-types";
import { Request, Response, Router } from "express";
const router = Router();
@@ -14,37 +15,15 @@ router.get("/", route({}), async (req: Request, res: Response) => {
});
const { webDomain } = Config.get().federation;
return res.json({
const ret: APAnnounce = {
"@context": "https://www.w3.org/ns/activitystreams",
id: "Announce",
actor: `https://${webDomain}/fed/user/${message.author!.id}`,
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://www.w3.org/ns/activitystreams#Public"],
cc: [
message.author?.id
? `https://${webDomain}/fed/users/${message.author.id}`
: undefined,
`https://${webDomain}/fed/channel/${channel_id}/followers`,
],
object: {
id: `https://${webDomain}/fed/channel/${channel_id}/mesages/${message.id}`,
type: "Note",
summary: null,
inReplyTo: undefined, // TODO
published: message.timestamp,
url: `https://app.spacebar.chat/channels${
message.guild?.id ? `/${message.guild.id}` : ""
}/${channel_id}/${message.id}`,
attributedTo: `https://${webDomain}/fed/user/${message.author!.id}`,
to: ["https://www.w3.org/ns/activitystreams#Public"],
cc: [
message.author?.id
? `https://${webDomain}/fed/users/${message.author.id}`
: undefined,
`https://${webDomain}/fed/channel/${channel_id}/followers`,
],
sensitive: false,
content: message.content,
},
});
to: `https://${webDomain}/fed/channel/${message.channel_id}`,
object: message.toAP(),
};
return res.json(ret);
});

View File

@@ -1,5 +1,6 @@
import { route } from "@spacebar/api";
import { Config, Message, Snowflake } from "@spacebar/util";
import { APOrderedCollection } from "activitypub-types";
import { Router } from "express";
import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm";
@@ -14,14 +15,16 @@ router.get("/", route({}), async (req, res) => {
const { webDomain } = Config.get().federation;
if (!page)
return res.json({
if (!page) {
const ret: APOrderedCollection = {
"@context": "https://www.w3.org/ns/activitystreams",
id: `https://${webDomain}/fed/users/${channel_id}/outbox`,
type: "OrderedCollection",
first: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true`,
last: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true&min_id=0`,
});
};
return res.json(ret);
}
const after = min_id ? `${min_id}` : undefined;
const before = max_id ? `${max_id}` : undefined;
@@ -47,30 +50,26 @@ router.get("/", route({}), async (req, res) => {
const messages = await Message.find(query);
return res.json({
// move this to like, Channel.createAPMessages or smth
const apMessages = messages.map((message) => ({
"@context": "https://www.w3.org/ns/activitystreams",
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",
next: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&max_id=${
messages[0]?.id || "0"
}`,
prev: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&max_id=${
messages[messages.length - 1]?.id || "0"
}`,
partOf: `https://${webDomain}/fed/channel/${channel_id}/outbox`,
orderedItems: messages.map((message) => ({
id: `https://${webDomain}/fed/channel/${channel_id}/message/${message.id}`,
type: "Announce", // hmm
actor: `https://${webDomain}/fed/channel/${channel_id}`,
published: message.timestamp,
to: ["https://www.w3.org/ns/activitystreams#Public"],
cc: [
message.author?.id
? `https://${webDomain}/fed/users/${message.author.id}`
: undefined,
`https://${webDomain}/fed/channel/${channel_id}/followers`,
],
object: `https://${webDomain}/fed/channel/${channel_id}/messages/${message.id}`,
})),
});
first: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true`,
last: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true&min_id=0`,
totalItems: await Message.count({ where: { channel_id } }),
items: apMessages,
};
return res.json(ret);
});

View File

@@ -1,5 +1,6 @@
import { route } from "@spacebar/api";
import { Config, User } from "@spacebar/util";
import { APPerson } from "activitypub-types";
import { Request, Response, Router } from "express";
const router = Router();
@@ -12,7 +13,7 @@ router.get("/:id", route({}), async (req: Request, res: Response) => {
const { webDomain } = Config.get().federation;
return res.json({
const ret: APPerson = {
"@context": "https://www.w3.org/ns/activitystreams",
type: "Person",
id: `https://${webDomain}/fed/user/${user.id}`,
@@ -31,6 +32,8 @@ router.get("/:id", route({}), async (req: Request, res: Response) => {
outbox: `https://${webDomain}/fed/user/${user.id}/outbox`,
followers: `https://${webDomain}/fed/user/${user.id}/followers`,
following: `https://${webDomain}/fed/user/${user.id}/following`,
linked: `https://${webDomain}/fed/user/${user.id}/likeds`,
});
liked: `https://${webDomain}/fed/user/${user.id}/likeds`,
};
return res.json(ret);
});

View File

@@ -16,6 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { APActor } from "activitypub-types";
import { HTTPError } from "lambert-server";
import {
Column,
@@ -28,6 +29,7 @@ import {
import { DmChannelDTO } from "../dtos";
import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces";
import {
Config,
InvisibleCharacters,
Snowflake,
containsAll,
@@ -482,6 +484,26 @@ export class Channel extends BaseClass {
owner_id: this.owner_id || undefined,
};
}
toAP(): APActor {
const { webDomain } = Config.get().federation;
return {
"@context": "https://www.w3.org/ns/activitystreams",
type: "Group",
id: `https://${webDomain}/fed/channel/${this.id}`,
name: this.name,
preferredUsername: this.name,
summary: this.topic,
icon: undefined,
inbox: `https://${webDomain}/fed/channel/${this.id}/inbox`,
outbox: `https://${webDomain}/fed/channel/${this.id}/outbox`,
followers: `https://${webDomain}/fed/channel/${this.id}/followers`,
following: `https://${webDomain}/fed/channel/${this.id}/following`,
liked: `https://${webDomain}/fed/channel/${this.id}/likeds`,
};
}
}
export interface ChannelPermissionOverwrite {

View File

@@ -16,12 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { User } from "./User";
import { Member } from "./Member";
import { Role } from "./Role";
import { Channel } from "./Channel";
import { InteractionType } from "../interfaces/Interaction";
import { Application } from "./Application";
import type { APNote } from "activitypub-types";
import {
Column,
CreateDateColumn,
@@ -34,11 +29,18 @@ import {
OneToMany,
RelationId,
} from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { Webhook } from "./Webhook";
import { Sticker } from "./Sticker";
import { Config } from "..";
import { InteractionType } from "../interfaces/Interaction";
import { Application } from "./Application";
import { Attachment } from "./Attachment";
import { BaseClass } from "./BaseClass";
import { Channel } from "./Channel";
import { Guild } from "./Guild";
import { Member } from "./Member";
import { Role } from "./Role";
import { Sticker } from "./Sticker";
import { User } from "./User";
import { Webhook } from "./Webhook";
export enum MessageType {
DEFAULT = 0,
@@ -240,6 +242,20 @@ export class Message extends BaseClass {
components: this.components ?? undefined,
};
}
toAP(): APNote {
const { webDomain } = Config.get().federation;
return {
id: `https://${webDomain}/fed/channel/${this.channel_id}/messages/${this.id}`,
type: "Note",
published: this.timestamp,
url: `https://${webDomain}/fed/channel/${this.channel_id}/messages/${this.id}`,
attributedTo: `https://${webDomain}/fed/user/${this.author_id}`,
to: `https://${webDomain}/fed/channel/${this.channel_id}`,
content: this.content,
};
}
}
export interface MessageComponent {