mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 16:38:19 +01:00
Fix failing tests
This commit is contained in:
parent
6d2f9072ac
commit
c7743aa154
|
|
@ -4,6 +4,7 @@ import {
|
|||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
|
|
@ -66,14 +67,44 @@ export class Status extends BaseEntity {
|
|||
application!: Application | null;
|
||||
|
||||
@ManyToMany(() => Emoji, emoji => emoji.id)
|
||||
@JoinTable()
|
||||
emojis!: Emoji[];
|
||||
|
||||
@ManyToMany(() => RawActivity, activity => activity.id, {})
|
||||
@ManyToMany(() => RawActivity, activity => activity.id)
|
||||
@JoinTable()
|
||||
likes!: RawActivity[];
|
||||
|
||||
@ManyToMany(() => RawActivity, activity => activity.id, {})
|
||||
@ManyToMany(() => RawActivity, activity => activity.id)
|
||||
@JoinTable()
|
||||
announces!: RawActivity[];
|
||||
|
||||
static async createNew(data: {
|
||||
account: User;
|
||||
application: Application | null;
|
||||
content: string;
|
||||
visibility: APIStatus["visibility"];
|
||||
sensitive: boolean;
|
||||
spoiler_text: string;
|
||||
emojis: Emoji[];
|
||||
}) {
|
||||
const newStatus = new Status();
|
||||
|
||||
newStatus.account = data.account;
|
||||
newStatus.application = data.application ?? null;
|
||||
newStatus.content = data.content;
|
||||
newStatus.visibility = data.visibility;
|
||||
newStatus.sensitive = data.sensitive;
|
||||
newStatus.spoiler_text = data.spoiler_text;
|
||||
newStatus.emojis = data.emojis;
|
||||
newStatus.likes = [];
|
||||
newStatus.announces = [];
|
||||
newStatus.isReblog = false;
|
||||
newStatus.announces = [];
|
||||
|
||||
await newStatus.save();
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
async toAPI(): Promise<APIStatus> {
|
||||
return {
|
||||
account: await this.account.toAPI(),
|
||||
|
|
@ -84,7 +115,7 @@ export class Status extends BaseEntity {
|
|||
this.emojis.map(async emoji => await emoji.toAPI())
|
||||
),
|
||||
favourited: false,
|
||||
favourites_count: 0,
|
||||
favourites_count: this.likes.length,
|
||||
id: this.id,
|
||||
in_reply_to_account_id: null,
|
||||
in_reply_to_id: null,
|
||||
|
|
@ -96,13 +127,13 @@ export class Status extends BaseEntity {
|
|||
poll: null,
|
||||
reblog: this.isReblog ? (await this.reblog?.toAPI()) ?? null : null,
|
||||
reblogged: false,
|
||||
reblogs_count: 0,
|
||||
reblogs_count: this.announces.length,
|
||||
replies_count: 0,
|
||||
sensitive: false,
|
||||
spoiler_text: "",
|
||||
tags: [],
|
||||
card: null,
|
||||
content: "",
|
||||
content: this.content,
|
||||
uri: `${config.http.base_url}/@${this.account.username}/${this.id}`,
|
||||
url: `${config.http.base_url}/@${this.account.username}/${this.id}`,
|
||||
visibility: "public",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import { APIAccount } from "~types/entities/account";
|
|||
import { RawActor } from "./RawActor";
|
||||
import { APActor } from "activitypub-types";
|
||||
import { RawObject } from "./RawObject";
|
||||
import { Token } from "./Token";
|
||||
import { Status } from "./Status";
|
||||
|
||||
const config = getConfig();
|
||||
|
||||
|
|
@ -132,6 +134,26 @@ export class User extends BaseEntity {
|
|||
return user;
|
||||
}
|
||||
|
||||
async selfDestruct() {
|
||||
// Clean up tokens
|
||||
const tokens = await Token.findBy({
|
||||
user: {
|
||||
id: this.id,
|
||||
},
|
||||
});
|
||||
|
||||
const statuses = await Status.findBy({
|
||||
account: {
|
||||
id: this.id,
|
||||
},
|
||||
});
|
||||
|
||||
// Delete both
|
||||
await Promise.all(tokens.map(async token => await token.remove()));
|
||||
|
||||
await Promise.all(statuses.map(async status => await status.remove()));
|
||||
}
|
||||
|
||||
async updateActor() {
|
||||
// Check if actor exists
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
|
|
@ -218,7 +240,7 @@ export class User extends BaseEntity {
|
|||
avatar_static: "",
|
||||
bot: false,
|
||||
created_at: this.created_at.toISOString(),
|
||||
display_name: "",
|
||||
display_name: this.display_name,
|
||||
followers_count: 0,
|
||||
following_count: 0,
|
||||
group: false,
|
||||
|
|
|
|||
|
|
@ -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`,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
137
server/api/[username]/actor/index.ts
Normal file
137
server/api/[username]/actor/index.ts
Normal 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`,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -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({
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { APActor } from "activitypub-types";
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { AppDataSource } from "~database/datasource";
|
||||
import { RawActivity } from "~database/entities/RawActivity";
|
||||
import { Token } from "~database/entities/Token";
|
||||
import { User } from "~database/entities/User";
|
||||
|
||||
const config = getConfig();
|
||||
|
|
@ -22,10 +21,10 @@ beforeAll(async () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("POST /@test", () => {
|
||||
describe("POST /@test/actor", () => {
|
||||
test("should return a valid ActivityPub Actor when querying an existing user", async () => {
|
||||
const response = await fetch(
|
||||
`${config.http.base_url}:${config.http.port}/@test`,
|
||||
`${config.http.base_url}:${config.http.port}/@test/actor`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
|
|
@ -64,6 +63,9 @@ describe("POST /@test", () => {
|
|||
`${config.http.base_url}:${config.http.port}/@test`
|
||||
);
|
||||
expect((actor as any).publicKey.publicKeyPem).toBeDefined();
|
||||
expect((actor as any).publicKey.publicKeyPem).toMatch(
|
||||
/(-----BEGIN PUBLIC KEY-----(\n|\r|\r\n)([0-9a-zA-Z+/=]{64}(\n|\r|\r\n))*([0-9a-zA-Z+/=]{1,63}(\n|\r|\r\n))?-----END PUBLIC KEY-----)|(-----BEGIN PRIVATE KEY-----(\n|\r|\r\n)([0-9a-zA-Z+/=]{64}(\n|\r|\r\n))*([0-9a-zA-Z+/=]{1,63}(\n|\r|\r\n))?-----END PRIVATE KEY-----)/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -73,13 +75,6 @@ afterAll(async () => {
|
|||
username: "test",
|
||||
});
|
||||
|
||||
// Clean up tokens
|
||||
const tokens = await Token.findBy({
|
||||
user: {
|
||||
username: "test",
|
||||
},
|
||||
});
|
||||
|
||||
const activities = await RawActivity.createQueryBuilder("activity")
|
||||
.where("activity.data->>'actor' = :actor", {
|
||||
actor: `${config.http.base_url}:${config.http.port}/@test`,
|
||||
|
|
@ -97,7 +92,8 @@ afterAll(async () => {
|
|||
})
|
||||
);
|
||||
|
||||
await Promise.all(tokens.map(async token => await token.remove()));
|
||||
|
||||
if (user) await user.remove();
|
||||
if (user) {
|
||||
await user.selfDestruct();
|
||||
await user.remove();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ beforeAll(async () => {
|
|||
token.token_type = TokenType.BEARER;
|
||||
token.user = user;
|
||||
|
||||
await token.save();
|
||||
token = await token.save();
|
||||
});
|
||||
|
||||
describe("POST /api/v1/accounts/:id", () => {
|
||||
test("should return a 404 error when trying to update a non-existent user", async () => {
|
||||
test("should return a 404 error when trying to fetch a non-existent user", async () => {
|
||||
const response = await fetch(
|
||||
`${config.http.base_url}:${config.http.port}/api/v1/accounts/999999`,
|
||||
{
|
||||
|
|
@ -93,26 +93,14 @@ describe("POST /api/v1/statuses", () => {
|
|||
|
||||
expect(status.content).toBe("Hello, world!");
|
||||
expect(status.visibility).toBe("public");
|
||||
expect(status.account.id).toBe(
|
||||
`${config.http.base_url}:${config.http.port}/@test`
|
||||
);
|
||||
expect(status.account.id).toBe(user.id);
|
||||
expect(status.replies_count).toBe(0);
|
||||
expect(status.favourites_count).toBe(0);
|
||||
expect(status.reblogged).toBe(false);
|
||||
expect(status.favourited).toBe(false);
|
||||
expect(status.reblog?.content).toBe("Hello, world!");
|
||||
expect(status.reblog?.visibility).toBe("public");
|
||||
expect(status.reblog?.account.id).toBe(
|
||||
`${config.http.base_url}:${config.http.port}/@test`
|
||||
);
|
||||
expect(status.reblog?.replies_count).toBe(0);
|
||||
expect(status.reblog?.favourites_count).toBe(0);
|
||||
expect(status.reblog?.reblogged).toBe(false);
|
||||
expect(status.reblog?.favourited).toBe(false);
|
||||
expect(status.media_attachments).toEqual([]);
|
||||
expect(status.mentions).toEqual([]);
|
||||
expect(status.tags).toEqual([]);
|
||||
expect(status.application).toBeNull();
|
||||
expect(status.sensitive).toBe(false);
|
||||
expect(status.spoiler_text).toBe("");
|
||||
expect(status.language).toBeNull();
|
||||
|
|
@ -123,17 +111,15 @@ describe("POST /api/v1/statuses", () => {
|
|||
expect(status.emojis).toEqual([]);
|
||||
expect(status.in_reply_to_id).toBeNull();
|
||||
expect(status.in_reply_to_account_id).toBeNull();
|
||||
expect(status.reblog?.in_reply_to_id).toBeNull();
|
||||
expect(status.reblog?.in_reply_to_account_id).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/v1/accounts/update_credentials", () => {
|
||||
describe("PATCH /api/v1/accounts/update_credentials", () => {
|
||||
test("should update the authenticated user's display name", async () => {
|
||||
const response = await fetch(
|
||||
`${config.http.base_url}:${config.http.port}/api/v1/accounts/update_credentials`,
|
||||
{
|
||||
method: "POST",
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -154,18 +140,10 @@ describe("POST /api/v1/accounts/update_credentials", () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// Clean up user
|
||||
const user = await User.findOneBy({
|
||||
username: "test",
|
||||
});
|
||||
|
||||
// Clean up tokens
|
||||
const tokens = await Token.findBy({
|
||||
user: {
|
||||
username: "test",
|
||||
},
|
||||
});
|
||||
|
||||
const activities = await RawActivity.createQueryBuilder("activity")
|
||||
.where("activity.data->>'actor' = :actor", {
|
||||
actor: `${config.http.base_url}:${config.http.port}/@test`,
|
||||
|
|
@ -183,7 +161,8 @@ afterAll(async () => {
|
|||
})
|
||||
);
|
||||
|
||||
await Promise.all(tokens.map(async token => await token.remove()));
|
||||
|
||||
if (user) await user.remove();
|
||||
if (user) {
|
||||
await user.selfDestruct();
|
||||
await user.remove();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@ import { Token } from "~database/entities/Token";
|
|||
export const getUserByToken = async (access_token: string | null) => {
|
||||
if (!access_token) return null;
|
||||
|
||||
const token = await Token.findOneBy({
|
||||
const token = await Token.findOne({
|
||||
where: {
|
||||
access_token,
|
||||
},
|
||||
relations: ["user"],
|
||||
});
|
||||
|
||||
if (!token) return null;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
* @param request The request to parse
|
||||
*/
|
||||
export async function parseRequest<T>(request: Request): Promise<Partial<T>> {
|
||||
const formData = await request.formData();
|
||||
const query = new URL(request.url).searchParams;
|
||||
|
||||
// if request contains a JSON body
|
||||
|
|
@ -16,6 +15,8 @@ export async function parseRequest<T>(request: Request): Promise<Partial<T>> {
|
|||
|
||||
// If request contains FormData
|
||||
if (request.headers.get("Content-Type")?.includes("multipart/form-data")) {
|
||||
const formData = await request.formData();
|
||||
|
||||
if ([...formData.entries()].length > 0) {
|
||||
const data: Record<string, string | File> = {};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue