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) => {
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 (

View File

@ -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 (

View File

@ -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 });
},

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.
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();

View File

@ -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 })

View File

@ -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 {

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({
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;
}