diff --git a/src/api/routes/users/@me/settings-proto/1.ts b/src/api/routes/users/@me/settings-proto/1.ts index 334a7015..2eea291a 100644 --- a/src/api/routes/users/@me/settings-proto/1.ts +++ b/src/api/routes/users/@me/settings-proto/1.ts @@ -50,7 +50,7 @@ router.get( }, }), async (req: Request, res: Response) => { - const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); + const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); res.json({ settings: PreloadedUserSettings.toBase64( @@ -102,7 +102,7 @@ router.get( }, }), async (req: Request, res: Response) => { - const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); + const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); res.json({ settings: PreloadedUserSettings.toJson(userSettings.userSettings!), @@ -155,7 +155,7 @@ async function patchUserSettings( required_data_version: number | undefined, atomic: boolean = false, ) { - const userSettings = await UserSettingsProtos.getOrCreate(userId); + const userSettings = await UserSettingsProtos.getOrDefault(userId); let settings = userSettings.userSettings!; if ( diff --git a/src/api/routes/users/@me/settings-proto/2.ts b/src/api/routes/users/@me/settings-proto/2.ts index 9c989758..34cd3bfc 100644 --- a/src/api/routes/users/@me/settings-proto/2.ts +++ b/src/api/routes/users/@me/settings-proto/2.ts @@ -50,7 +50,7 @@ router.get( }, }), async (req: Request, res: Response) => { - const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); + const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); res.json({ settings: FrecencyUserSettings.toBase64( @@ -102,7 +102,7 @@ router.get( }, }), async (req: Request, res: Response) => { - const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); + const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); res.json({ settings: FrecencyUserSettings.toJson( @@ -157,7 +157,7 @@ async function patchUserSettings( required_data_version: number | undefined, atomic: boolean = false, ) { - const userSettings = await UserSettingsProtos.getOrCreate(userId); + const userSettings = await UserSettingsProtos.getOrDefault(userId); let settings = userSettings.frecencySettings!; if ( diff --git a/src/api/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts index b21b31ed..26d2f21b 100644 --- a/src/api/routes/users/@me/settings.ts +++ b/src/api/routes/users/@me/settings.ts @@ -17,7 +17,7 @@ */ import { route } from "@spacebar/api"; -import { User, UserSettingsSchema } from "@spacebar/util"; +import { User, UserSettings, UserSettingsSchema } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router({ mergeParams: true }); @@ -35,11 +35,8 @@ router.get( }, }), async (req: Request, res: Response) => { - const user = await User.findOneOrFail({ - where: { id: req.user_id }, - relations: ["settings"], - }); - return res.json(user.settings); + const settings = await UserSettings.getOrDefault(req.user_id) + return res.json(settings); }, ); @@ -68,11 +65,16 @@ router.patch( relations: ["settings"], }); - user.settings.assign(body); + if (!user.settings) + user.settings = UserSettings.create(body); + else + user.settings.assign(body); + if (body.guild_folders) user.settings.guild_folders = body.guild_folders; await user.settings.save(); + await user.save(); res.json({ ...user.settings, index: undefined }); }, diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts index 4bd41d21..74402bc8 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -358,7 +358,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { // so for instances that migrated, users may not have a `user_settings` row. let createUserSettingsTime: ElapsedTime | undefined = undefined; if (!user.settings) { - console.warn("[WARN] Creating new user settings!") + console.warn("[WARN] Creating new user settings!"); user.settings = new UserSettings(); await user.settings.save(); createUserSettingsTime = taskSw.getElapsedAndReset(); diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts index 840c028d..138a24c1 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts @@ -202,10 +202,10 @@ export class User extends BaseClass { @OneToOne(() => UserSettings, { cascade: true, orphanedRowAction: "delete", - eager: false, + nullable: true }) @JoinColumn() - settings: UserSettings; + settings?: UserSettings; // workaround to prevent fossord-unaware clients from deleting settings not used by them @Column({ type: "simple-json", select: false }) diff --git a/src/util/entities/UserSettings.ts b/src/util/entities/UserSettings.ts index 1a196871..6d842d6c 100644 --- a/src/util/entities/UserSettings.ts +++ b/src/util/entities/UserSettings.ts @@ -18,6 +18,7 @@ import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; import { BaseClassWithoutId } from "./BaseClass"; +import { User } from "./User"; @Entity({ name: "user_settings", @@ -124,6 +125,24 @@ export class UserSettings extends BaseClassWithoutId { @Column({ nullable: true }) view_nsfw_guilds: boolean = true; + + public static async getOrDefault(userId: string) { + // raw sql query + const userSettingsIndex = await User.getRepository() + .createQueryBuilder() + .select("settingsIndex") + .where('id = :id', { id: userId }) + .execute(); + + console.log(`[INFO/UserSettings] Fetched settings index for user ${userId}:`, userSettingsIndex); + + if (!userSettingsIndex) return new UserSettings(); + + const settings = await UserSettings.findOne({ where: { index: userSettingsIndex } }); + if (!settings) return new UserSettings(); + + return settings; + } } interface CustomStatus { diff --git a/src/util/entities/UserSettingsProtos.ts b/src/util/entities/UserSettingsProtos.ts index eb2a1871..e68fca57 100644 --- a/src/util/entities/UserSettingsProtos.ts +++ b/src/util/entities/UserSettingsProtos.ts @@ -118,7 +118,7 @@ export class UserSettingsProtos extends BaseClassWithoutId { } } - static async getOrCreate(user_id: string): Promise { + static async getOrDefault(user_id: string, save: boolean = false): Promise { const user = await User.findOneOrFail({ where: { id: user_id }, select: { settings: true }, @@ -158,7 +158,7 @@ export class UserSettingsProtos extends BaseClassWithoutId { modified = true; } - if (modified) userSettings = await userSettings.save(); + if (modified && save) userSettings = await userSettings.save(); return userSettings; }