Return defaults for missing {proto-,}settings

This commit is contained in:
Rory& 2025-10-11 06:31:02 +02:00
parent 0b2e8981c0
commit c0dfeaefb6
7 changed files with 39 additions and 18 deletions

View File

@ -50,7 +50,7 @@ router.get(
}, },
}), }),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); const userSettings = await UserSettingsProtos.getOrDefault(req.user_id);
res.json({ res.json({
settings: PreloadedUserSettings.toBase64( settings: PreloadedUserSettings.toBase64(
@ -102,7 +102,7 @@ router.get(
}, },
}), }),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); const userSettings = await UserSettingsProtos.getOrDefault(req.user_id);
res.json({ res.json({
settings: PreloadedUserSettings.toJson(userSettings.userSettings!), settings: PreloadedUserSettings.toJson(userSettings.userSettings!),
@ -155,7 +155,7 @@ async function patchUserSettings(
required_data_version: number | undefined, required_data_version: number | undefined,
atomic: boolean = false, atomic: boolean = false,
) { ) {
const userSettings = await UserSettingsProtos.getOrCreate(userId); const userSettings = await UserSettingsProtos.getOrDefault(userId);
let settings = userSettings.userSettings!; let settings = userSettings.userSettings!;
if ( if (

View File

@ -50,7 +50,7 @@ router.get(
}, },
}), }),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); const userSettings = await UserSettingsProtos.getOrDefault(req.user_id);
res.json({ res.json({
settings: FrecencyUserSettings.toBase64( settings: FrecencyUserSettings.toBase64(
@ -102,7 +102,7 @@ router.get(
}, },
}), }),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
const userSettings = await UserSettingsProtos.getOrCreate(req.user_id); const userSettings = await UserSettingsProtos.getOrDefault(req.user_id);
res.json({ res.json({
settings: FrecencyUserSettings.toJson( settings: FrecencyUserSettings.toJson(
@ -157,7 +157,7 @@ async function patchUserSettings(
required_data_version: number | undefined, required_data_version: number | undefined,
atomic: boolean = false, atomic: boolean = false,
) { ) {
const userSettings = await UserSettingsProtos.getOrCreate(userId); const userSettings = await UserSettingsProtos.getOrDefault(userId);
let settings = userSettings.frecencySettings!; let settings = userSettings.frecencySettings!;
if ( if (

View File

@ -17,7 +17,7 @@
*/ */
import { route } from "@spacebar/api"; import { route } from "@spacebar/api";
import { User, UserSettingsSchema } from "@spacebar/util"; import { User, UserSettings, UserSettingsSchema } from "@spacebar/util";
import { Request, Response, Router } from "express"; import { Request, Response, Router } from "express";
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });
@ -35,11 +35,8 @@ router.get(
}, },
}), }),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
const user = await User.findOneOrFail({ const settings = await UserSettings.getOrDefault(req.user_id)
where: { id: req.user_id }, return res.json(settings);
relations: ["settings"],
});
return res.json(user.settings);
}, },
); );
@ -68,11 +65,16 @@ router.patch(
relations: ["settings"], relations: ["settings"],
}); });
user.settings.assign(body); if (!user.settings)
user.settings = UserSettings.create(body);
else
user.settings.assign(body);
if (body.guild_folders) if (body.guild_folders)
user.settings.guild_folders = body.guild_folders; user.settings.guild_folders = body.guild_folders;
await user.settings.save(); await user.settings.save();
await user.save();
res.json({ ...user.settings, index: undefined }); res.json({ ...user.settings, index: undefined });
}, },

View File

@ -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. // so for instances that migrated, users may not have a `user_settings` row.
let createUserSettingsTime: ElapsedTime | undefined = undefined; let createUserSettingsTime: ElapsedTime | undefined = undefined;
if (!user.settings) { if (!user.settings) {
console.warn("[WARN] Creating new user settings!") console.warn("[WARN] Creating new user settings!");
user.settings = new UserSettings(); user.settings = new UserSettings();
await user.settings.save(); await user.settings.save();
createUserSettingsTime = taskSw.getElapsedAndReset(); createUserSettingsTime = taskSw.getElapsedAndReset();

View File

@ -202,10 +202,10 @@ export class User extends BaseClass {
@OneToOne(() => UserSettings, { @OneToOne(() => UserSettings, {
cascade: true, cascade: true,
orphanedRowAction: "delete", orphanedRowAction: "delete",
eager: false, nullable: true
}) })
@JoinColumn() @JoinColumn()
settings: UserSettings; settings?: UserSettings;
// workaround to prevent fossord-unaware clients from deleting settings not used by them // workaround to prevent fossord-unaware clients from deleting settings not used by them
@Column({ type: "simple-json", select: false }) @Column({ type: "simple-json", select: false })

View File

@ -18,6 +18,7 @@
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { BaseClassWithoutId } from "./BaseClass"; import { BaseClassWithoutId } from "./BaseClass";
import { User } from "./User";
@Entity({ @Entity({
name: "user_settings", name: "user_settings",
@ -124,6 +125,24 @@ export class UserSettings extends BaseClassWithoutId {
@Column({ nullable: true }) @Column({ nullable: true })
view_nsfw_guilds: boolean = 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 { interface CustomStatus {

View File

@ -118,7 +118,7 @@ export class UserSettingsProtos extends BaseClassWithoutId {
} }
} }
static async getOrCreate(user_id: string): Promise<UserSettingsProtos> { static async getOrDefault(user_id: string, save: boolean = false): Promise<UserSettingsProtos> {
const user = await User.findOneOrFail({ const user = await User.findOneOrFail({
where: { id: user_id }, where: { id: user_id },
select: { settings: true }, select: { settings: true },
@ -158,7 +158,7 @@ export class UserSettingsProtos extends BaseClassWithoutId {
modified = true; modified = true;
} }
if (modified) userSettings = await userSettings.save(); if (modified && save) userSettings = await userSettings.save();
return userSettings; return userSettings;
} }