summary refs log tree commit diff
path: root/util/src/entities
diff options
context:
space:
mode:
Diffstat (limited to 'util/src/entities')
-rw-r--r--util/src/entities/Channel.ts37
-rw-r--r--util/src/entities/ClientRelease.ts (renamed from util/src/entities/ClientRelase.ts)4
-rw-r--r--util/src/entities/Config.ts10
-rw-r--r--util/src/entities/ConnectedAccount.ts4
-rw-r--r--util/src/entities/Encryption.ts35
-rw-r--r--util/src/entities/Guild.ts12
-rw-r--r--util/src/entities/Member.ts19
-rw-r--r--util/src/entities/Message.ts9
-rw-r--r--util/src/entities/ReadState.ts3
-rw-r--r--util/src/entities/User.ts22
-rw-r--r--util/src/entities/index.ts2
11 files changed, 114 insertions, 43 deletions
diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
index 1cc4a538..4bf81901 100644
--- a/util/src/entities/Channel.ts
+++ b/util/src/entities/Channel.ts
@@ -14,19 +14,23 @@ import { Webhook } from "./Webhook";
 import { DmChannelDTO } from "../dtos";

 

 export enum ChannelType {

-	GUILD_TEXT = 0, // a text channel within a server

+	GUILD_TEXT = 0, // a text channel within a guild

 	DM = 1, // a direct message between users

-	GUILD_VOICE = 2, // a voice channel within a server

+	GUILD_VOICE = 2, // a voice channel within a guild

 	GROUP_DM = 3, // a direct message between multiple users

-	GUILD_CATEGORY = 4, // an organizational category that contains up to 50 channels

-	GUILD_NEWS = 5, // a channel that users can follow and crosspost into their own server

-	GUILD_STORE = 6, // a channel in which game developers can sell their game on Discord

+	GUILD_CATEGORY = 4, // an organizational category that contains zero or more channels

+	GUILD_NEWS = 5, // a channel that users can follow and crosspost into a guild or route

+	GUILD_STORE = 6, // a channel in which game developers can sell their things

 	ENCRYPTED = 7, // end-to-end encrypted channel

 	ENCRYPTED_THREAD = 8, // end-to-end encrypted thread channel

+	TRANSACTIONAL = 9, // event chain style transactional channel

 	GUILD_NEWS_THREAD = 10, // a temporary sub-channel within a GUILD_NEWS channel

 	GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel

 	GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission

 	GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience

+	TICKET_TRACKER = 33, // ticket tracker, individual ticket items shall have type 12

+	KANBAN = 34, // confluence like kanban board

+	VOICELESS_WHITEBOARD = 35, // whiteboard but without voice (whiteboard + voice is the same as stage)

 	CUSTOM_START = 64, // start custom channel types from here

 	UNHANDLED = 255 // unhandled unowned pass-through channel type

 }

@@ -72,7 +76,7 @@ export class Channel extends BaseClass {
 	@ManyToOne(() => Channel)

 	parent?: Channel;

 

-	// only for group dms

+	// for group DMs and owned custom channel types

 	@Column({ nullable: true })

 	@RelationId((channel: Channel) => channel.owner)

 	owner_id: string;

@@ -117,6 +121,9 @@ export class Channel extends BaseClass {
 	})

 	invites?: Invite[];

 

+	@Column({ nullable: true })

+	retention_policy_id?: string;

+

 	@OneToMany(() => Message, (message: Message) => message.channel, {

 		cascade: true,

 		orphanedRowAction: "delete",

@@ -140,7 +147,7 @@ export class Channel extends BaseClass {
 		orphanedRowAction: "delete",

 	})

 	webhooks?: Webhook[];

-

+	

 	// TODO: DM channel

 	static async createChannel(

 		channel: Partial<Channel>,

@@ -182,6 +189,7 @@ export class Channel extends BaseClass {
 

 		switch (channel.type) {

 			case ChannelType.GUILD_TEXT:

+			case ChannelType.GUILD_NEWS:

 			case ChannelType.GUILD_VOICE:

 				if (channel.parent_id && !opts?.skipExistsCheck) {

 					const exists = await Channel.findOneOrFail({ id: channel.parent_id });

@@ -191,25 +199,24 @@ export class Channel extends BaseClass {
 				}

 				break;

 			case ChannelType.GUILD_CATEGORY:

+			case ChannelType.UNHANDLED:

 				break;

 			case ChannelType.DM:

 			case ChannelType.GROUP_DM:

 				throw new HTTPError("You can't create a dm channel in a guild");

-			// TODO: check if guild is community server

 			case ChannelType.GUILD_STORE:

-			case ChannelType.GUILD_NEWS:

 			default:

 				throw new HTTPError("Not yet supported");

 		}

 

 		if (!channel.permission_overwrites) channel.permission_overwrites = [];

-		// TODO: auto generate position

+		// TODO: eagerly auto generate position of all guild channels

 

 		channel = {

 			...channel,

 			...(!opts?.keepId && { id: Snowflake.generate() }),

 			created_at: new Date(),

-			position: channel.position || 0,

+			position: (channel.type === ChannelType.UNHANDLED ? 0 : channel.position) || 0,

 		};

 

 		await Promise.all([

@@ -231,11 +238,13 @@ export class Channel extends BaseClass {
 		const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });

 

 		// TODO: check config for max number of recipients

+		/** if you want to disallow note to self channels, uncomment the conditional below

 		if (otherRecipientsUsers.length !== recipients.length) {

 			throw new HTTPError("Recipient/s not found");

 		}

+		**/

 

-		const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM;

+		const type = recipients.length > 1 ? ChannelType.DM : ChannelType.GROUP_DM;

 

 		let channel = null;

 

@@ -288,7 +297,8 @@ export class Channel extends BaseClass {
 			await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });

 		}

 

-		return channel_dto.excludedRecipients([creator_user_id]);

+		if (recipients.length === 1) return channel_dto; 

+		else return channel_dto.excludedRecipients([creator_user_id]);

 	}

 

 	static async removeRecipientFromChannel(channel: Channel, user_id: string) {

@@ -354,4 +364,5 @@ export interface ChannelPermissionOverwrite {
 export enum ChannelPermissionOverwriteType {

 	role = 0,

 	member = 1,

+	group = 2,

 }

diff --git a/util/src/entities/ClientRelase.ts b/util/src/entities/ClientRelease.ts
index e021b82b..c5afd307 100644
--- a/util/src/entities/ClientRelase.ts
+++ b/util/src/entities/ClientRelease.ts
@@ -1,8 +1,8 @@
 import { Column, Entity} from "typeorm";
 import { BaseClass } from "./BaseClass";
 
-@Entity("client_relase")
-export class Relase extends BaseClass {
+@Entity("client_release")
+export class Release extends BaseClass {
 	@Column()
 	name: string;
 
diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts
index f4a266dc..8d29b387 100644
--- a/util/src/entities/Config.ts
+++ b/util/src/entities/Config.ts
@@ -188,8 +188,8 @@ export interface ConfigValue {
 	},
 	client: {
 		useTestClient: Boolean;
-		relases: {
-			useLocalRelases: Boolean; //TODO
+		releases: {
+			useLocalRelease: Boolean; //TODO
 			upstreamVersion: string;
 		}
 	},
@@ -222,7 +222,7 @@ export const DefaultConfigOptions: ConfigValue = {
 	},
 	general: {
 		instanceName: "Fosscord Instance",
-		instanceDescription: "This is a Fosscord instance made in pre-relase days",
+		instanceDescription: "This is a Fosscord instance made in pre-release days",
 		frontPage: null,
 		tosPage: null,
 		correspondenceEmail: "noreply@localhost.local",
@@ -389,8 +389,8 @@ export const DefaultConfigOptions: ConfigValue = {
 	},
 	client: {
 		useTestClient: true,
-		relases: {
-			useLocalRelases: true,
+		releases: {
+			useLocalRelease: true,
 			upstreamVersion: "0.0.264"
 		}
 	},
diff --git a/util/src/entities/ConnectedAccount.ts b/util/src/entities/ConnectedAccount.ts
index b8aa2889..09ae30ab 100644
--- a/util/src/entities/ConnectedAccount.ts
+++ b/util/src/entities/ConnectedAccount.ts
@@ -2,7 +2,7 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
 import { BaseClass } from "./BaseClass";
 import { User } from "./User";
 
-export interface PublicConnectedAccount extends Pick<ConnectedAccount, "name" | "type" | "verifie"> {}
+export interface PublicConnectedAccount extends Pick<ConnectedAccount, "name" | "type" | "verified"> {}
 
 @Entity("connected_accounts")
 export class ConnectedAccount extends BaseClass {
@@ -35,7 +35,7 @@ export class ConnectedAccount extends BaseClass {
 	type: string;
 
 	@Column()
-	verifie: boolean;
+	verified: boolean;
 
 	@Column({ select: false })
 	visibility: number;
diff --git a/util/src/entities/Encryption.ts b/util/src/entities/Encryption.ts
new file mode 100644
index 00000000..3b82ff84
--- /dev/null
+++ b/util/src/entities/Encryption.ts
@@ -0,0 +1,35 @@
+import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";
+import { BaseClass } from "./BaseClass";
+import { Guild } from "./Guild";
+import { PublicUserProjection, User } from "./User";
+import { HTTPError } from "lambert-server";
+import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters } from "../util";
+import { BitField, BitFieldResolvable, BitFlag } from "../util/BitField";
+import { Recipient } from "./Recipient";
+import { Message } from "./Message";
+import { ReadState } from "./ReadState";
+import { Invite } from "./Invite";
+import { DmChannelDTO } from "../dtos";
+
+@Entity("security_settings")
+export class SecuritySettings extends BaseClass {
+
+  @Column({nullable: true})
+  guild_id: Snowflake;
+
+  @Column({nullable: true})
+  channel_id: Snowflake;
+
+  @Column()
+  encryption_permission_mask: BitField;
+
+  @Column()
+  allowed_algorithms: string[];
+
+  @Column()
+  current_algorithm: string;
+
+  @Column({nullable: true})
+  used_since_message: Snowflake;
+
+}
diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts
index 9ac148ee..70bb41c5 100644
--- a/util/src/entities/Guild.ts
+++ b/util/src/entities/Guild.ts
@@ -187,11 +187,11 @@ export class Guild extends BaseClass {
 
 	@Column({ nullable: true })
 	@RelationId((guild: Guild) => guild.owner)
-	owner_id: string;
+	owner_id?: string; // optional to allow for ownerless guilds
 
 	@JoinColumn({ name: "owner_id", referencedColumnName: "id" })
 	@ManyToOne(() => User)
-	owner: User;
+	owner?: User; // optional to allow for ownerless guilds
 
 	@Column({ nullable: true })
 	preferred_locale?: string;
@@ -200,7 +200,7 @@ export class Guild extends BaseClass {
 	premium_subscription_count?: number;
 
 	@Column({ nullable: true })
-	premium_tier?: number; // nitro boost level
+	premium_tier?: number; // crowd premium level
 
 	@Column({ nullable: true })
 	@RelationId((guild: Guild) => guild.public_updates_channel)
@@ -269,6 +269,10 @@ export class Guild extends BaseClass {
 
 	@Column({ nullable: true })
 	nsfw?: boolean;
+	
+	// TODO: nested guilds
+	@Column({ nullable: true })
+	parent?: string;
 
 	// only for developer portal
 	permissions?: number;
@@ -308,7 +312,7 @@ export class Guild extends BaseClass {
 			verification_level: 0,
 			welcome_screen: {
 				enabled: false,
-				description: "No description",
+				description: "Fill in your description",
 				welcome_channels: [],
 			},
 			widget_enabled: true, // NB: don't set it as false to prevent artificial restrictions
diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts
index 3c5f9db0..fe2d5590 100644
--- a/util/src/entities/Member.ts
+++ b/util/src/entities/Member.ts
@@ -70,7 +70,7 @@ export class Member extends BaseClassWithoutId {
 
 	@Column({ nullable: true })
 	nick?: string;
-
+	
 	@JoinTable({
 		name: "member_roles",
 		joinColumn: { name: "index", referencedColumnName: "index" },
@@ -85,8 +85,8 @@ export class Member extends BaseClassWithoutId {
 	@Column()
 	joined_at: Date;
 
-	@Column({ nullable: true })
-	premium_since?: Date;
+	@Column({ type: "bigint", nullable: true })
+	premium_since?: number;
 
 	@Column()
 	deaf: boolean;
@@ -102,8 +102,17 @@ export class Member extends BaseClassWithoutId {
 
 	@Column({ nullable: true })
 	last_message_id?: string;
+	
+	/**
+	@JoinColumn({ name: "id" })
+	@ManyToOne(() => User, {
+		onDelete: "DO NOTHING",
+	// do not auto-kick force-joined members just because their joiners left the server
+	}) **/
+	@Column({ nullable: true})
+	joined_by?: string;
 
-	// TODO: update
+	// TODO: add this when we have proper read receipts
 	// @Column({ type: "simple-json" })
 	// read_state: ReadState;
 
@@ -245,7 +254,7 @@ export class Member extends BaseClassWithoutId {
 			nick: undefined,
 			roles: [guild_id], // @everyone role
 			joined_at: new Date(),
-			premium_since: new Date(),
+			premium_since: (new Date()).getTime(),
 			deaf: false,
 			mute: false,
 			pending: false,
diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts
index e577d5df..b32bbd94 100644
--- a/util/src/entities/Message.ts
+++ b/util/src/entities/Message.ts
@@ -41,8 +41,14 @@ export enum MessageType {
 	CHANNEL_FOLLOW_ADD = 12,
 	GUILD_DISCOVERY_DISQUALIFIED = 14,
 	GUILD_DISCOVERY_REQUALIFIED = 15,
+	ENCRYPTED = 16,
 	REPLY = 19,
 	APPLICATION_COMMAND = 20,
+	ROUTE_ADDED = 41, // custom message routing: new route affecting that channel
+	ROUTE_DISABLED = 42, // custom message routing: given route no longer affecting that channel
+	ENCRYPTION = 50,
+	CUSTOM_START = 63,
+	UNHANDLED = 255
 }
 
 @Entity("messages")
@@ -84,7 +90,7 @@ export class Message extends BaseClass {
 	@RelationId((message: Message) => message.member)
 	member_id: string;
 
-	@JoinColumn({ name: "author_id", referencedColumnName: "id" })
+	@JoinColumn({ name: "member_id", referencedColumnName: "id" })
 	@ManyToOne(() => User, {
 		onDelete: "CASCADE",
 	})
@@ -203,6 +209,7 @@ export interface MessageComponent {
 }
 
 export enum MessageComponentType {
+	Script = 0, // self command script
 	ActionRow = 1,
 	Button = 2,
 }
diff --git a/util/src/entities/ReadState.ts b/util/src/entities/ReadState.ts
index e6d73105..b915573b 100644
--- a/util/src/entities/ReadState.ts
+++ b/util/src/entities/ReadState.ts
@@ -49,6 +49,7 @@ export class ReadState extends BaseClass {
 	@Column({ nullable: true })
 	mention_count: number;
 
-	@Column({ nullable: true })
+	// @Column({ nullable: true })
+	// TODO: derive this from (last_message_id=notifications_cursor=public_ack)=true
 	manual: boolean;
 }
diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts
index 1d18c838..a5c4c136 100644
--- a/util/src/entities/User.ts
+++ b/util/src/entities/User.ts
@@ -60,7 +60,7 @@ export class User extends BaseClass {
 	username: string; // username max length 32, min 2 (should be configurable)
 
 	@Column()
-	discriminator: string; // #0001 4 digit long string from #0001 - #9999
+	discriminator: string; // opaque string: 4 digits on discord.com
 
 	setDiscriminator(val: string) {
 		const number = Number(val);
@@ -88,10 +88,10 @@ export class User extends BaseClass {
 	mobile: boolean; // if the user has mobile app installed
 
 	@Column()
-	premium: boolean; // if user bought nitro
-
+	premium: boolean; // if user bought individual premium
+	
 	@Column()
-	premium_type: number; // nitro level
+	premium_type: number; // individual premium level
 
 	@Column()
 	bot: boolean; // if user is bot
@@ -100,11 +100,11 @@ export class User extends BaseClass {
 	bio: string; // short description of the user (max 190 chars -> should be configurable)
 
 	@Column()
-	system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author
+	system: boolean; // 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 is older than 18 (resp. Config)
-
+	nsfw_allowed: boolean; // if the user can do age-restricted actions (NSFW channels/guilds/commands)
+	
 	@Column({ select: false })
 	mfa_enabled: boolean; // if multi factor authentication is enabled
 
@@ -132,7 +132,7 @@ export class User extends BaseClass {
 	@Column()
 	public_flags: number;
 
-	@Column()
+	@Column({ type: "bigint" })
 	rights: string; // Rights
 
 	@OneToMany(() => Session, (session: Session) => session.user)
@@ -164,6 +164,9 @@ export class User extends BaseClass {
 	@Column({ type: "simple-json", select: false })
 	settings: UserSettings;
 
+	@Column({ type: "simple-json" })
+	notes: { [key: string]: string };	//key is ID of user
+
 	toPublicUser() {
 		const user: any = {};
 		PublicUserProjection.forEach((x) => {
@@ -271,6 +274,7 @@ export class User extends BaseClass {
 			},
 			settings: { ...defaultSettings, locale: language },
 			fingerprints: [],
+			notes: {},
 		});
 
 		await user.save();
@@ -360,7 +364,7 @@ export interface UserSettings {
 	render_reactions: boolean;
 	restricted_guilds: string[];
 	show_current_game: boolean;
-	status: "online" | "offline" | "dnd" | "idle";
+	status: "online" | "offline" | "dnd" | "idle" | "invisible";
 	stream_notifications_enabled: boolean;
 	theme: "dark" | "white"; // dark
 	timezone_offset: number; // e.g -60
diff --git a/util/src/entities/index.ts b/util/src/entities/index.ts
index fc18d422..f023d5a6 100644
--- a/util/src/entities/index.ts
+++ b/util/src/entities/index.ts
@@ -27,4 +27,4 @@ export * from "./Template";
 export * from "./User";
 export * from "./VoiceState";
 export * from "./Webhook";
-export * from "./ClientRelase";
\ No newline at end of file
+export * from "./ClientRelease";
\ No newline at end of file