Fix failing tests

This commit is contained in:
Jesse Wierzbinski 2023-09-21 15:09:14 -10:00
parent 6d2f9072ac
commit c7743aa154
12 changed files with 245 additions and 200 deletions

View file

@ -1,126 +0,0 @@
import { errorResponse, jsonLdResponse } from "@response";
import { MatchedRoute } from "bun";
import { User } from "~database/entities/User";
import { getHost } from "@config";
import { compact } from "jsonld";
/**
* ActivityPub user actor endpoinmt
*/
export default async (
req: Request,
matchedRoute: MatchedRoute
): Promise<Response> => {
const username = matchedRoute.params.username.split("@")[0];
const user = await User.findOneBy({ username });
if (!user) {
return errorResponse("User not found", 404);
}
return jsonLdResponse(
await compact({
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
toot: "http://joinmastodon.org/ns#",
featured: {
"@id": "toot:featured",
"@type": "@id",
},
featuredTags: {
"@id": "toot:featuredTags",
"@type": "@id",
},
alsoKnownAs: {
"@id": "as:alsoKnownAs",
"@type": "@id",
},
movedTo: {
"@id": "as:movedTo",
"@type": "@id",
},
schema: "http://schema.org#",
PropertyValue: "schema:PropertyValue",
value: "schema:value",
discoverable: "toot:discoverable",
Device: "toot:Device",
Ed25519Signature: "toot:Ed25519Signature",
Ed25519Key: "toot:Ed25519Key",
Curve25519Key: "toot:Curve25519Key",
EncryptedMessage: "toot:EncryptedMessage",
publicKeyBase64: "toot:publicKeyBase64",
deviceId: "toot:deviceId",
claim: {
"@type": "@id",
"@id": "toot:claim",
},
fingerprintKey: {
"@type": "@id",
"@id": "toot:fingerprintKey",
},
identityKey: {
"@type": "@id",
"@id": "toot:identityKey",
},
devices: {
"@type": "@id",
"@id": "toot:devices",
},
messageFranking: "toot:messageFranking",
messageType: "toot:messageType",
cipherText: "toot:cipherText",
suspended: "toot:suspended",
Emoji: "toot:Emoji",
focalPoint: {
"@container": "@list",
"@id": "toot:focalPoint",
},
Hashtag: "as:Hashtag",
},
],
id: `${getHost()}/@${user.username}/actor`,
type: "Person",
preferredUsername: user.username, // TODO: Add user display name
name: user.username,
summary: user.note,
icon: /*{
type: "Image",
url: user.avatar,
mediaType: mimetype
}*/ undefined, // TODO: Add avatar
image: /*{
type: "Image",
url: user.avatar,
mediaType: mimetype
}*/ undefined, // TODO: Add banner
inbox: `${getHost()}/@${user.username}/inbox`,
outbox: `${getHost()}/@${user.username}/outbox`,
followers: `${getHost()}/@${user.username}/followers`,
following: `${getHost()}/@${user.username}/following`,
liked: `${getHost()}/@${user.username}/liked`,
discoverable: true,
alsoKnownAs: [
// TODO: Add accounts from which the user migrated
],
manuallyApprovesFollowers: false, // TODO: Change
publicKey: {
id: `${getHost()}/@${user.username}/actor#main-key`,
owner: `${getHost()}/@${user.username}/actor`,
// TODO: Add user public key
},
tag: [
// TODO: Add emojis here, and hashtags
],
attachment: [
// TODO: Add user attachments (I.E. profile metadata)
],
endpoints: {
sharedInbox: `${getHost()}/inbox`,
},
})
);
};

View file

