spacebar/src/models/User.ts

230 lines
6.1 KiB
TypeScript

import { Activity, ActivitySchema } from "./Activity";
import { ClientStatus, Status } from "./Status";
import { Schema, Types, Document } from "mongoose";
import db from "../util/Database";
import toBigInt from "../util/toBigInt";
export const PublicUserProjection = {
username: true,
discriminator: true,
id: true,
public_flags: true,
avatar: true,
};
export interface User {
id: string;
username: string; // username max length 32, min 2
discriminator: string; // #0001 4 digit long string from #0001 - #9999
avatar: string | null; // hash of the user avatar
phone: string | null; // phone number of the user
desktop: boolean; // if the user has desktop app installed
mobile: boolean; // if the user has mobile app installed
premium: boolean; // if user bought nitro
premium_type: number; // nitro level
bot: boolean; // if user is bot
system: boolean; // shouldn't be used, the api sents this field type true, if the genetaed message comes from a system generated author
nsfw_allowed: boolean; // if the user is older than 18 (resp. Config)
mfa_enabled: boolean; // if multi factor authentication is enabled
created_at: Date; // registration date
verified: boolean; // if the user is offically verified
email: string | null; // email of the user
flags: bigint; // UserFlags
public_flags: bigint;
user_settings: UserSettings;
guilds: string[]; // array of guild ids the user is part of
user_data: UserData;
presence: {
status: Status;
activities: Activity[];
client_status: ClientStatus;
};
}
// Privat user data:
export interface UserData {
valid_tokens_since: Date; // all tokens with a previous issue date are invalid
relationships: Relationship[];
connected_accounts: ConnectedAccount[];
hash: string; // hash of the password, salt is saved in password (bcrypt)
fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts
}
export interface UserDocument extends User, Document {
id: string;
}
export interface PublicUser {
id: string;
discriminator: string;
username: string;
avatar: string | null;
public_flags: bigint;
}
export interface ConnectedAccount {
access_token: string;
friend_sync: boolean;
id: string;
name: string;
revoked: boolean;
show_activity: boolean;
type: string;
verifie: boolean;
visibility: number;
}
export interface Relationship {
id: string;
nickname?: string;
type: number;
user_id: string;
}
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 | null;
emoji_name: string | null;
expires_at: number | null;
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;
guild_folders: // every top guild is displayed as a "folder"
{
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";
stream_notifications_enabled: boolean;
theme: "dark" | "white"; // dark
timezone_offset: number; // e.g -60
}
export const UserSchema = new Schema({
id: String,
username: String,
discriminator: String,
avatar: String,
phone: String,
desktop: Boolean,
mobile: Boolean,
premium: Boolean,
premium_type: Number,
bot: Boolean,
system: Boolean,
nsfw_allowed: Boolean,
mfa_enabled: Boolean,
created_at: Date,
verified: Boolean,
email: String,
flags: { type: String, get: toBigInt }, // TODO: automatically convert Types.Long to BitField of UserFlags
public_flags: { type: String, get: toBigInt },
guilds: [String], // array of guild ids the user is part of
user_data: {
fingerprints: [String],
hash: String, // hash of the password, salt is saved in password (bcrypt)
valid_tokens_since: Date, // all tokens with a previous issue date are invalid
relationships: [
{
id: String,
nickname: String,
type: Number,
user_id: String,
},
],
connected_accounts: [
{
access_token: String,
friend_sync: Boolean,
id: String,
name: String,
revoked: Boolean,
show_activity: Boolean,
type: String,
verifie: Boolean,
visibility: Number,
},
],
},
user_settings: {
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,
},
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: String,
stream_notifications_enabled: Boolean,
theme: String, // dark
timezone_offset: Number, // e.g -60,
},
presence: {
status: String,
activities: [ActivitySchema],
client_status: ClientStatus,
},
});
// @ts-ignore
export const UserModel = db.model<UserDocument>("User", UserSchema, "users");