mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-05 10:22:31 +01:00
Move UserSettings to own entity
This commit is contained in:
parent
d407d8ebe7
commit
803ab38fad
2784
assets/schemas.json
2784
assets/schemas.json
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@
|
||||
"start:gateway": "node dist/gateway/start.js",
|
||||
"build": "tsc -p .",
|
||||
"setup": "npm run build && npm run generate:schema",
|
||||
"generate:db": "node scripts/syncronise.js",
|
||||
"sync:db": "npm run build && node scripts/syncronise.js",
|
||||
"generate:rights": "node scripts/rights.js",
|
||||
"generate:schema": "node scripts/schema.js",
|
||||
"generate:client": "node scripts/client.js",
|
||||
|
@ -7,7 +7,7 @@ const router = Router();
|
||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
||||
const user = await User.findOneOrFail({
|
||||
where: { id: req.user_id },
|
||||
select: ["settings"],
|
||||
relations: ["settings"],
|
||||
});
|
||||
return res.json(user.settings);
|
||||
});
|
||||
@ -21,10 +21,12 @@ router.patch(
|
||||
|
||||
const user = await User.findOneOrFail({
|
||||
where: { id: req.user_id, bot: false },
|
||||
select: ["settings"]
|
||||
relations: ["settings"]
|
||||
});
|
||||
user.settings = OrmUtils.mergeDeep(user.settings, body);
|
||||
User.update({ id: user.id }, { settings: user.settings });
|
||||
|
||||
user.settings.assign(body);
|
||||
|
||||
user.settings.save();
|
||||
|
||||
res.json(user.settings);
|
||||
},
|
||||
|
@ -18,9 +18,10 @@ import {
|
||||
PrivateSessionProjection,
|
||||
MemberPrivateProjection,
|
||||
PresenceUpdateEvent,
|
||||
UserSettings,
|
||||
IdentifySchema,
|
||||
DefaultUserGuildSettings,
|
||||
UserGuildSettings,
|
||||
IdentifySchema,
|
||||
} from "@fosscord/util";
|
||||
import { Send } from "../util/Send";
|
||||
import { CLOSECODES, OPCODES } from "../util/Constants";
|
||||
@ -60,7 +61,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
|
||||
await Promise.all([
|
||||
User.findOneOrFail({
|
||||
where: { id: this.user_id },
|
||||
relations: ["relationships", "relationships.to"],
|
||||
relations: ["relationships", "relationships.to", "settings"],
|
||||
select: [...PrivateUserProjection, "relationships"],
|
||||
}),
|
||||
ReadState.find({ where: { user_id: this.user_id } }),
|
||||
@ -105,6 +106,10 @@ export async function onIdentify(this: WebSocket, data: Payload) {
|
||||
]);
|
||||
|
||||
if (!user) return this.close(CLOSECODES.Authentication_failed);
|
||||
if (!user.settings) {
|
||||
user.settings = new UserSettings();
|
||||
await user.settings.save();
|
||||
}
|
||||
|
||||
if (!identify.intents) identify.intents = BigInt("0x6ffffffff");
|
||||
this.intents = new Intents(identify.intents);
|
||||
|
@ -62,7 +62,11 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
|
||||
}
|
||||
|
||||
// 'Fix' for this one voice state error. TODO: Find out why this is sent
|
||||
if (!voiceState.guild_id) return;
|
||||
// It seems to be sent on client load,
|
||||
// so maybe its trying to find which server you were connected to before disconnecting, if any?
|
||||
if (body.guild_id == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO the member should only have these properties: hoisted_role, deaf, joined_at, mute, roles, user
|
||||
//TODO the member.user should only have these properties: avatar, discriminator, id, username
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { GuildDefaults } from ".";
|
||||
import { GuildDefaults, UserDefaults } from ".";
|
||||
|
||||
export class DefaultsConfiguration {
|
||||
guild: GuildDefaults = new GuildDefaults();
|
||||
user: UserDefaults = new UserDefaults();
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
export class UserDefaults {
|
||||
premium: boolean = false;
|
||||
premium_type: number = 2;
|
||||
verified: boolean = true;
|
||||
}
|
@ -1 +1,2 @@
|
||||
export * from "./GuildDefaults";
|
||||
export * from "./UserDefaults";
|
||||
|
@ -110,7 +110,7 @@ export class Guild extends BaseClass {
|
||||
max_presences?: number;
|
||||
|
||||
@Column({ nullable: true })
|
||||
max_video_channel_users?: number; // ? default: 25, is this max 25 streaming or watching
|
||||
max_video_channel_users?: number;
|
||||
|
||||
@Column({ nullable: true })
|
||||
member_count?: number;
|
||||
@ -286,6 +286,10 @@ export class Guild extends BaseClass {
|
||||
// only for developer portal
|
||||
permissions?: number;
|
||||
|
||||
//new guild settings, 11/08/2022:
|
||||
@Column({ nullable: true })
|
||||
premium_progress_bar_enabled: boolean;
|
||||
|
||||
static async createGuild(body: {
|
||||
name?: string;
|
||||
icon?: string | null;
|
||||
|
@ -6,11 +6,15 @@ import {
|
||||
FindOneOptions,
|
||||
JoinColumn,
|
||||
OneToMany,
|
||||
OneToOne,
|
||||
} from "typeorm";
|
||||
import { BaseClass } from "./BaseClass";
|
||||
import { BitField } from "../util/BitField";
|
||||
import { Relationship } from "./Relationship";
|
||||
import { ConnectedAccount } from "./ConnectedAccount";
|
||||
import { Member } from "./Member";
|
||||
import { UserSettings } from "./UserSettings";
|
||||
import { Session } from "./Session";
|
||||
import {
|
||||
Config,
|
||||
FieldErrors,
|
||||
@ -18,7 +22,6 @@ import {
|
||||
trimSpecial,
|
||||
adjustEmail,
|
||||
} from "..";
|
||||
import { Member, Session } from ".";
|
||||
|
||||
export enum PublicUserEnum {
|
||||
username,
|
||||
@ -46,7 +49,7 @@ export enum PrivateUserEnum {
|
||||
purchased_flags,
|
||||
premium_usage_flags,
|
||||
disabled,
|
||||
settings,
|
||||
// settings, // now a relation
|
||||
// locale
|
||||
}
|
||||
export type PrivateUserKeys = keyof typeof PrivateUserEnum | PublicUserKeys;
|
||||
@ -89,67 +92,67 @@ export class User extends BaseClass {
|
||||
phone?: string; // phone number of the user
|
||||
|
||||
@Column({ select: false })
|
||||
desktop: boolean; // if the user has desktop app installed
|
||||
desktop: boolean = false; // if the user has desktop app installed
|
||||
|
||||
@Column({ select: false })
|
||||
mobile: boolean; // if the user has mobile app installed
|
||||
mobile: boolean = false; // if the user has mobile app installed
|
||||
|
||||
@Column()
|
||||
premium: boolean; // if user bought individual premium
|
||||
premium: boolean = false; // if user bought individual premium
|
||||
|
||||
@Column()
|
||||
premium_type: number; // individual premium level
|
||||
premium_type: number = 0; // individual premium level
|
||||
|
||||
@Column()
|
||||
bot: boolean; // if user is bot
|
||||
bot: boolean = false; // if user is bot
|
||||
|
||||
@Column()
|
||||
bio: string; // short description of the user (max 190 chars -> should be configurable)
|
||||
bio: string = ""; // short description of the user (max 190 chars -> should be configurable)
|
||||
|
||||
@Column()
|
||||
system: boolean; // shouldn't be used, the api sends this field type true, if the generated message comes from a system generated author
|
||||
system: boolean = false; // shouldn't be used, the api sends this field type true, if the generated message comes from a system generated author
|
||||
|
||||
@Column({ select: false })
|
||||
nsfw_allowed: boolean; // if the user can do age-restricted actions (NSFW channels/guilds/commands)
|
||||
nsfw_allowed: boolean = true; // if the user can do age-restricted actions (NSFW channels/guilds/commands) // TODO: depending on age
|
||||
|
||||
@Column({ select: false })
|
||||
mfa_enabled: boolean; // if multi factor authentication is enabled
|
||||
mfa_enabled: boolean = false; // if multi factor authentication is enabled
|
||||
|
||||
@Column({ select: false, nullable: true })
|
||||
totp_secret?: string;
|
||||
totp_secret?: string = "";
|
||||
|
||||
@Column({ nullable: true, select: false })
|
||||
totp_last_ticket?: string;
|
||||
totp_last_ticket?: string = "";
|
||||
|
||||
@Column()
|
||||
created_at: Date; // registration date
|
||||
created_at: Date = new Date(); // registration date
|
||||
|
||||
@Column({ nullable: true })
|
||||
premium_since: Date; // premium date
|
||||
premium_since: Date = new Date(); // premium date
|
||||
|
||||
@Column({ select: false })
|
||||
verified: boolean; // if the user is offically verified
|
||||
verified: boolean = true; // email is verified
|
||||
|
||||
@Column()
|
||||
disabled: boolean; // if the account is disabled
|
||||
disabled: boolean = false; // if the account is disabled
|
||||
|
||||
@Column()
|
||||
deleted: boolean; // if the user was deleted
|
||||
deleted: boolean = false; // if the user was deleted
|
||||
|
||||
@Column({ nullable: true, select: false })
|
||||
email?: string; // email of the user
|
||||
|
||||
@Column()
|
||||
flags: string; // UserFlags
|
||||
flags: string = "0"; // UserFlags // TODO: generate
|
||||
|
||||
@Column()
|
||||
public_flags: number;
|
||||
public_flags: number = 0;
|
||||
|
||||
@Column()
|
||||
purchased_flags: number;
|
||||
purchased_flags: number = 0;
|
||||
|
||||
@Column()
|
||||
premium_usage_flags: number;
|
||||
premium_usage_flags: number = 0;
|
||||
|
||||
@Column({ type: "bigint" })
|
||||
rights: string; // Rights
|
||||
@ -186,14 +189,19 @@ export class User extends BaseClass {
|
||||
};
|
||||
|
||||
@Column({ type: "simple-array", select: false })
|
||||
fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts
|
||||
fingerprints: string[] = []; // array of fingerprints -> used to prevent multiple accounts
|
||||
|
||||
@Column({ type: "simple-json", select: false })
|
||||
@OneToOne(() => UserSettings, {
|
||||
cascade: true,
|
||||
orphanedRowAction: "delete",
|
||||
eager: false
|
||||
})
|
||||
@JoinColumn()
|
||||
settings: UserSettings;
|
||||
|
||||
// workaround to prevent fossord-unaware clients from deleting settings not used by them
|
||||
@Column({ type: "simple-json", select: false })
|
||||
extended_settings: string;
|
||||
extended_settings: string = "{}";
|
||||
|
||||
// TODO: I don't like this method?
|
||||
validate() {
|
||||
@ -327,40 +335,25 @@ export class User extends BaseClass {
|
||||
req.language === "en" ? "en-US" : req.language || "en-US";
|
||||
|
||||
const user = User.create({
|
||||
created_at: new Date(),
|
||||
username: username,
|
||||
discriminator,
|
||||
id: Snowflake.generate(),
|
||||
bot: false,
|
||||
system: false,
|
||||
premium_since: new Date(),
|
||||
desktop: false,
|
||||
mobile: false,
|
||||
premium: true,
|
||||
premium_type: 2,
|
||||
bio: "",
|
||||
mfa_enabled: false,
|
||||
verified: true,
|
||||
disabled: false,
|
||||
deleted: false,
|
||||
email: email,
|
||||
rights: Config.get().register.defaultRights,
|
||||
nsfw_allowed: true, // TODO: depending on age
|
||||
public_flags: 0,
|
||||
flags: "0", // TODO: generate
|
||||
data: {
|
||||
hash: password,
|
||||
valid_tokens_since: new Date(),
|
||||
},
|
||||
settings: { ...defaultSettings, locale: language },
|
||||
purchased_flags: 5, // TODO: idk what the values for this are
|
||||
premium_usage_flags: 2, // TODO: idk what the values for this are
|
||||
extended_settings: "", // TODO: was {}
|
||||
fingerprints: [],
|
||||
extended_settings: "{}",
|
||||
premium_type: Config.get().defaults.user.premium_type,
|
||||
premium: Config.get().defaults.user.premium,
|
||||
verified: Config.get().defaults.user.verified,
|
||||
settings: { ...new UserSettings(), locale: language }
|
||||
});
|
||||
|
||||
user.validate();
|
||||
await user.save();
|
||||
await user.settings.save();
|
||||
|
||||
setImmediate(async () => {
|
||||
if (Config.get().guild.autoJoin.enabled) {
|
||||
@ -374,94 +367,6 @@ export class User extends BaseClass {
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultSettings: UserSettings = {
|
||||
afk_timeout: 3600,
|
||||
allow_accessibility_detection: true,
|
||||
animate_emoji: true,
|
||||
animate_stickers: 0,
|
||||
contact_sync_enabled: false,
|
||||
convert_emoticons: false,
|
||||
custom_status: null,
|
||||
default_guilds_restricted: false,
|
||||
detect_platform_accounts: false,
|
||||
developer_mode: true,
|
||||
disable_games_tab: true,
|
||||
enable_tts_command: false,
|
||||
explicit_content_filter: 0,
|
||||
friend_source_flags: { all: true },
|
||||
gateway_connected: false,
|
||||
gif_auto_play: true,
|
||||
guild_folders: [],
|
||||
guild_positions: [],
|
||||
inline_attachment_media: true,
|
||||
inline_embed_media: true,
|
||||
locale: "en-US",
|
||||
message_display_compact: false,
|
||||
native_phone_integration_enabled: true,
|
||||
render_embeds: true,
|
||||
render_reactions: true,
|
||||
restricted_guilds: [],
|
||||
show_current_game: true,
|
||||
status: "online",
|
||||
stream_notifications_enabled: false,
|
||||
theme: "dark",
|
||||
timezone_offset: 0, // TODO: timezone from request
|
||||
|
||||
banner_color: null,
|
||||
friend_discovery_flags: 0,
|
||||
view_nsfw_guilds: true,
|
||||
passwordless: false,
|
||||
};
|
||||
|
||||
export interface UserSettings {
|
||||
afk_timeout: number;
|
||||
allow_accessibility_detection: boolean;
|
||||
animate_emoji: boolean;
|
||||
animate_stickers: number;
|
||||
contact_sync_enabled: boolean;
|
||||
convert_emoticons: boolean;
|
||||
custom_status: {
|
||||
emoji_id?: string;
|
||||
emoji_name?: string;
|
||||
expires_at?: number;
|
||||
text?: string;
|
||||
} | null;
|
||||
default_guilds_restricted: boolean;
|
||||
detect_platform_accounts: boolean;
|
||||
developer_mode: boolean;
|
||||
disable_games_tab: boolean;
|
||||
enable_tts_command: boolean;
|
||||
explicit_content_filter: number;
|
||||
friend_source_flags: { all: boolean; };
|
||||
gateway_connected: boolean;
|
||||
gif_auto_play: boolean;
|
||||
// every top guild is displayed as a "folder"
|
||||
guild_folders: {
|
||||
color?: number;
|
||||
guild_ids: string[];
|
||||
id?: number;
|
||||
name?: string;
|
||||
}[];
|
||||
guild_positions: string[]; // guild ids ordered by position
|
||||
inline_attachment_media: boolean;
|
||||
inline_embed_media: boolean;
|
||||
locale: string; // en_US
|
||||
message_display_compact: boolean;
|
||||
native_phone_integration_enabled: boolean;
|
||||
render_embeds: boolean;
|
||||
render_reactions: boolean;
|
||||
restricted_guilds: string[];
|
||||
show_current_game: boolean;
|
||||
status: "online" | "offline" | "dnd" | "idle" | "invisible";
|
||||
stream_notifications_enabled: boolean;
|
||||
theme: "dark" | "light"; // dark
|
||||
timezone_offset: number; // e.g -60
|
||||
banner_color: string | null;
|
||||
friend_discovery_flags: number;
|
||||
view_nsfw_guilds: boolean;
|
||||
passwordless: boolean;
|
||||
}
|
||||
|
||||
export const CUSTOM_USER_FLAG_OFFSET = BigInt(1) << BigInt(32);
|
||||
|
||||
export class UserFlags extends BitField {
|
||||
|
119
src/util/entities/UserSettings.ts
Normal file
119
src/util/entities/UserSettings.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { BaseClassWithoutId } from "./BaseClass";
|
||||
|
||||
@Entity("user_settings")
|
||||
export class UserSettings extends BaseClassWithoutId {
|
||||
@PrimaryGeneratedColumn()
|
||||
index: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
afk_timeout: number = 3600;
|
||||
|
||||
@Column({ nullable: true })
|
||||
allow_accessibility_detection: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
animate_emoji: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
animate_stickers: number = 0;
|
||||
|
||||
@Column({ nullable: true })
|
||||
contact_sync_enabled: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
convert_emoticons: boolean = false;
|
||||
|
||||
@Column({ nullable: true, type: "simple-json" })
|
||||
custom_status: CustomStatus | null = null;
|
||||
|
||||
@Column({ nullable: true })
|
||||
default_guilds_restricted: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
detect_platform_accounts: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
developer_mode: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
disable_games_tab: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
enable_tts_command: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
explicit_content_filter: number = 0;
|
||||
|
||||
@Column({ nullable: true, type: "simple-json" })
|
||||
friend_source_flags: FriendSourceFlags = { all: true };
|
||||
|
||||
@Column({ nullable: true })
|
||||
gateway_connected: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
gif_auto_play: boolean = false;
|
||||
|
||||
@Column({ nullable: true, type: "simple-json" })
|
||||
guild_folders: GuildFolder[] = []; // every top guild is displayed as a "folder"
|
||||
|
||||
@Column({ nullable: true, type: "simple-json" })
|
||||
guild_positions: string[] = []; // guild ids ordered by position
|
||||
|
||||
@Column({ nullable: true })
|
||||
inline_attachment_media: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
inline_embed_media: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
locale: string = "en-US"; // en_US
|
||||
|
||||
@Column({ nullable: true })
|
||||
message_display_compact: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
native_phone_integration_enabled: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
render_embeds: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
render_reactions: boolean = true;
|
||||
|
||||
@Column({ nullable: true, type: "simple-json" })
|
||||
restricted_guilds: string[] = [];
|
||||
|
||||
@Column({ nullable: true })
|
||||
show_current_game: boolean = true;
|
||||
|
||||
@Column({ nullable: true })
|
||||
status: "online" | "offline" | "dnd" | "idle" | "invisible" = "online";
|
||||
|
||||
@Column({ nullable: true })
|
||||
stream_notifications_enabled: boolean = false;
|
||||
|
||||
@Column({ nullable: true })
|
||||
theme: "dark" | "light" = "dark"; // dark
|
||||
|
||||
@Column({ nullable: true })
|
||||
timezone_offset: number = 0; // e.g -60
|
||||
}
|
||||
|
||||
interface CustomStatus {
|
||||
emoji_id?: string;
|
||||
emoji_name?: string;
|
||||
expires_at?: number;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
interface GuildFolder {
|
||||
color: number;
|
||||
guild_ids: string[];
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface FriendSourceFlags {
|
||||
all: boolean
|
||||
}
|
@ -30,4 +30,5 @@ export * from "./VoiceState";
|
||||
export * from "./Webhook";
|
||||
export * from "./ClientRelease";
|
||||
export * from "./BackupCodes";
|
||||
export * from "./Note";
|
||||
export * from "./Note";
|
||||
export * from "./UserSettings";
|
||||
|
Loading…
Reference in New Issue
Block a user