@ -0,0 +1,137 @@
import { errorResponse, jsonLdResponse } from "@response";
import { MatchedRoute } from "bun";
import { User } from "~database/entities/User";
import { getConfig, getHost } from "@config";
/**
* ActivityPub user actor endpoinmt
*/
export default async (
req: Request,
matchedRoute: MatchedRoute
): Promise<Response> => {
// Check for Accept header
const accept = req.headers.get("Accept");
if (!accept || !accept.includes("application/activity+json")) {
return errorResponse("This endpoint requires an Accept header", 406);
}
const config = getConfig();
const username = matchedRoute.params.username.replace("@", "");
const user = await User.findOneBy({ username });
if (!user) {
return errorResponse("User not found", 404);
}
return jsonLdResponse({
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
toot: "http://joinmastodon.org/ns#",
featured: {
"@id": "toot:featured",
"@type": "@id",
},
featuredTags: {
"@id": "toot:featuredTags",
"@type": "@id",
},
alsoKnownAs: {
"@id": "as:alsoKnownAs",
"@type": "@id",
},
movedTo: {
"@id": "as:movedTo",
"@type": "@id",
},
schema: "http://schema.org#",
PropertyValue: "schema:PropertyValue",
value: "schema:value",
discoverable: "toot:discoverable",
Device: "toot:Device",
Ed25519Signature: "toot:Ed25519Signature",
Ed25519Key: "toot:Ed25519Key",
Curve25519Key: "toot:Curve25519Key",
EncryptedMessage: "toot:EncryptedMessage",
publicKeyBase64: "toot:publicKeyBase64",
deviceId: "toot:deviceId",
claim: {
"@type": "@id",
"@id": "toot:claim",
},
fingerprintKey: {
"@type": "@id",
"@id": "toot:fingerprintKey",
},
identityKey: {
"@type": "@id",
"@id": "toot:identityKey",
},
devices: {
"@type": "@id",
"@id": "toot:devices",
},
messageFranking: "toot:messageFranking",
messageType: "toot:messageType",
cipherText: "toot:cipherText",
suspended: "toot:suspended",
Emoji: "toot:Emoji",
focalPoint: {
"@container": "@list",
"@id": "toot:focalPoint",
},
Hashtag: "as:Hashtag",
},
],
id: `${config.http.base_url}:${config.http.port}/@${user.username}`,
type: "Person",
preferredUsername: user.username, // TODO: Add user display name
name: user.username,
summary: user.note,
icon: {
type: "Image",
url: user.avatar,
mediaType: "image/png", // TODO: Set user avatar mimetype
},
image: {
type: "Image",
url: user.header,
mediaType: "image/png", // TODO: Set user header mimetype
},
inbox: `${config.http.base_url}:${config.http.port}/@${user.username}/inbox`,
outbox: `${config.http.base_url}:${config.http.port}/@${user.username}/outbox`,
followers: `${config.http.base_url}:${config.http.port}/@${user.username}/followers`,
following: `${config.http.base_url}:${config.http.port}/@${user.username}/following`,
liked: `${config.http.base_url}:${config.http.port}/@${user.username}/liked`,
discoverable: true,
alsoKnownAs: [
// TODO: Add accounts from which the user migrated
],
manuallyApprovesFollowers: false, // TODO: Change
publicKey: {
id: `${getHost()}${config.http.base_url}:${config.http.port}/@${
user.username
}/actor#main-key`,
owner: `${config.http.base_url}:${config.http.port}/@${user.username}`,
// Split the public key into PEM format
publicKeyPem: `-----BEGIN PUBLIC KEY-----\n${user.public_key
.match(/.{1,64}/g)
?.join("\n")}\n-----END PUBLIC KEY-----`,
},
tag: [
// TODO: Add emojis here, and hashtags
],
attachment: [
// TODO: Add user attachments (I.E. profile metadata)
],
endpoints: {
sharedInbox: `${config.http.base_url}:${config.http.port}/inbox`,
},
});
};

View file

@ -16,9 +16,14 @@ export default async (
const token = req.headers.get("Authorization")?.split(" ")[1] || null;
const user = await getUserByToken(token);
const foundUser = await RawActor.findOneBy({
id,
});
let foundUser: RawActor | null;
try {
foundUser = await RawActor.findOneBy({
id,
});
} catch (e) {
return errorResponse("Invalid ID", 404);
}
if (!foundUser) return errorResponse("User not found", 404);

View file

@ -46,5 +46,7 @@ export default async (
take: limit ?? 20,
});
return jsonResponse(statuses.map(status => status.toAPI()));
return jsonResponse(
await Promise.all(statuses.map(async status => await status.toAPI()))
);
};

View file

@ -119,10 +119,7 @@ export default async (req: Request): Promise<Response> => {
// user.discoverable = discoverable === "true";
}
return jsonResponse(
{
error: `Not really implemented yet`,
},
501
);
await user.save();
return jsonResponse(await user.toAPI());
};

View file

@ -98,19 +98,17 @@ export default async (req: Request): Promise<Response> => {
}
// Create status
const newStatus = new Status();
newStatus.account = user;
newStatus.application = application;
newStatus.content = status;
newStatus.spoiler_text = spoiler_text || "";
newStatus.sensitive = sensitive || false;
newStatus.visibility = visibility || "public";
newStatus.likes = [];
newStatus.isReblog = false;
const newStatus = await Status.createNew({
account: user,
application,
content: status,
visibility: visibility || "public",
sensitive: sensitive || false,
spoiler_text: spoiler_text || "",
emojis: [],
});
// TODO: add database jobs to deliver the post
await newStatus.save();
return jsonResponse(newStatus);
return jsonResponse(await newStatus.toAPI());
};