mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
refactor(database): ♻️ Move Token to its own ORM abstraction, optimize familiar_followers route
This commit is contained in:
parent
962c159ddd
commit
845041e4db
|
|
@ -27,7 +27,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -40,7 +40,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -56,7 +56,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -46,7 +46,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -64,7 +64,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -33,7 +33,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", users[1].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -54,7 +54,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -65,7 +65,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", users[1].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -33,7 +33,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", users[0].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -54,7 +54,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -65,7 +65,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", users[0].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/statuses/${status.id}/favourite`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -46,7 +46,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -64,7 +64,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -33,7 +33,7 @@ describe(meta.route, () => {
|
|||
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -53,7 +53,7 @@ describe(meta.route, () => {
|
|||
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -72,7 +72,7 @@ describe(meta.route, () => {
|
|||
const replyResponse = await fakeRequest("/api/v1/statuses", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Reply",
|
||||
|
|
@ -88,7 +88,7 @@ describe(meta.route, () => {
|
|||
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -108,7 +108,7 @@ describe(meta.route, () => {
|
|||
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -126,7 +126,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -138,7 +138,7 @@ describe(meta.route, () => {
|
|||
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/accounts/${users[0].id}/mute`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
@ -36,7 +36,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -49,7 +49,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -65,7 +65,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
156
api/api/v1/accounts/familiar_followers/index.test.ts
Normal file
156
api/api/v1/accounts/familiar_followers/index.test.ts
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { fakeRequest, getTestUsers } from "~/tests/utils.ts";
|
||||
import { meta } from "./index.ts";
|
||||
|
||||
const { users, tokens, deleteUsers } = await getTestUsers(5);
|
||||
|
||||
beforeAll(async () => {
|
||||
// Create followers relationships
|
||||
const result1 = await fakeRequest(
|
||||
`/api/v1/accounts/${users[1].id}/follow`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result1.status).toBe(200);
|
||||
|
||||
const result2 = await fakeRequest(
|
||||
`/api/v1/accounts/${users[2].id}/follow`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result2.status).toBe(200);
|
||||
|
||||
const result3 = await fakeRequest(
|
||||
`/api/v1/accounts/${users[3].id}/follow`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result3.status).toBe(200);
|
||||
|
||||
const result4 = await fakeRequest(
|
||||
`/api/v1/accounts/${users[2].id}/follow`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result4.status).toBe(200);
|
||||
|
||||
const result5 = await fakeRequest(
|
||||
`/api/v1/accounts/${users[3].id}/follow`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result5.status).toBe(200);
|
||||
|
||||
const result6 = await fakeRequest(
|
||||
`/api/v1/accounts/${users[3].id}/follow`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[2].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result6.status).toBe(200);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
describe(meta.route, () => {
|
||||
test("should return 0 familiar followers", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?id=${users[4].id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const data = await response.json();
|
||||
expect(data.length).toBe(1);
|
||||
expect(data[0].id).toBe(users[4].id);
|
||||
expect(data[0].accounts).toBeArrayOfSize(0);
|
||||
});
|
||||
|
||||
test("should return 1 familiar follower", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?id=${users[2].id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const data = await response.json();
|
||||
expect(data.length).toBe(1);
|
||||
expect(data[0].id).toBe(users[2].id);
|
||||
expect(data[0].accounts[0].id).toBe(users[1].id);
|
||||
});
|
||||
|
||||
test("should return 2 familiar followers", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?id=${users[3].id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const data = await response.json();
|
||||
expect(data.length).toBe(1);
|
||||
expect(data[0].id).toBe(users[3].id);
|
||||
expect(data[0].accounts).toBeArrayOfSize(2);
|
||||
expect(data[0].accounts[0].id).toBe(users[2].id);
|
||||
expect(data[0].accounts[1].id).toBe(users[1].id);
|
||||
});
|
||||
|
||||
test("should work with multiple ids", async () => {
|
||||
const response = await fakeRequest(
|
||||
`${meta.route}?id[]=${users[2].id}&id[]=${users[3].id}&id[]=${users[4].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const data = await response.json();
|
||||
expect(data.length).toBe(3);
|
||||
expect(data[0].id).toBe(users[2].id);
|
||||
expect(data[0].accounts[0].id).toBe(users[1].id);
|
||||
expect(data[1].id).toBe(users[3].id);
|
||||
expect(data[1].accounts[0].id).toBe(users[2].id);
|
||||
expect(data[1].accounts[1].id).toBe(users[1].id);
|
||||
expect(data[2].id).toBe(users[4].id);
|
||||
expect(data[2].accounts).toBeArrayOfSize(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import { apiRoute, applyConfig, auth, qsQuery } from "@/api";
|
||||
import { createRoute } from "@hono/zod-openapi";
|
||||
import { User, db } from "@versia/kit/db";
|
||||
import { RolePermissions, Users } from "@versia/kit/tables";
|
||||
import { type SQL, inArray } from "drizzle-orm";
|
||||
import { RolePermissions, type Users } from "@versia/kit/tables";
|
||||
import { type InferSelectModel, sql } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { ErrorSchema } from "~/types/api";
|
||||
|
||||
|
|
@ -23,7 +23,12 @@ export const meta = applyConfig({
|
|||
|
||||
export const schemas = {
|
||||
query: z.object({
|
||||
id: z.array(z.string().uuid()).min(1).max(10).or(z.string().uuid()),
|
||||
id: z
|
||||
.array(z.string().uuid())
|
||||
.min(1)
|
||||
.max(10)
|
||||
.or(z.string().uuid())
|
||||
.transform((v) => (Array.isArray(v) ? v : [v])),
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
@ -42,7 +47,12 @@ const route = createRoute({
|
|||
description: "Familiar followers",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.array(User.schema),
|
||||
schema: z.array(
|
||||
z.object({
|
||||
id: z.string().uuid(),
|
||||
accounts: z.array(User.schema),
|
||||
}),
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -66,53 +76,35 @@ export default apiRoute((app) =>
|
|||
return context.json({ error: "Unauthorized" }, 401);
|
||||
}
|
||||
|
||||
const idFollowerRelationships = await db.query.Relationships.findMany({
|
||||
columns: {
|
||||
ownerId: true,
|
||||
},
|
||||
where: (relationship, { inArray, and, eq }): SQL | undefined =>
|
||||
and(
|
||||
inArray(
|
||||
relationship.subjectId,
|
||||
Array.isArray(ids) ? ids : [ids],
|
||||
),
|
||||
eq(relationship.following, true),
|
||||
),
|
||||
});
|
||||
|
||||
if (idFollowerRelationships.length === 0) {
|
||||
return context.json([], 200);
|
||||
}
|
||||
|
||||
// Find users that you follow in idFollowerRelationships
|
||||
const relevantRelationships = await db.query.Relationships.findMany({
|
||||
columns: {
|
||||
subjectId: true,
|
||||
},
|
||||
where: (relationship, { inArray, and, eq }): SQL | undefined =>
|
||||
and(
|
||||
eq(relationship.ownerId, self.id),
|
||||
inArray(
|
||||
relationship.subjectId,
|
||||
idFollowerRelationships.map((f) => f.ownerId),
|
||||
),
|
||||
eq(relationship.following, true),
|
||||
),
|
||||
});
|
||||
|
||||
if (relevantRelationships.length === 0) {
|
||||
return context.json([], 200);
|
||||
}
|
||||
|
||||
const finalUsers = await User.manyFromSql(
|
||||
inArray(
|
||||
Users.id,
|
||||
relevantRelationships.map((r) => r.subjectId),
|
||||
// Find followers of the accounts in "ids", that you also follow
|
||||
const finalUsers = await Promise.all(
|
||||
ids.map(async (id) => ({
|
||||
id,
|
||||
accounts: await User.fromIds(
|
||||
(
|
||||
await db.execute(sql<InferSelectModel<typeof Users>>`
|
||||
SELECT "Users"."id" FROM "Users"
|
||||
INNER JOIN "Relationships" AS "SelfFollowing"
|
||||
ON "SelfFollowing"."subjectId" = "Users"."id"
|
||||
WHERE "SelfFollowing"."ownerId" = ${self.id}
|
||||
AND "SelfFollowing"."following" = true
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM "Relationships" AS "IdsFollowers"
|
||||
WHERE "IdsFollowers"."subjectId" = ${id}
|
||||
AND "IdsFollowers"."ownerId" = "Users"."id"
|
||||
AND "IdsFollowers"."following" = true
|
||||
)
|
||||
`)
|
||||
).rows.map((u) => u.id as string),
|
||||
),
|
||||
})),
|
||||
);
|
||||
|
||||
return context.json(
|
||||
finalUsers.map((o) => o.toApi()),
|
||||
finalUsers.map((u) => ({
|
||||
...u,
|
||||
accounts: u.accounts.map((a) => a.toApi()),
|
||||
})),
|
||||
200,
|
||||
);
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?acct=${users[0].data.username}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ beforeAll(async () => {
|
|||
const res1 = await fakeRequest(`/api/v1/accounts/${users[0].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -30,7 +30,7 @@ beforeAll(async () => {
|
|||
const res2 = await fakeRequest(`/api/v1/accounts/${users[2].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -56,7 +56,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?id[]=${users[2].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -86,7 +86,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?id[]=${users[1].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?q=${users[0].data.username}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,9 @@ export default apiRoute((app) =>
|
|||
return context.json({ error: "Unauthorized" }, 401);
|
||||
}
|
||||
|
||||
const application = await Application.getFromToken(token);
|
||||
const application = await Application.getFromToken(
|
||||
token.data.accessToken,
|
||||
);
|
||||
|
||||
if (!application) {
|
||||
return context.json({ error: "Unauthorized" }, 401);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ beforeAll(async () => {
|
|||
// Upload one emoji as admin, then one as each user
|
||||
const response = await fakeRequest("/api/v1/emojis", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
|
|
@ -29,7 +29,7 @@ beforeAll(async () => {
|
|||
|
||||
await fakeRequest("/api/v1/emojis", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
|
|
@ -41,7 +41,7 @@ beforeAll(async () => {
|
|||
|
||||
await fakeRequest("/api/v1/emojis", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
|
|
@ -64,7 +64,7 @@ describe(meta.route, () => {
|
|||
test("should return all global emojis", async () => {
|
||||
const response = await fakeRequest(meta.route, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ describe(meta.route, () => {
|
|||
test("should return all user emojis", async () => {
|
||||
const response = await fakeRequest(meta.route, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ beforeAll(async () => {
|
|||
// Create an emoji
|
||||
const response = await fakeRequest("/api/v1/emojis", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
|
|
@ -55,7 +55,7 @@ describe(meta.route, () => {
|
|||
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
method: "GET",
|
||||
},
|
||||
|
|
@ -67,7 +67,7 @@ describe(meta.route, () => {
|
|||
test("should not work if the user is trying to update an emoji they don't own", async () => {
|
||||
const response = await fakeRequest(meta.route.replace(":id", id), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "PATCH",
|
||||
|
|
@ -82,7 +82,7 @@ describe(meta.route, () => {
|
|||
test("should return the emoji", async () => {
|
||||
const response = await fakeRequest(meta.route.replace(":id", id), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
method: "GET",
|
||||
});
|
||||
|
|
@ -95,7 +95,7 @@ describe(meta.route, () => {
|
|||
test("should update the emoji", async () => {
|
||||
const response = await fakeRequest(meta.route.replace(":id", id), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "PATCH",
|
||||
|
|
@ -112,7 +112,7 @@ describe(meta.route, () => {
|
|||
test("should update the emoji with another url, but keep the shortcode", async () => {
|
||||
const response = await fakeRequest(meta.route.replace(":id", id), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "PATCH",
|
||||
|
|
@ -129,7 +129,7 @@ describe(meta.route, () => {
|
|||
test("should update the emoji to be non-global", async () => {
|
||||
const response = await fakeRequest(meta.route.replace(":id", id), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "PATCH",
|
||||
|
|
@ -143,7 +143,7 @@ describe(meta.route, () => {
|
|||
// Check if the other user can see it
|
||||
const response2 = await fakeRequest("/api/v1/custom_emojis", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
method: "GET",
|
||||
});
|
||||
|
|
@ -156,7 +156,7 @@ describe(meta.route, () => {
|
|||
test("should delete the emoji", async () => {
|
||||
const response = await fakeRequest(meta.route.replace(":id", id), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
method: "DELETE",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
@ -83,7 +83,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
@ -95,7 +95,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
|
@ -118,7 +118,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
@ -136,7 +136,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
@ -155,7 +155,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
@ -171,7 +171,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[2].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[2].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -45,7 +45,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -69,7 +69,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -41,7 +41,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
expect(response.status).toBe(200);
|
||||
|
|
@ -62,7 +62,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -73,7 +73,7 @@ describe(meta.route, () => {
|
|||
const response2 = await fakeRequest(meta.route, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
expect(response2.status).toBe(200);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/accounts/${users[0].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -19,7 +19,7 @@ beforeAll(async () => {
|
|||
|
||||
notifications = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
}).then((r) => r.json());
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -60,7 +60,7 @@ describe(meta.route, () => {
|
|||
test("should not display dismissed notification", async () => {
|
||||
const response = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/accounts/${users[0].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -19,7 +19,7 @@ beforeAll(async () => {
|
|||
|
||||
notifications = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
}).then((r) => r.json());
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", "invalid"),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -57,7 +57,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", "00000000-0000-0000-0000-000000000000"),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -70,7 +70,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", notifications[0].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/accounts/${users[0].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -19,7 +19,7 @@ beforeAll(async () => {
|
|||
|
||||
notifications = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
}).then((r) => r.json());
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ describe(meta.route, () => {
|
|||
|
||||
const newNotifications = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
}).then((r) => r.json());
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/accounts/${users[0].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -22,7 +22,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/statuses/${statuses[i].id}/favourite`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -31,7 +31,7 @@ beforeAll(async () => {
|
|||
|
||||
notifications = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
}).then((r) => r.json());
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -76,7 +76,7 @@ describe(meta.route, () => {
|
|||
test("should not display dismissed notification", async () => {
|
||||
const response = await fakeRequest("/api/v1/notifications", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ beforeAll(async () => {
|
|||
const res1 = await fakeRequest(`/api/v1/accounts/${users[0].id}/follow`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -31,7 +31,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -45,7 +45,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
body: getFormData({}),
|
||||
},
|
||||
|
|
@ -56,7 +56,7 @@ beforeAll(async () => {
|
|||
const res4 = await fakeRequest("/api/v1/statuses", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: `@${users[0].data.username} test mention`,
|
||||
|
|
@ -83,7 +83,7 @@ describe(meta.route, () => {
|
|||
test("should return 200 with notifications", async () => {
|
||||
const response = await fakeRequest(meta.route, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ describe(meta.route, () => {
|
|||
const filterResponse = await fakeRequest("/api/v2/filters", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
|
|
@ -132,7 +132,7 @@ describe(meta.route, () => {
|
|||
|
||||
const response = await fakeRequest(`${meta.route}?limit=20`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -89,7 +89,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route.replace(":id", role.id), {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -133,7 +133,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -144,7 +144,7 @@ describe(meta.route, () => {
|
|||
const response2 = await fakeRequest("/api/v1/roles", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route.replace(":id", role.id), {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ describe(meta.route, () => {
|
|||
const response2 = await fakeRequest("/api/v1/roles", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -47,7 +47,7 @@ describe(meta.route, () => {
|
|||
`/api/v1/statuses/${timeline[0].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/statuses/${status.id}/favourite`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", timeline[0].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ beforeAll(async () => {
|
|||
await fakeRequest(`/api/v1/statuses/${status.id}/reblog`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", timeline[0].id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -42,7 +42,7 @@ describe(meta.route, () => {
|
|||
await fakeRequest(`/api/v1/statuses/${timeline[1].id}/favourite`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
@ -52,7 +52,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -70,7 +70,7 @@ describe(meta.route, () => {
|
|||
`/api/v1/statuses/${timeline[1].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[1].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams(),
|
||||
});
|
||||
|
|
@ -51,7 +51,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "a".repeat(config.validation.max_note_size + 1),
|
||||
|
|
@ -66,7 +66,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -82,7 +82,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -98,7 +98,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -114,7 +114,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -130,7 +130,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -146,7 +146,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -169,7 +169,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
|
@ -194,7 +194,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -207,7 +207,7 @@ describe(meta.route, () => {
|
|||
const response2 = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world again!",
|
||||
|
|
@ -231,7 +231,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -244,7 +244,7 @@ describe(meta.route, () => {
|
|||
const response2 = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world again!",
|
||||
|
|
@ -268,7 +268,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, :test:!",
|
||||
|
|
@ -295,7 +295,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: `Hello, @${users[1].data.username}!`,
|
||||
|
|
@ -322,7 +322,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: `Hello, @${users[1].data.username}@${
|
||||
|
|
@ -353,7 +353,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hi! <script>alert('Hello, world!');</script>",
|
||||
|
|
@ -377,7 +377,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -403,7 +403,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "<img src='https://example.com/image.jpg'> <video src='https://example.com/video.mp4'> Test!",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ describe(meta.route, () => {
|
|||
test("should correctly parse limit", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?limit=5`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ describe(meta.route, () => {
|
|||
test("should return 200 with statuses", async () => {
|
||||
const response = await fakeRequest(meta.route, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ describe(meta.route, () => {
|
|||
test("should send correct Link header", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?limit=20`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&max_id=${timeline[19].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -104,7 +104,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&max_id=${timeline[19].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -119,7 +119,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&min_id=${timeline[20].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -145,7 +145,7 @@ describe(meta.route, () => {
|
|||
const filterResponse = await fakeRequest("/api/v2/filters", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
|
|
@ -162,7 +162,7 @@ describe(meta.route, () => {
|
|||
|
||||
const response = await fakeRequest(`${meta.route}?limit=20`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ describe(meta.route, () => {
|
|||
test("should correctly parse limit", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?limit=5`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ describe(meta.route, () => {
|
|||
test("should return 200 with statuses", async () => {
|
||||
const response = await fakeRequest(meta.route, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&local=true`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -85,7 +85,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?remote=true&allow_local_only=false&only_media=false`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -104,7 +104,7 @@ describe(meta.route, () => {
|
|||
test("should send correct Link header", async () => {
|
||||
const response = await fakeRequest(`${meta.route}?limit=20`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&max_id=${timeline[19].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -145,7 +145,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&max_id=${timeline[19].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -160,7 +160,7 @@ describe(meta.route, () => {
|
|||
`${meta.route}?limit=20&min_id=${timeline[20].id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -187,7 +187,7 @@ describe(meta.route, () => {
|
|||
const filterResponse = await fakeRequest("/api/v2/filters", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
|
|
@ -206,7 +206,7 @@ describe(meta.route, () => {
|
|||
|
||||
const response = await fakeRequest(`${meta.route}?limit=20`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const { tokens, deleteUsers } = await getTestUsers(2);
|
|||
const response = await fakeRequest("/api/v2/filters", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
|
|
@ -49,7 +49,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", filter.id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -75,7 +75,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
|
|
@ -111,7 +111,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
"keywords_attributes[0][id]": filter.keywords[0].id,
|
||||
|
|
@ -131,7 +131,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", filter.id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -148,7 +148,7 @@ describe(meta.route, () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
},
|
||||
|
|
@ -161,7 +161,7 @@ describe(meta.route, () => {
|
|||
meta.route.replace(":id", filter.id),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ describe(meta.route, () => {
|
|||
test("should return user filters (none)", async () => {
|
||||
const response = await fakeRequest(meta.route, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ describe(meta.route, () => {
|
|||
const response = await fakeRequest(meta.route, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Application as APIApplication } from "@versia/client/types";
|
||||
import { db } from "@versia/kit/db";
|
||||
import { Token, db } from "@versia/kit/db";
|
||||
import { Applications } from "@versia/kit/tables";
|
||||
import {
|
||||
type InferInsertModel,
|
||||
|
|
@ -81,15 +81,11 @@ export class Application extends BaseInterface<typeof Applications> {
|
|||
public static async getFromToken(
|
||||
token: string,
|
||||
): Promise<Application | null> {
|
||||
const result = await db.query.Tokens.findFirst({
|
||||
where: (tokens, { eq }): SQL | undefined =>
|
||||
eq(tokens.accessToken, token),
|
||||
with: {
|
||||
application: true,
|
||||
},
|
||||
});
|
||||
const result = await Token.fromAccessToken(token);
|
||||
|
||||
return result?.application ? new Application(result.application) : null;
|
||||
return result?.data.application
|
||||
? new Application(result.data.application)
|
||||
: null;
|
||||
}
|
||||
|
||||
public static fromClientId(clientId: string): Promise<Application | null> {
|
||||
|
|
|
|||
171
classes/database/token.ts
Normal file
171
classes/database/token.ts
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
import type { Token as ApiToken } from "@versia/client/types";
|
||||
import { User, db } from "@versia/kit/db";
|
||||
import { type Applications, Tokens } from "@versia/kit/tables";
|
||||
import {
|
||||
type InferInsertModel,
|
||||
type InferSelectModel,
|
||||
type SQL,
|
||||
desc,
|
||||
eq,
|
||||
inArray,
|
||||
} from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { BaseInterface } from "./base.ts";
|
||||
|
||||
export type TokenType = InferSelectModel<typeof Tokens> & {
|
||||
application: InferSelectModel<typeof Applications> | null;
|
||||
};
|
||||
|
||||
export class Token extends BaseInterface<typeof Tokens, TokenType> {
|
||||
public static schema: z.ZodType<ApiToken> = z.object({
|
||||
access_token: z.string(),
|
||||
token_type: z.enum(["bearer"]),
|
||||
scope: z.string(),
|
||||
created_at: z.number(),
|
||||
});
|
||||
|
||||
public async reload(): Promise<void> {
|
||||
const reloaded = await Token.fromId(this.data.id);
|
||||
|
||||
if (!reloaded) {
|
||||
throw new Error("Failed to reload token");
|
||||
}
|
||||
|
||||
this.data = reloaded.data;
|
||||
}
|
||||
|
||||
public static async fromId(id: string | null): Promise<Token | null> {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await Token.fromSql(eq(Tokens.id, id));
|
||||
}
|
||||
|
||||
public static async fromIds(ids: string[]): Promise<Token[]> {
|
||||
return await Token.manyFromSql(inArray(Tokens.id, ids));
|
||||
}
|
||||
|
||||
public static async fromSql(
|
||||
sql: SQL<unknown> | undefined,
|
||||
orderBy: SQL<unknown> | undefined = desc(Tokens.id),
|
||||
): Promise<Token | null> {
|
||||
const found = await db.query.Tokens.findFirst({
|
||||
where: sql,
|
||||
orderBy,
|
||||
with: {
|
||||
application: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
return null;
|
||||
}
|
||||
return new Token(found);
|
||||
}
|
||||
|
||||
public static async manyFromSql(
|
||||
sql: SQL<unknown> | undefined,
|
||||
orderBy: SQL<unknown> | undefined = desc(Tokens.id),
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
extra?: Parameters<typeof db.query.Tokens.findMany>[0],
|
||||
): Promise<Token[]> {
|
||||
const found = await db.query.Tokens.findMany({
|
||||
where: sql,
|
||||
orderBy,
|
||||
limit,
|
||||
offset,
|
||||
with: {
|
||||
application: true,
|
||||
...extra?.with,
|
||||
},
|
||||
});
|
||||
|
||||
return found.map((s) => new Token(s));
|
||||
}
|
||||
|
||||
public async update(newAttachment: Partial<TokenType>): Promise<TokenType> {
|
||||
await db
|
||||
.update(Tokens)
|
||||
.set(newAttachment)
|
||||
.where(eq(Tokens.id, this.id));
|
||||
|
||||
const updated = await Token.fromId(this.data.id);
|
||||
|
||||
if (!updated) {
|
||||
throw new Error("Failed to update token");
|
||||
}
|
||||
|
||||
this.data = updated.data;
|
||||
return updated.data;
|
||||
}
|
||||
|
||||
public save(): Promise<TokenType> {
|
||||
return this.update(this.data);
|
||||
}
|
||||
|
||||
public async delete(ids?: string[]): Promise<void> {
|
||||
if (Array.isArray(ids)) {
|
||||
await db.delete(Tokens).where(inArray(Tokens.id, ids));
|
||||
} else {
|
||||
await db.delete(Tokens).where(eq(Tokens.id, this.id));
|
||||
}
|
||||
}
|
||||
|
||||
public static async insert(
|
||||
data: InferInsertModel<typeof Tokens>,
|
||||
): Promise<Token> {
|
||||
const inserted = (await db.insert(Tokens).values(data).returning())[0];
|
||||
|
||||
const token = await Token.fromId(inserted.id);
|
||||
|
||||
if (!token) {
|
||||
throw new Error("Failed to insert token");
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public static async insertMany(
|
||||
data: InferInsertModel<typeof Tokens>[],
|
||||
): Promise<Token[]> {
|
||||
const inserted = await db.insert(Tokens).values(data).returning();
|
||||
|
||||
return await Token.fromIds(inserted.map((i) => i.id));
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return this.data.id;
|
||||
}
|
||||
|
||||
public static async fromAccessToken(
|
||||
accessToken: string,
|
||||
): Promise<Token | null> {
|
||||
return await Token.fromSql(eq(Tokens.accessToken, accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the associated user from this token
|
||||
*
|
||||
* @returns The user associated with this token
|
||||
*/
|
||||
public async getUser(): Promise<User | null> {
|
||||
if (!this.data.userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await User.fromId(this.data.userId);
|
||||
}
|
||||
|
||||
public toApi(): ApiToken {
|
||||
return {
|
||||
access_token: this.data.accessToken,
|
||||
token_type: "Bearer",
|
||||
scope: this.data.scope,
|
||||
created_at: Math.floor(
|
||||
new Date(this.data.createdAt).getTime() / 1000,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import type { Tokens } from "@versia/kit/tables";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
|
||||
/**
|
||||
* The type of token.
|
||||
*/
|
||||
export enum TokenType {
|
||||
Bearer = "Bearer",
|
||||
}
|
||||
|
||||
export type Token = InferSelectModel<typeof Tokens>;
|
||||
|
|
@ -3,18 +3,10 @@ import type {
|
|||
FollowAccept,
|
||||
FollowReject,
|
||||
} from "@versia/federation/types";
|
||||
import { User, db } from "@versia/kit/db";
|
||||
import {
|
||||
Applications,
|
||||
type Instances,
|
||||
type Roles,
|
||||
Tokens,
|
||||
type Users,
|
||||
} from "@versia/kit/tables";
|
||||
import { type InferSelectModel, type SQL, eq, sql } from "drizzle-orm";
|
||||
import type { ApplicationType } from "~/classes/database/application.ts";
|
||||
import { type Application, type Token, type User, db } from "@versia/kit/db";
|
||||
import type { Instances, Roles, Users } from "@versia/kit/tables";
|
||||
import { type InferSelectModel, type SQL, sql } from "drizzle-orm";
|
||||
import type { EmojiWithInstance } from "~/classes/database/emoji.ts";
|
||||
import type { Token } from "./token.ts";
|
||||
|
||||
export type UserType = InferSelectModel<typeof Users>;
|
||||
|
||||
|
|
@ -31,23 +23,7 @@ export type UserWithRelations = UserType & {
|
|||
roles: InferSelectModel<typeof Roles>[];
|
||||
};
|
||||
|
||||
export const userRelations: {
|
||||
instance: true;
|
||||
emojis: {
|
||||
with: {
|
||||
emoji: {
|
||||
with: {
|
||||
instance: true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
roles: {
|
||||
with: {
|
||||
role: true;
|
||||
};
|
||||
};
|
||||
} = {
|
||||
export const userRelations = {
|
||||
instance: true,
|
||||
emojis: {
|
||||
with: {
|
||||
|
|
@ -63,7 +39,7 @@ export const userRelations: {
|
|||
role: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
} as const;
|
||||
|
||||
export const userExtras = {
|
||||
followerCount:
|
||||
|
|
@ -103,19 +79,10 @@ export const userExtrasTemplate = (
|
|||
|
||||
export interface AuthData {
|
||||
user: User | null;
|
||||
token: string;
|
||||
application: ApplicationType | null;
|
||||
token: Token | null;
|
||||
application: Application | null;
|
||||
}
|
||||
|
||||
export const getFromHeader = async (value: string): Promise<AuthData> => {
|
||||
const token = value.split(" ")[1];
|
||||
|
||||
const { user, application } =
|
||||
await retrieveUserAndApplicationFromToken(token);
|
||||
|
||||
return { user, token, application };
|
||||
};
|
||||
|
||||
export const transformOutputToUserWithRelations = (
|
||||
user: Omit<UserType, "endpoints"> & {
|
||||
followerCount: unknown;
|
||||
|
|
@ -180,52 +147,6 @@ export const findManyUsers = async (
|
|||
return output.map((user) => transformOutputToUserWithRelations(user));
|
||||
};
|
||||
|
||||
export const retrieveUserAndApplicationFromToken = async (
|
||||
accessToken: string,
|
||||
): Promise<{
|
||||
user: User | null;
|
||||
application: ApplicationType | null;
|
||||
}> => {
|
||||
if (!accessToken) {
|
||||
return { user: null, application: null };
|
||||
}
|
||||
|
||||
const output = (
|
||||
await db
|
||||
.select({
|
||||
token: Tokens,
|
||||
application: Applications,
|
||||
})
|
||||
.from(Tokens)
|
||||
.leftJoin(Applications, eq(Tokens.applicationId, Applications.id))
|
||||
.where(eq(Tokens.accessToken, accessToken))
|
||||
.limit(1)
|
||||
)[0];
|
||||
|
||||
if (!output?.token.userId) {
|
||||
return { user: null, application: null };
|
||||
}
|
||||
|
||||
const user = await User.fromId(output.token.userId);
|
||||
|
||||
return { user, application: output.application ?? null };
|
||||
};
|
||||
|
||||
export const retrieveToken = async (
|
||||
accessToken: string,
|
||||
): Promise<Token | null> => {
|
||||
if (!accessToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
(await db.query.Tokens.findFirst({
|
||||
where: (tokens, { eq }): SQL | undefined =>
|
||||
eq(tokens.accessToken, accessToken),
|
||||
})) ?? null
|
||||
);
|
||||
};
|
||||
|
||||
export const followRequestToVersia = (
|
||||
follower: User,
|
||||
followee: User,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
// biome-ignore lint/performance/noBarrelFile: <explanation>
|
||||
export { User } from "~/classes/database/user";
|
||||
export { Role } from "~/classes/database/role";
|
||||
export { Attachment } from "~/classes/database/attachment";
|
||||
export { Emoji } from "~/classes/database/emoji";
|
||||
export { Instance } from "~/classes/database/instance";
|
||||
export { Note } from "~/classes/database/note";
|
||||
export { Timeline } from "~/classes/database/timeline";
|
||||
export { Application } from "~/classes/database/application";
|
||||
export { db } from "~/drizzle/db";
|
||||
export { Relationship } from "~/classes/database/relationship";
|
||||
export { Like } from "~/classes/database/like";
|
||||
export { User } from "~/classes/database/user.ts";
|
||||
export { Role } from "~/classes/database/role.ts";
|
||||
export { Attachment } from "~/classes/database/attachment.ts";
|
||||
export { Emoji } from "~/classes/database/emoji.ts";
|
||||
export { Instance } from "~/classes/database/instance.ts";
|
||||
export { Note } from "~/classes/database/note.ts";
|
||||
export { Timeline } from "~/classes/database/timeline.ts";
|
||||
export { Application } from "~/classes/database/application.ts";
|
||||
export { db } from "~/drizzle/db.ts";
|
||||
export { Relationship } from "~/classes/database/relationship.ts";
|
||||
export { Like } from "~/classes/database/like.ts";
|
||||
export { Token } from "~/classes/database/token.ts";
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
@ -79,7 +79,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: "jwt=invalid-jwt",
|
||||
},
|
||||
|
|
@ -118,7 +118,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
@ -160,7 +160,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
@ -200,7 +200,7 @@ describe("/oauth/authorize", () => {
|
|||
const response2 = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt2}`,
|
||||
},
|
||||
|
|
@ -245,7 +245,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
@ -289,7 +289,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
@ -331,7 +331,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
@ -373,7 +373,7 @@ describe("/oauth/authorize", () => {
|
|||
const response = await fakeRequest("/oauth/authorize", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Cookie: `jwt=${jwt}`,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { auth, jsonOrForm } from "@/api";
|
||||
import { randomString } from "@/math";
|
||||
import { Application, User, db } from "@versia/kit/db";
|
||||
import { RolePermissions, Tokens } from "@versia/kit/tables";
|
||||
import { Application, Token, User } from "@versia/kit/db";
|
||||
import { RolePermissions } from "@versia/kit/tables";
|
||||
import { type JWTPayload, SignJWT, jwtVerify } from "jose";
|
||||
import { JOSEError } from "jose/errors";
|
||||
import { z } from "zod";
|
||||
import { TokenType } from "~/classes/functions/token";
|
||||
import type { PluginType } from "../index.ts";
|
||||
|
||||
const schemas = {
|
||||
|
|
@ -282,11 +281,11 @@ export default (plugin: PluginType): void =>
|
|||
.setProtectedHeader({ alg: "EdDSA" })
|
||||
.sign(keys.private);
|
||||
|
||||
await db.insert(Tokens).values({
|
||||
await Token.insert({
|
||||
accessToken: randomString(64, "base64url"),
|
||||
code,
|
||||
scope: scope ?? application.data.scopes,
|
||||
tokenType: TokenType.Bearer,
|
||||
tokenType: "Bearer",
|
||||
applicationId: application.id,
|
||||
redirectUri: redirect_uri ?? application.data.redirectUri,
|
||||
expiresAt: new Date(
|
||||
|
|
|
|||
|
|
@ -1,16 +1,10 @@
|
|||
import { randomString } from "@/math.ts";
|
||||
import { setCookie } from "@hono/hono/cookie";
|
||||
import { createRoute, z } from "@hono/zod-openapi";
|
||||
import { User, db } from "@versia/kit/db";
|
||||
import { Token, User, db } from "@versia/kit/db";
|
||||
import { type SQL, and, eq, isNull } from "@versia/kit/drizzle";
|
||||
import {
|
||||
OpenIdAccounts,
|
||||
RolePermissions,
|
||||
Tokens,
|
||||
Users,
|
||||
} from "@versia/kit/tables";
|
||||
import { OpenIdAccounts, RolePermissions, Users } from "@versia/kit/tables";
|
||||
import { SignJWT } from "jose";
|
||||
import { TokenType } from "~/classes/functions/token.ts";
|
||||
import type { PluginType } from "../../index.ts";
|
||||
import { automaticOidcFlow } from "../../utils.ts";
|
||||
|
||||
|
|
@ -314,11 +308,11 @@ export default (plugin: PluginType): void => {
|
|||
|
||||
const code = randomString(32, "hex");
|
||||
|
||||
await db.insert(Tokens).values({
|
||||
await Token.insert({
|
||||
accessToken: randomString(64, "base64url"),
|
||||
code,
|
||||
scope: flow.application.scopes,
|
||||
tokenType: TokenType.Bearer,
|
||||
tokenType: "Bearer",
|
||||
userId: user.id,
|
||||
applicationId: flow.application.id,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { Application, db } from "@versia/kit/db";
|
||||
import { eq } from "@versia/kit/drizzle";
|
||||
import { Tokens } from "@versia/kit/tables";
|
||||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { Application, Token } from "@versia/kit/db";
|
||||
import { fakeRequest, getTestUsers } from "~/tests/utils";
|
||||
|
||||
const { deleteUsers, users } = await getTestUsers(1);
|
||||
|
|
@ -13,9 +11,7 @@ const application = await Application.insert({
|
|||
secret: "test-secret",
|
||||
name: "Test Application",
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
await db.insert(Tokens).values({
|
||||
const token = await Token.insert({
|
||||
code: "test-code",
|
||||
redirectUri: application.data.redirectUri,
|
||||
clientId: application.data.clientId,
|
||||
|
|
@ -26,15 +22,12 @@ beforeAll(async () => {
|
|||
scope: application.data.scopes,
|
||||
userId: users[0].id,
|
||||
applicationId: application.id,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
await application.delete();
|
||||
await db
|
||||
.delete(Tokens)
|
||||
.where(eq(Tokens.clientId, application.data.clientId));
|
||||
await token.delete();
|
||||
});
|
||||
|
||||
describe("/oauth/revoke", () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { jsonOrForm } from "@/api";
|
||||
import { createRoute, z } from "@hono/zod-openapi";
|
||||
import { db } from "@versia/kit/db";
|
||||
import { type SQL, eq } from "@versia/kit/drizzle";
|
||||
import { Token, db } from "@versia/kit/db";
|
||||
import { and, eq } from "@versia/kit/drizzle";
|
||||
import { Tokens } from "@versia/kit/tables";
|
||||
import type { PluginType } from "../../index.ts";
|
||||
|
||||
|
|
@ -62,16 +62,12 @@ export default (plugin: PluginType): void => {
|
|||
const { client_id, client_secret, token } =
|
||||
context.req.valid("json");
|
||||
|
||||
const foundToken = await db.query.Tokens.findFirst({
|
||||
where: (tokenTable, { eq, and }): SQL | undefined =>
|
||||
const foundToken = await Token.fromSql(
|
||||
and(
|
||||
eq(tokenTable.accessToken, token ?? ""),
|
||||
eq(tokenTable.clientId, client_id),
|
||||
eq(Tokens.accessToken, token ?? ""),
|
||||
eq(Tokens.clientId, client_id),
|
||||
),
|
||||
with: {
|
||||
application: true,
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (!(foundToken && token)) {
|
||||
return context.json(
|
||||
|
|
@ -85,7 +81,7 @@ export default (plugin: PluginType): void => {
|
|||
}
|
||||
|
||||
// Check if the client secret is correct
|
||||
if (foundToken.application?.secret !== client_secret) {
|
||||
if (foundToken.data.application?.secret !== client_secret) {
|
||||
return context.json(
|
||||
{
|
||||
error: "unauthorized_client",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { Application, db } from "@versia/kit/db";
|
||||
import { eq } from "@versia/kit/drizzle";
|
||||
import { Tokens } from "@versia/kit/tables";
|
||||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { Application, Token } from "@versia/kit/db";
|
||||
import { fakeRequest, getTestUsers } from "~/tests/utils";
|
||||
|
||||
const { deleteUsers, users } = await getTestUsers(1);
|
||||
|
|
@ -13,9 +11,7 @@ const application = await Application.insert({
|
|||
secret: "test-secret",
|
||||
name: "Test Application",
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
await db.insert(Tokens).values({
|
||||
const token = await Token.insert({
|
||||
code: "test-code",
|
||||
redirectUri: application.data.redirectUri,
|
||||
clientId: application.data.clientId,
|
||||
|
|
@ -25,15 +21,12 @@ beforeAll(async () => {
|
|||
tokenType: "Bearer",
|
||||
scope: application.data.scopes,
|
||||
userId: users[0].id,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
await application.delete();
|
||||
await db
|
||||
.delete(Tokens)
|
||||
.where(eq(Tokens.clientId, application.data.clientId));
|
||||
await token.delete();
|
||||
});
|
||||
|
||||
describe("/oauth/token", () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { jsonOrForm } from "@/api";
|
||||
import { createRoute, z } from "@hono/zod-openapi";
|
||||
import { Application, db } from "@versia/kit/db";
|
||||
import { type SQL, eq } from "@versia/kit/drizzle";
|
||||
import { Application, Token } from "@versia/kit/db";
|
||||
import { and, eq } from "@versia/kit/drizzle";
|
||||
import { Tokens } from "@versia/kit/tables";
|
||||
import type { PluginType } from "../../index.ts";
|
||||
|
||||
|
|
@ -154,17 +154,13 @@ export default (plugin: PluginType): void => {
|
|||
);
|
||||
}
|
||||
|
||||
const token = await db.query.Tokens.findFirst({
|
||||
where: (token, { eq, and }): SQL | undefined =>
|
||||
const token = await Token.fromSql(
|
||||
and(
|
||||
eq(token.code, code),
|
||||
eq(
|
||||
token.redirectUri,
|
||||
decodeURI(redirect_uri),
|
||||
eq(Tokens.code, code),
|
||||
eq(Tokens.redirectUri, decodeURI(redirect_uri)),
|
||||
eq(Tokens.clientId, client_id),
|
||||
),
|
||||
eq(token.clientId, client_id),
|
||||
),
|
||||
});
|
||||
);
|
||||
|
||||
if (!token) {
|
||||
return context.json(
|
||||
|
|
@ -177,28 +173,22 @@ export default (plugin: PluginType): void => {
|
|||
}
|
||||
|
||||
// Invalidate the code
|
||||
await db
|
||||
.update(Tokens)
|
||||
.set({ code: null })
|
||||
.where(eq(Tokens.id, token.id));
|
||||
await token.update({ code: null });
|
||||
|
||||
return context.json(
|
||||
{
|
||||
access_token: token.accessToken,
|
||||
token_type: "Bearer",
|
||||
expires_in: token.expiresAt
|
||||
...token.toApi(),
|
||||
expires_in: token.data.expiresAt
|
||||
? Math.floor(
|
||||
(new Date(token.expiresAt).getTime() -
|
||||
(new Date(
|
||||
token.data.expiresAt,
|
||||
).getTime() -
|
||||
Date.now()) /
|
||||
1000,
|
||||
)
|
||||
: null,
|
||||
id_token: token.idToken,
|
||||
id_token: token.data.idToken,
|
||||
refresh_token: null,
|
||||
scope: token.scope,
|
||||
created_at: Math.floor(
|
||||
new Date(token.createdAt).getTime() / 1000,
|
||||
),
|
||||
},
|
||||
200,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe("/api/v1/sso/:id", () => {
|
|||
const response = await fakeRequest("/api/v1/sso/unknown", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ describe("/api/v1/sso/:id", () => {
|
|||
const response2 = await fakeRequest("/api/v1/sso/unknown", {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ describe("/api/v1/sso", () => {
|
|||
const response = await fakeRequest("/api/v1/sso", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ describe("/api/v1/sso", () => {
|
|||
const response = await fakeRequest("/api/v1/sso", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0]?.accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v1/statuses", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
body: formData,
|
||||
|
|
@ -42,7 +42,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
Authorization: `Bearer ${tokens[0].data.accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
body: getFormData({
|
||||
display_name: "New Display Name",
|
||||
|
|
@ -59,7 +59,7 @@ describe("API Tests", () => {
|
|||
"/api/v1/accounts/verify_credentials",
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -106,7 +106,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -132,7 +132,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -156,7 +156,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v1/blocks", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -205,7 +205,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -231,7 +231,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -257,7 +257,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ comment: "This is a new note" }),
|
||||
|
|
@ -283,7 +283,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -314,7 +314,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v1/profile/avatar", {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v1/profile/header", {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -371,13 +371,13 @@ describe("API Tests", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("should return an array of objects with id and accounts properties, where id is a string and accounts is an array of APIAccount objects", async () => {
|
||||
test("should return no familiar followers", async () => {
|
||||
const response = await fakeRequest(
|
||||
`/api/v1/accounts/familiar_followers?id[]=${user2.id}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -393,7 +393,9 @@ describe("API Tests", () => {
|
|||
}[];
|
||||
|
||||
expect(Array.isArray(familiarFollowers)).toBe(true);
|
||||
expect(familiarFollowers.length).toBe(0);
|
||||
expect(familiarFollowers.length).toBe(1);
|
||||
expect(familiarFollowers[0].id).toBe(user2.id);
|
||||
expect(familiarFollowers[0].accounts).toBeArrayOfSize(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v2/media", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
|
@ -52,7 +52,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v1/statuses", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "Hello, world!",
|
||||
|
|
@ -94,7 +94,7 @@ describe("API Tests", () => {
|
|||
const response = await fakeRequest("/api/v1/statuses", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
status: "This is a reply!",
|
||||
|
|
@ -139,7 +139,7 @@ describe("API Tests", () => {
|
|||
`/api/v1/statuses/${status?.id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -184,7 +184,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -209,7 +209,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -232,7 +232,7 @@ describe("API Tests", () => {
|
|||
`/api/v1/statuses/${status?.id}/context`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -259,7 +259,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -289,7 +289,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -306,7 +306,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -330,7 +330,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Authorization: `Bearer ${token.data.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { generateChallenge } from "@/challenges";
|
||||
import { randomString } from "@/math";
|
||||
import { Note, User, db } from "@versia/kit/db";
|
||||
import { Notes, Tokens, Users } from "@versia/kit/tables";
|
||||
import { Note, Token, User, db } from "@versia/kit/db";
|
||||
import { Notes, Users } from "@versia/kit/tables";
|
||||
import { solveChallenge } from "altcha-lib";
|
||||
import { asc, inArray, like } from "drizzle-orm";
|
||||
import { appFactory } from "~/app";
|
||||
import type { Status } from "~/classes/functions/status";
|
||||
import type { Token } from "~/classes/functions/token";
|
||||
import { searchManager } from "~/classes/search/search-manager";
|
||||
import { setupDatabase } from "~/drizzle/db";
|
||||
import { config } from "~/packages/config-manager";
|
||||
|
|
@ -60,9 +59,7 @@ export const getTestUsers = async (
|
|||
users.push(user);
|
||||
}
|
||||
|
||||
const tokens = await db
|
||||
.insert(Tokens)
|
||||
.values(
|
||||
const tokens = await Token.insertMany(
|
||||
users.map((u) => ({
|
||||
accessToken: randomString(32, "hex"),
|
||||
tokenType: "bearer",
|
||||
|
|
@ -71,12 +68,15 @@ export const getTestUsers = async (
|
|||
code: randomString(32, "hex"),
|
||||
scope: "read write follow push",
|
||||
})),
|
||||
)
|
||||
.returning();
|
||||
);
|
||||
|
||||
return {
|
||||
users,
|
||||
tokens,
|
||||
// Order tokens in the same order as users
|
||||
// The first token belongs to the first user, the second token belongs to the second user, etc.
|
||||
tokens: users.map(
|
||||
(u) => tokens.find((t) => t.data.userId === u.id) as Token,
|
||||
),
|
||||
passwords,
|
||||
deleteUsers: async (): Promise<void> => {
|
||||
await db.delete(Users).where(
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import type {
|
|||
Unfollow,
|
||||
User,
|
||||
} from "@versia/federation/types";
|
||||
import type { Application, User as DatabaseUser } from "@versia/kit/db";
|
||||
import type { RolePermissions } from "@versia/kit/tables";
|
||||
import type { SocketAddress } from "bun";
|
||||
import { z } from "zod";
|
||||
import type { AuthData } from "~/classes/functions/user";
|
||||
import type { Config } from "~/packages/config-manager";
|
||||
|
||||
export type HttpVerb = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
|
||||
|
|
@ -52,11 +52,7 @@ export const ErrorSchema = z.object({
|
|||
export type HonoEnv = {
|
||||
Variables: {
|
||||
config: Config;
|
||||
auth: {
|
||||
user: DatabaseUser | null;
|
||||
token: string | null;
|
||||
application: Application | null;
|
||||
};
|
||||
auth: AuthData;
|
||||
};
|
||||
Bindings: {
|
||||
ip?: SocketAddress | null;
|
||||
|
|
|
|||
43
utils/api.ts
43
utils/api.ts
|
|
@ -2,7 +2,7 @@ import type { Context, MiddlewareHandler } from "@hono/hono";
|
|||
import { createMiddleware } from "@hono/hono/factory";
|
||||
import type { OpenAPIHono } from "@hono/zod-openapi";
|
||||
import { getLogger } from "@logtape/logtape";
|
||||
import { Application, type User, db } from "@versia/kit/db";
|
||||
import { Application, Token, db } from "@versia/kit/db";
|
||||
import { Challenges } from "@versia/kit/tables";
|
||||
import { extractParams, verifySolution } from "altcha-lib";
|
||||
import chalk from "chalk";
|
||||
|
|
@ -24,7 +24,7 @@ import {
|
|||
import { type ParsedQs, parse } from "qs";
|
||||
import type { z } from "zod";
|
||||
import { fromZodError } from "zod-validation-error";
|
||||
import { type AuthData, getFromHeader } from "~/classes/functions/user";
|
||||
import type { AuthData } from "~/classes/functions/user";
|
||||
import { config } from "~/packages/config-manager/index.ts";
|
||||
import type { ApiRouteMetadata, HonoEnv, HttpVerb } from "~/types/api";
|
||||
|
||||
|
|
@ -178,20 +178,12 @@ const checkRouteNeedsAuth = (
|
|||
auth: AuthData | null,
|
||||
authData: ApiRouteMetadata["auth"],
|
||||
context: Context,
|
||||
):
|
||||
| Response
|
||||
| {
|
||||
user: User | null;
|
||||
token: string | null;
|
||||
application: Application | null;
|
||||
} => {
|
||||
if (auth?.user) {
|
||||
): Response | AuthData => {
|
||||
if (auth?.user && auth?.token) {
|
||||
return {
|
||||
user: auth.user as User,
|
||||
token: auth.token as string,
|
||||
application: auth.application
|
||||
? new Application(auth.application)
|
||||
: null,
|
||||
user: auth.user,
|
||||
token: auth.token,
|
||||
application: auth.application,
|
||||
};
|
||||
}
|
||||
if (
|
||||
|
|
@ -295,8 +287,19 @@ export const auth = (
|
|||
): MiddlewareHandler<HonoEnv, string> =>
|
||||
createMiddleware<HonoEnv>(async (context, next) => {
|
||||
const header = context.req.header("Authorization");
|
||||
const tokenString = header?.split(" ")[1];
|
||||
|
||||
const auth = header ? await getFromHeader(header) : null;
|
||||
const token = tokenString
|
||||
? await Token.fromAccessToken(tokenString)
|
||||
: null;
|
||||
|
||||
const auth: AuthData = {
|
||||
token,
|
||||
application: token?.data.application
|
||||
? new Application(token?.data.application)
|
||||
: null,
|
||||
user: (await token?.getUser()) ?? null,
|
||||
};
|
||||
|
||||
// Only exists for type casting, as otherwise weird errors happen with Hono
|
||||
const fakeResponse = context.json({});
|
||||
|
|
@ -325,11 +328,7 @@ export const auth = (
|
|||
|
||||
const authCheck = checkRouteNeedsAuth(auth, authData, context) as
|
||||
| typeof fakeResponse
|
||||
| {
|
||||
user: User | null;
|
||||
token: string | null;
|
||||
application: Application | null;
|
||||
};
|
||||
| AuthData;
|
||||
|
||||
if (authCheck instanceof Response) {
|
||||
return authCheck;
|
||||
|
|
@ -385,7 +384,7 @@ async function parseUrlEncoded(context: Context): Promise<ParsedQs> {
|
|||
|
||||
export const qsQuery = (): MiddlewareHandler => {
|
||||
return createMiddleware(async (context, next) => {
|
||||
const parsed = parse(context.req.query(), {
|
||||
const parsed = parse(new URL(context.req.url).searchParams.toString(), {
|
||||
parseArrays: true,
|
||||
interpretNumericEntities: true,
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue