import { Column, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; import { Activity } from "./Activity"; import { BaseClass } from "./BaseClass"; import { ClientStatus, Status } from "./Status"; import { validateOrReject, IsInt, IsEmail, IsPhoneNumber, IsBoolean, IsString, ValidateNested } from "class-validator"; export const PublicUserProjection = { username: true, discriminator: true, id: true, public_flags: true, avatar: true, accent_color: true, banner: true, bio: true, bot: true, }; export class User extends BaseClass { @Column() @IsString() username: string; // username max length 32, min 2 (should be configurable) @Column() @IsInt() discriminator: string; // #0001 4 digit long string from #0001 - #9999 @Column() @IsString() avatar: string | null; // hash of the user avatar @Column() @IsInt() accent_color: number | null; // banner color of user @Column() banner: string | null; // hash of the user banner @Column() @IsPhoneNumber() phone: string | null; // phone number of the user @Column() @IsBoolean() desktop: boolean; // if the user has desktop app installed @Column() @IsBoolean() mobile: boolean; // if the user has mobile app installed @Column() @IsBoolean() premium: boolean; // if user bought nitro @Column() premium_type: number; // nitro level @Column() @IsBoolean() bot: boolean; // if user is bot @Column() bio: string; // short description of the user (max 190 chars -> should be configurable) @Column() @IsBoolean() system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author @Column() @IsBoolean() nsfw_allowed: boolean; // if the user is older than 18 (resp. Config) @Column() @IsBoolean() mfa_enabled: boolean; // if multi factor authentication is enabled @Column() created_at: Date; // registration date @Column() @IsBoolean() verified: boolean; // if the user is offically verified @Column() @IsBoolean() disabled: boolean; // if the account is disabled @Column() @IsBoolean() deleted: boolean; // if the user was deleted @Column() @IsEmail() email: string | null; // email of the user @Column() flags: bigint; // UserFlags @Column() public_flags: bigint; @Column("simple-array") // string in simple-array must not contain commas @IsString({ each: true }) guilds: string[]; // array of guild ids the user is part of @Column("simple-json") @ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects user_data: { valid_tokens_since: Date; // all tokens with a previous issue date are invalid hash: string; // hash of the password, salt is saved in password (bcrypt) fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts }; @Column("simple-json") @ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects presence: { status: Status; activities: Activity[]; client_status: ClientStatus; }; @Column("simple-json") @ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects relationships: { id: string; nickname?: string; type: RelationshipType; }[]; @Column("simple-json") @ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects connected_accounts: { access_token: string; friend_sync: boolean; id: string; name: string; revoked: boolean; show_activity: boolean; type: string; verifie: boolean; visibility: number; }[]; @Column("simple-json") @ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects 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 | 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 }; } // Private user data that should never get sent to the client export interface PublicUser { id: string; discriminator: string; username: string; avatar: string | null; accent_color: number; banner: string | null; public_flags: bigint; bot: boolean; } export enum RelationshipType { outgoing = 4, incoming = 3, blocked = 2, friends = 1, }