Add new follow API endpoint

This commit is contained in:
Jesse Wierzbinski 2023-09-21 17:18:05 -10:00
parent 36b682d662
commit a9688b8178
7 changed files with 275 additions and 30 deletions

View file

@ -0,0 +1,116 @@
import {
BaseEntity,
Column,
CreateDateColumn,
Entity,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from "typeorm";
import { User } from "./User";
import { APIRelationship } from "~types/entities/relationship";
/**
* Stores Mastodon API relationships
*/
@Entity({
name: "relationships",
})
export class Relationship extends BaseEntity {
@PrimaryGeneratedColumn("uuid")
id!: string;
@ManyToOne(() => User, user => user.relationships)
owner!: User;
@ManyToOne(() => User)
subject!: User;
@Column("varchar")
following!: boolean;
@Column("varchar")
showing_reblogs!: boolean;
@Column("varchar")
notifying!: boolean;
@Column("varchar")
followed_by!: boolean;
@Column("varchar")
blocking!: boolean;
@Column("varchar")
blocked_by!: boolean;
@Column("varchar")
muting!: boolean;
@Column("varchar")
muting_notifications!: boolean;
@Column("varchar")
requested!: boolean;
@Column("varchar")
domain_blocking!: boolean;
@Column("varchar")
endorsed!: boolean;
@Column("jsonb")
languages!: string[];
@Column("varchar")
note!: string;
@CreateDateColumn()
created_at!: Date;
@UpdateDateColumn()
updated_at!: Date;
static async createNew(owner: User, other: User) {
const newRela = new Relationship();
newRela.owner = owner;
newRela.subject = other;
newRela.languages = [];
newRela.following = false;
newRela.showing_reblogs = false;
newRela.notifying = false;
newRela.followed_by = false;
newRela.blocking = false;
newRela.blocked_by = false;
newRela.muting = false;
newRela.muting_notifications = false;
newRela.requested = false;
newRela.domain_blocking = false;
newRela.endorsed = false;
newRela.note = "";
await newRela.save();
return newRela;
}
// eslint-disable-next-line @typescript-eslint/require-await
async toAPI(): Promise<APIRelationship> {
return {
blocked_by: this.blocked_by,
blocking: this.blocking,
domain_blocking: this.domain_blocking,
endorsed: this.endorsed,
followed_by: this.followed_by,
following: this.following,
id: this.subject.id,
muting: this.muting,
muting_notifications: this.muting_notifications,
notifying: this.notifying,
requested: this.requested,
showing_reblogs: this.showing_reblogs,
languages: this.languages,
note: this.note,
};
}
}

View file

@ -7,6 +7,7 @@ import {
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from "typeorm";
@ -17,6 +18,7 @@ import { RawObject } from "./RawObject";
import { Token } from "./Token";
import { Status } from "./Status";
import { APISource } from "~types/entities/source";
import { Relationship } from "./Relationship";
const config = getConfig();
@ -35,9 +37,7 @@ export class User extends BaseEntity {
})
username!: string;
@Column("varchar", {
unique: true,
})
@Column("varchar")
display_name!: string;
@Column("varchar")
@ -79,17 +79,12 @@ export class User extends BaseEntity {
@Column("varchar")
private_key!: string;
@OneToMany(() => Relationship, relationship => relationship.owner)
relationships!: Relationship[];
@ManyToOne(() => RawActor, actor => actor.id)
actor!: RawActor;
@ManyToMany(() => RawActor, actor => actor.id)
@JoinTable()
following!: RawActor[];
@ManyToMany(() => RawActor, actor => actor.id)
@JoinTable()
followers!: RawActor[];
@ManyToMany(() => RawObject, object => object.id)
@JoinTable()
pinned_notes!: RawObject[];
@ -98,8 +93,7 @@ export class User extends BaseEntity {
return await User.createQueryBuilder("user")
// Objects is a many-to-many relationship
.leftJoinAndSelect("user.actor", "actor")
.leftJoinAndSelect("user.following", "following")
.leftJoinAndSelect("user.followers", "followers")
.leftJoinAndSelect("user.relationships", "relationships")
.where("actor.data @> :data", {
data: JSON.stringify({
id,
@ -128,6 +122,8 @@ export class User extends BaseEntity {
user.avatar = data.avatar ?? config.defaults.avatar;
user.header = data.header ?? config.defaults.avatar;
user.relationships = [];
user.source = {
language: null,
note: "",
@ -136,9 +132,6 @@ export class User extends BaseEntity {
fields: [],
};
user.followers = [];
user.following = [];
await user.generateKeys();
await user.updateActor();
@ -146,6 +139,22 @@ export class User extends BaseEntity {
return user;
}
async getRelationshipToOtherUser(other: User) {
const relationship = await Relationship.findOne({
where: {
owner: {
id: this.id,
},
subject: {
id: other.id,
},
},
relations: ["owner", "subject"],
});
return relationship;
}
async selfDestruct() {
// Clean up tokens
const tokens = await Token.findBy({
@ -164,6 +173,26 @@ export class User extends BaseEntity {
await Promise.all(tokens.map(async token => await token.remove()));
await Promise.all(statuses.map(async status => await status.remove()));
// Get relationships
const relationships = await this.getRelationships();
// Delete them all
await Promise.all(
relationships.map(async relationship => await relationship.remove())
);
}
async getRelationships() {
const relationships = await Relationship.find({
where: {
owner: {
id: this.id,
},
},
relations: ["subject"],
});
return relationships;
}
async updateActor() {