mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
feat(api): ✨ Add requested_by to relationships
This commit is contained in:
parent
ffcf01e3cd
commit
20d1a5f39e
|
|
@ -4,7 +4,9 @@ import { Relationships } from "~/drizzle/schema";
|
||||||
import type { User } from "~/packages/database-interface/user";
|
import type { User } from "~/packages/database-interface/user";
|
||||||
import type { Relationship as APIRelationship } from "~/types/mastodon/relationship";
|
import type { Relationship as APIRelationship } from "~/types/mastodon/relationship";
|
||||||
|
|
||||||
export type Relationship = InferSelectModel<typeof Relationships>;
|
export type Relationship = InferSelectModel<typeof Relationships> & {
|
||||||
|
requestedBy: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new relationship between two users.
|
* Creates a new relationship between two users.
|
||||||
|
|
@ -16,29 +18,32 @@ export const createNewRelationship = async (
|
||||||
owner: User,
|
owner: User,
|
||||||
other: User,
|
other: User,
|
||||||
): Promise<Relationship> => {
|
): Promise<Relationship> => {
|
||||||
return (
|
return {
|
||||||
await db
|
...(
|
||||||
.insert(Relationships)
|
await db
|
||||||
.values({
|
.insert(Relationships)
|
||||||
ownerId: owner.id,
|
.values({
|
||||||
subjectId: other.id,
|
ownerId: owner.id,
|
||||||
languages: [],
|
subjectId: other.id,
|
||||||
following: false,
|
languages: [],
|
||||||
showingReblogs: false,
|
following: false,
|
||||||
notifying: false,
|
showingReblogs: false,
|
||||||
followedBy: false,
|
notifying: false,
|
||||||
blocking: false,
|
followedBy: false,
|
||||||
blockedBy: false,
|
blocking: false,
|
||||||
muting: false,
|
blockedBy: false,
|
||||||
mutingNotifications: false,
|
muting: false,
|
||||||
requested: false,
|
mutingNotifications: false,
|
||||||
domainBlocking: false,
|
requested: false,
|
||||||
endorsed: false,
|
domainBlocking: false,
|
||||||
note: "",
|
endorsed: false,
|
||||||
updatedAt: new Date().toISOString(),
|
note: "",
|
||||||
})
|
updatedAt: new Date().toISOString(),
|
||||||
.returning()
|
})
|
||||||
)[0];
|
.returning()
|
||||||
|
)[0],
|
||||||
|
requestedBy: false,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkForBidirectionalRelationships = async (
|
export const checkForBidirectionalRelationships = async (
|
||||||
|
|
@ -81,6 +86,7 @@ export const relationshipToAPI = (rel: Relationship): APIRelationship => {
|
||||||
muting_notifications: rel.mutingNotifications,
|
muting_notifications: rel.mutingNotifications,
|
||||||
notifying: rel.notifying,
|
notifying: rel.notifying,
|
||||||
requested: rel.requested,
|
requested: rel.requested,
|
||||||
|
requested_by: rel.requestedBy,
|
||||||
showing_reblogs: rel.showingReblogs,
|
showing_reblogs: rel.showingReblogs,
|
||||||
note: rel.note,
|
note: rel.note,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import { LogLevel } from "~/packages/log-manager";
|
||||||
import type { Application } from "./Application";
|
import type { Application } from "./Application";
|
||||||
import type { EmojiWithInstance } from "./Emoji";
|
import type { EmojiWithInstance } from "./Emoji";
|
||||||
import { objectToInboxRequest } from "./Federation";
|
import { objectToInboxRequest } from "./Federation";
|
||||||
import { createNewRelationship } from "./Relationship";
|
import { type Relationship, createNewRelationship } from "./Relationship";
|
||||||
import type { Token } from "./Token";
|
import type { Token } from "./Token";
|
||||||
|
|
||||||
export type UserType = InferSelectModel<typeof Users>;
|
export type UserType = InferSelectModel<typeof Users>;
|
||||||
|
|
@ -121,22 +121,33 @@ export const followRequestUser = async (
|
||||||
reblogs = false,
|
reblogs = false,
|
||||||
notify = false,
|
notify = false,
|
||||||
languages: string[] = [],
|
languages: string[] = [],
|
||||||
): Promise<InferSelectModel<typeof Relationships>> => {
|
): Promise<Relationship> => {
|
||||||
const isRemote = followee.isRemote();
|
const isRemote = followee.isRemote();
|
||||||
|
|
||||||
const updatedRelationship = (
|
await db
|
||||||
await db
|
.update(Relationships)
|
||||||
.update(Relationships)
|
.set({
|
||||||
.set({
|
following: isRemote ? false : !followee.getUser().isLocked,
|
||||||
following: isRemote ? false : !followee.getUser().isLocked,
|
requested: isRemote ? true : followee.getUser().isLocked,
|
||||||
requested: isRemote ? true : followee.getUser().isLocked,
|
showingReblogs: reblogs,
|
||||||
showingReblogs: reblogs,
|
notifying: notify,
|
||||||
notifying: notify,
|
languages: languages,
|
||||||
languages: languages,
|
})
|
||||||
})
|
.where(eq(Relationships.id, relationshipId));
|
||||||
.where(eq(Relationships.id, relationshipId))
|
|
||||||
.returning()
|
const updatedRelationship = await db.query.Relationships.findFirst({
|
||||||
)[0];
|
where: (rel, { eq }) => eq(rel.id, relationshipId),
|
||||||
|
extras: {
|
||||||
|
requestedBy:
|
||||||
|
sql<boolean>`(SELECT "requested" FROM "Relationships" WHERE "Relationships"."ownerId" = ${followee.id} AND "Relationships"."subjectId" = ${follower.id})`.as(
|
||||||
|
"requested_by",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updatedRelationship) {
|
||||||
|
throw new Error("Failed to update relationship");
|
||||||
|
}
|
||||||
|
|
||||||
if (isRemote) {
|
if (isRemote) {
|
||||||
// Federate
|
// Federate
|
||||||
|
|
@ -165,16 +176,29 @@ export const followRequestUser = async (
|
||||||
} to ${followee.getUri()}`,
|
} to ${followee.getUri()}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
await db
|
||||||
await db
|
.update(Relationships)
|
||||||
.update(Relationships)
|
.set({
|
||||||
.set({
|
following: false,
|
||||||
following: false,
|
requested: false,
|
||||||
requested: false,
|
})
|
||||||
})
|
.where(eq(Relationships.id, relationshipId));
|
||||||
.where(eq(Relationships.id, relationshipId))
|
|
||||||
.returning()
|
const result = await db.query.Relationships.findFirst({
|
||||||
)[0];
|
where: (rel, { eq }) => eq(rel.id, relationshipId),
|
||||||
|
extras: {
|
||||||
|
requestedBy:
|
||||||
|
sql<boolean>`(SELECT "requested" FROM "Relationships" WHERE "Relationships"."ownerId" = ${followee.id} AND "Relationships"."subjectId" = ${follower.id})`.as(
|
||||||
|
"requested_by",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
throw new Error("Failed to update relationship");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await db.insert(Notifications).values({
|
await db.insert(Notifications).values({
|
||||||
|
|
@ -458,13 +482,19 @@ export const retrieveToken = async (
|
||||||
export const getRelationshipToOtherUser = async (
|
export const getRelationshipToOtherUser = async (
|
||||||
user: User,
|
user: User,
|
||||||
other: User,
|
other: User,
|
||||||
): Promise<InferSelectModel<typeof Relationships>> => {
|
): Promise<Relationship> => {
|
||||||
const foundRelationship = await db.query.Relationships.findFirst({
|
const foundRelationship = await db.query.Relationships.findFirst({
|
||||||
where: (relationship, { and, eq }) =>
|
where: (relationship, { and, eq }) =>
|
||||||
and(
|
and(
|
||||||
eq(relationship.ownerId, user.id),
|
eq(relationship.ownerId, user.id),
|
||||||
eq(relationship.subjectId, other.id),
|
eq(relationship.subjectId, other.id),
|
||||||
),
|
),
|
||||||
|
extras: {
|
||||||
|
requestedBy:
|
||||||
|
sql<boolean>`(SELECT "requested" FROM "Relationships" WHERE "Relationships"."ownerId" = ${other.id} AND "Relationships"."subjectId" = ${user.id})`.as(
|
||||||
|
"requested_by",
|
||||||
|
),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!foundRelationship) {
|
if (!foundRelationship) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { applyConfig, auth, handleZodError, qsQuery } from "@/api";
|
import { applyConfig, auth, handleZodError, qsQuery } from "@/api";
|
||||||
import { errorResponse, jsonResponse } from "@/response";
|
import { errorResponse, jsonResponse } from "@/response";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
|
import { sql } from "drizzle-orm";
|
||||||
import type { Hono } from "hono";
|
import type { Hono } from "hono";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import {
|
import {
|
||||||
|
|
@ -8,7 +9,7 @@ import {
|
||||||
relationshipToAPI,
|
relationshipToAPI,
|
||||||
} from "~/database/entities/Relationship";
|
} from "~/database/entities/Relationship";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { RolePermissions } from "~/drizzle/schema";
|
import { Relationships, RolePermissions } from "~/drizzle/schema";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -54,6 +55,12 @@ export default (app: Hono) =>
|
||||||
inArray(relationship.subjectId, ids),
|
inArray(relationship.subjectId, ids),
|
||||||
eq(relationship.ownerId, self.id),
|
eq(relationship.ownerId, self.id),
|
||||||
),
|
),
|
||||||
|
extras: {
|
||||||
|
requestedBy:
|
||||||
|
sql<boolean>`(SELECT "requested" FROM "Relationships" WHERE "Relationships"."ownerId" = ${Relationships.id} AND "Relationships"."subjectId" = ${self.id})`.as(
|
||||||
|
"requested_by",
|
||||||
|
),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const missingIds = ids.filter(
|
const missingIds = ids.filter(
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ export type Relationship = {
|
||||||
muting: boolean;
|
muting: boolean;
|
||||||
muting_notifications: boolean;
|
muting_notifications: boolean;
|
||||||
requested: boolean;
|
requested: boolean;
|
||||||
|
requested_by: boolean;
|
||||||
domain_blocking: boolean;
|
domain_blocking: boolean;
|
||||||
showing_reblogs: boolean;
|
showing_reblogs: boolean;
|
||||||
endorsed: boolean;
|
endorsed: boolean;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue