mirror of
https://github.com/versia-pub/server.git
synced 2026-01-26 20:26:01 +01:00
fix(api): 🐛 Fix statuses not saving the user's applicationId
This commit is contained in:
parent
a5a5d57c81
commit
06bcbbe451
|
|
@ -40,7 +40,7 @@ import { LogLevel } from "~packages/log-manager";
|
||||||
import type { Note } from "~types/lysand/Object";
|
import type { Note } from "~types/lysand/Object";
|
||||||
import type { Attachment as APIAttachment } from "~types/mastodon/attachment";
|
import type { Attachment as APIAttachment } from "~types/mastodon/attachment";
|
||||||
import type { Status as APIStatus } from "~types/mastodon/status";
|
import type { Status as APIStatus } from "~types/mastodon/status";
|
||||||
import { applicationToAPI } from "./Application";
|
import { applicationToAPI, type Application } from "./Application";
|
||||||
import {
|
import {
|
||||||
attachmentFromLysand,
|
attachmentFromLysand,
|
||||||
attachmentToAPI,
|
attachmentToAPI,
|
||||||
|
|
@ -923,6 +923,7 @@ export const createNewStatus = async (
|
||||||
media_attachments?: string[],
|
media_attachments?: string[],
|
||||||
inReplyTo?: StatusWithRelations,
|
inReplyTo?: StatusWithRelations,
|
||||||
quoting?: StatusWithRelations,
|
quoting?: StatusWithRelations,
|
||||||
|
application?: Application,
|
||||||
): Promise<StatusWithRelations | null> => {
|
): Promise<StatusWithRelations | null> => {
|
||||||
const htmlContent = await contentToHtml(content, mentions);
|
const htmlContent = await contentToHtml(content, mentions);
|
||||||
|
|
||||||
|
|
@ -956,6 +957,7 @@ export const createNewStatus = async (
|
||||||
uri: uri || null,
|
uri: uri || null,
|
||||||
inReplyToPostId: inReplyTo?.id,
|
inReplyToPostId: inReplyTo?.id,
|
||||||
quotingPostId: quoting?.id,
|
quotingPostId: quoting?.id,
|
||||||
|
applicationId: application?.id ?? null,
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,12 @@ import { htmlToText } from "html-to-text";
|
||||||
import type * as Lysand from "lysand-types";
|
import type * as Lysand from "lysand-types";
|
||||||
import { db } from "~drizzle/db";
|
import { db } from "~drizzle/db";
|
||||||
import {
|
import {
|
||||||
|
application,
|
||||||
emojiToUser,
|
emojiToUser,
|
||||||
instance,
|
instance,
|
||||||
notification,
|
notification,
|
||||||
relationship,
|
relationship,
|
||||||
|
token,
|
||||||
user,
|
user,
|
||||||
} from "~drizzle/schema";
|
} from "~drizzle/schema";
|
||||||
import { LogLevel } from "~packages/log-manager";
|
import { LogLevel } from "~packages/log-manager";
|
||||||
|
|
@ -25,6 +27,8 @@ import {
|
||||||
import { objectToInboxRequest } from "./Federation";
|
import { objectToInboxRequest } from "./Federation";
|
||||||
import { addInstanceIfNotExists } from "./Instance";
|
import { addInstanceIfNotExists } from "./Instance";
|
||||||
import { createNewRelationship } from "./Relationship";
|
import { createNewRelationship } from "./Relationship";
|
||||||
|
import type { Token } from "./Token";
|
||||||
|
import type { Application } from "./Application";
|
||||||
|
|
||||||
export type User = InferSelectModel<typeof user> & {
|
export type User = InferSelectModel<typeof user> & {
|
||||||
endpoints?: Partial<{
|
endpoints?: Partial<{
|
||||||
|
|
@ -123,6 +127,7 @@ export const userExtrasTemplate = (name: string) => ({
|
||||||
export interface AuthData {
|
export interface AuthData {
|
||||||
user: UserWithRelations | null;
|
user: UserWithRelations | null;
|
||||||
token: string;
|
token: string;
|
||||||
|
application: Application | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -153,7 +158,10 @@ export const getFromRequest = async (req: Request): Promise<AuthData> => {
|
||||||
// Check auth token
|
// Check auth token
|
||||||
const token = req.headers.get("Authorization")?.split(" ")[1] || "";
|
const token = req.headers.get("Authorization")?.split(" ")[1] || "";
|
||||||
|
|
||||||
return { user: await retrieveUserFromToken(token), token };
|
const { user, application } =
|
||||||
|
await retrieveUserAndApplicationFromToken(token);
|
||||||
|
|
||||||
|
return { user, token, application };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const followRequestUser = async (
|
export const followRequestUser = async (
|
||||||
|
|
@ -652,9 +660,7 @@ export const retrieveUserFromToken = async (
|
||||||
): Promise<UserWithRelations | null> => {
|
): Promise<UserWithRelations | null> => {
|
||||||
if (!access_token) return null;
|
if (!access_token) return null;
|
||||||
|
|
||||||
const token = await db.query.token.findFirst({
|
const token = await retrieveToken(access_token);
|
||||||
where: (tokens, { eq }) => eq(tokens.accessToken, access_token),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!token || !token.userId) return null;
|
if (!token || !token.userId) return null;
|
||||||
|
|
||||||
|
|
@ -665,6 +671,47 @@ export const retrieveUserFromToken = async (
|
||||||
return user;
|
return user;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const retrieveUserAndApplicationFromToken = async (
|
||||||
|
access_token: string,
|
||||||
|
): Promise<{
|
||||||
|
user: UserWithRelations | null;
|
||||||
|
application: Application | null;
|
||||||
|
}> => {
|
||||||
|
if (!access_token) return { user: null, application: null };
|
||||||
|
|
||||||
|
const output = (
|
||||||
|
await db
|
||||||
|
.select({
|
||||||
|
token: token,
|
||||||
|
application: application,
|
||||||
|
})
|
||||||
|
.from(token)
|
||||||
|
.leftJoin(application, eq(token.applicationId, application.id))
|
||||||
|
.where(eq(token.accessToken, access_token))
|
||||||
|
.limit(1)
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
if (!output?.token.userId) return { user: null, application: null };
|
||||||
|
|
||||||
|
const user = await findFirstUser({
|
||||||
|
where: (user, { eq }) => eq(user.id, output.token.userId ?? ""),
|
||||||
|
});
|
||||||
|
|
||||||
|
return { user, application: output.application ?? null };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const retrieveToken = async (
|
||||||
|
access_token: string,
|
||||||
|
): Promise<Token | null> => {
|
||||||
|
if (!access_token) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
(await db.query.token.findFirst({
|
||||||
|
where: (tokens, { eq }) => eq(tokens.accessToken, access_token),
|
||||||
|
})) ?? null
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the relationship to another user.
|
* Gets the relationship to another user.
|
||||||
* @param other The other user to get the relationship to.
|
* @param other The other user to get the relationship to.
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { LogLevel, type LogManager, type MultiLogManager } from "log-manager";
|
||||||
import { RequestParser } from "request-parser";
|
import { RequestParser } from "request-parser";
|
||||||
import type { ZodType, z } from "zod";
|
import type { ZodType, z } from "zod";
|
||||||
import { fromZodError } from "zod-validation-error";
|
import { fromZodError } from "zod-validation-error";
|
||||||
|
import type { Application } from "~database/entities/Application";
|
||||||
import {
|
import {
|
||||||
type AuthData,
|
type AuthData,
|
||||||
type UserWithRelations,
|
type UserWithRelations,
|
||||||
|
|
@ -31,6 +32,7 @@ export type RouteHandler<
|
||||||
token: RouteMeta["auth"]["required"] extends true
|
token: RouteMeta["auth"]["required"] extends true
|
||||||
? string
|
? string
|
||||||
: string | null;
|
: string | null;
|
||||||
|
application: Application | null;
|
||||||
};
|
};
|
||||||
parsedRequest: z.infer<ZodSchema>;
|
parsedRequest: z.infer<ZodSchema>;
|
||||||
configManager: {
|
configManager: {
|
||||||
|
|
@ -140,6 +142,7 @@ export const processRoute = async (
|
||||||
auth: {
|
auth: {
|
||||||
token: auth?.token ?? null,
|
token: auth?.token ?? null,
|
||||||
user: auth?.user ?? null,
|
user: auth?.user ?? null,
|
||||||
|
application: auth?.application ?? null,
|
||||||
},
|
},
|
||||||
parsedRequest: parsingResult
|
parsedRequest: parsingResult
|
||||||
? (parsingResult.data as z.infer<typeof route.schema>)
|
? (parsingResult.data as z.infer<typeof route.schema>)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export default apiRoute<typeof meta, typeof schema>(
|
||||||
return errorResponse("Invalid ID, must be of type UUIDv7", 404);
|
return errorResponse("Invalid ID, must be of type UUIDv7", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { user } = extraData.auth;
|
const { user, application } = extraData.auth;
|
||||||
|
|
||||||
if (!user) return errorResponse("Unauthorized", 401);
|
if (!user) return errorResponse("Unauthorized", 401);
|
||||||
|
|
||||||
|
|
@ -70,6 +70,7 @@ export default apiRoute<typeof meta, typeof schema>(
|
||||||
visibility,
|
visibility,
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
|
applicationId: application?.id ?? null,
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
)[0];
|
)[0];
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export const schema = z.object({
|
||||||
*/
|
*/
|
||||||
export default apiRoute<typeof meta, typeof schema>(
|
export default apiRoute<typeof meta, typeof schema>(
|
||||||
async (req, matchedRoute, extraData) => {
|
async (req, matchedRoute, extraData) => {
|
||||||
const { user } = extraData.auth;
|
const { user, application } = extraData.auth;
|
||||||
|
|
||||||
if (!user) return errorResponse("Unauthorized", 401);
|
if (!user) return errorResponse("Unauthorized", 401);
|
||||||
|
|
||||||
|
|
@ -187,6 +187,7 @@ export default apiRoute<typeof meta, typeof schema>(
|
||||||
media_ids,
|
media_ids,
|
||||||
replyStatus ?? undefined,
|
replyStatus ?? undefined,
|
||||||
quote ?? undefined,
|
quote ?? undefined,
|
||||||
|
application ?? undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!newStatus) {
|
if (!newStatus) {
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ export const getTestStatuses = async (
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
visibility: "public",
|
visibility: "public",
|
||||||
|
applicationId: null,
|
||||||
...partial,
|
...partial,
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue