summary refs log tree commit diff
path: root/util/src
diff options
context:
space:
mode:
Diffstat (limited to 'util/src')
-rw-r--r--util/src/entities/AuditLog.ts60
-rw-r--r--util/src/entities/Channel.ts12
-rw-r--r--util/src/entities/Config.ts2
-rw-r--r--util/src/entities/Group.ts33
-rw-r--r--util/src/entities/Message.ts4
-rw-r--r--util/src/entities/User.ts5
-rw-r--r--util/src/entities/UserGroup.ts37
-rw-r--r--util/src/util/Constants.ts17
-rw-r--r--util/src/util/Email.ts7
-rw-r--r--util/src/util/Intents.ts43
-rw-r--r--util/src/util/MessageFlags.ts12
-rw-r--r--util/src/util/Rights.ts2
-rw-r--r--util/src/util/Token.ts7
13 files changed, 208 insertions, 33 deletions
diff --git a/util/src/entities/AuditLog.ts b/util/src/entities/AuditLog.ts
index 4b81ed6a..b003e7ba 100644
--- a/util/src/entities/AuditLog.ts
+++ b/util/src/entities/AuditLog.ts
@@ -4,41 +4,93 @@ import { ChannelPermissionOverwrite } from "./Channel";
 import { User } from "./User";
 
 export enum AuditLogEvents {
-	GUILD_UPDATE = 1,
-	CHANNEL_CREATE = 10,
+	// guild level
+	GUILD_UPDATE = 1, 
+	GUILD_IMPORT = 2,
+	GUILD_EXPORTED = 3,
+	GUILD_ARCHIVE = 4,
+	GUILD_UNARCHIVE = 5,
+	// join-leave
+	USER_JOIN = 6, 
+	USER_LEAVE = 7,
+	// channels
+	CHANNEL_CREATE = 10, 
 	CHANNEL_UPDATE = 11,
 	CHANNEL_DELETE = 12,
-	CHANNEL_OVERWRITE_CREATE = 13,
+	// permission overrides
+	CHANNEL_OVERWRITE_CREATE = 13, 
 	CHANNEL_OVERWRITE_UPDATE = 14,
 	CHANNEL_OVERWRITE_DELETE = 15,
-	MEMBER_KICK = 20,
+	// kick and ban
+	MEMBER_KICK = 20, 
 	MEMBER_PRUNE = 21,
 	MEMBER_BAN_ADD = 22,
 	MEMBER_BAN_REMOVE = 23,
+	// member updates
 	MEMBER_UPDATE = 24,
 	MEMBER_ROLE_UPDATE = 25,
 	MEMBER_MOVE = 26,
 	MEMBER_DISCONNECT = 27,
 	BOT_ADD = 28,
+	// roles
 	ROLE_CREATE = 30,
 	ROLE_UPDATE = 31,
 	ROLE_DELETE = 32,
+	ROLE_SWAP = 33,
+	// invites
 	INVITE_CREATE = 40,
 	INVITE_UPDATE = 41,
 	INVITE_DELETE = 42,
+	// webhooks
 	WEBHOOK_CREATE = 50,
 	WEBHOOK_UPDATE = 51,
 	WEBHOOK_DELETE = 52,
+	WEBHOOK_SWAP = 53,
+	// custom emojis
 	EMOJI_CREATE = 60,
 	EMOJI_UPDATE = 61,
 	EMOJI_DELETE = 62,
+	EMOJI_SWAP = 63,
+	// deletion
+	MESSAGE_CREATE = 70, // messages sent using non-primary seat of the user only
+	MESSAGE_EDIT = 71, // non-self edits only
 	MESSAGE_DELETE = 72,
 	MESSAGE_BULK_DELETE = 73,
+	// pinning
 	MESSAGE_PIN = 74,
 	MESSAGE_UNPIN = 75,
+	// integrations
 	INTEGRATION_CREATE = 80,
 	INTEGRATION_UPDATE = 81,
 	INTEGRATION_DELETE = 82,
+	// stage actions
+	STAGE_INSTANCE_CREATE = 83,
+	STAGE_INSTANCE_UPDATE = 84,
+	STAGE_INSTANCE_DELETE = 85,
+	// stickers
+	STICKER_CREATE = 90,
+	STICKER_UPDATE = 91,
+	STICKER_DELETE = 92,
+	STICKER_SWAP = 93,
+	// threads
+	THREAD_CREATE = 110,
+	THREAD_UPDATE = 111,
+	THREAD_DELETE = 112,
+	// application commands
+	APPLICATION_COMMAND_PERMISSION_UPDATE = 121,
+	// automod
+	POLICY_CREATE = 140, 
+	POLICY_UPDATE = 141,
+	POLICY_DELETE = 142,
+	MESSAGE_BLOCKED_BY_POLICIES = 143,  // in fosscord, blocked messages are stealth-dropped
+	// instance policies affecting the guild
+	GUILD_AFFECTED_BY_POLICIES = 216,
+	// message moves
+	IN_GUILD_MESSAGE_MOVE = 223,
+	CROSS_GUILD_MESSAGE_MOVE = 224,
+	// message routing
+	ROUTE_CREATE = 225, 
+	ROUTE_UPDATE = 226,
 }
 
 @Entity("audit_logs")
diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
index 4bf81901..69c08be7 100644
--- a/util/src/entities/Channel.ts
+++ b/util/src/entities/Channel.ts
@@ -28,6 +28,8 @@ export enum ChannelType {
 	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

+	DIRECTORY = 14, // guild directory listing channel

+	GUILD_FORUM = 15, // forum composed of IM threads

 	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)

@@ -352,6 +354,16 @@ export class Channel extends BaseClass {
 	isDm() {

 		return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM;

 	}

+

+	// Does the channel support sending messages ( eg categories do not )

+	isWritable() {

+		const disallowedChannelTypes = [

+			ChannelType.GUILD_CATEGORY,

+			ChannelType.GUILD_STAGE_VOICE,

+			ChannelType.VOICELESS_WHITEBOARD,

+		];

+		return disallowedChannelTypes.indexOf(this.type) == -1;

+	}

 }

 

 export interface ChannelPermissionOverwrite {

diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts
index 8d29b387..063a4d4d 100644
--- a/util/src/entities/Config.ts
+++ b/util/src/entities/Config.ts
@@ -324,7 +324,7 @@ export const DefaultConfigOptions: ConfigValue = {
 			// domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"),
 		},
 		dateOfBirth: {
-			required: false,
+			required: true,
 			minimum: 13,
 		},
 		disabled: false,
diff --git a/util/src/entities/Group.ts b/util/src/entities/Group.ts
new file mode 100644
index 00000000..b24d38cf
--- /dev/null
+++ b/util/src/entities/Group.ts
@@ -0,0 +1,33 @@
+import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
+
+import { BaseClass } from "./BaseClass";
+
+@Entity("groups")
+export class UserGroup extends BaseClass {
+  @Column({ nullable: true })
+  parent?: BigInt;
+
+	@Column()
+	color: number;
+
+	@Column()
+	hoist: boolean;
+
+ 	@Column()
+	mentionable: boolean;
+
+	@Column()
+	name: string;
+
+	@Column()
+	rights: BigInt;
+
+	@Column()
+	position: number;
+
+	@Column({ nullable: true })
+	icon: BigInt;
+
+	@Column({ nullable: true })
+	unicode_emoji: BigInt;
+}
diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts
index b32bbd94..e18cf691 100644
--- a/util/src/entities/Message.ts
+++ b/util/src/entities/Message.ts
@@ -39,13 +39,15 @@ export enum MessageType {
 	USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10,
 	USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11,
 	CHANNEL_FOLLOW_ADD = 12,
+	ACTION = 13, // /me messages
 	GUILD_DISCOVERY_DISQUALIFIED = 14,
 	GUILD_DISCOVERY_REQUALIFIED = 15,
 	ENCRYPTED = 16,
 	REPLY = 19,
-	APPLICATION_COMMAND = 20,
+	APPLICATION_COMMAND = 20, // application command or self command invocation
 	ROUTE_ADDED = 41, // custom message routing: new route affecting that channel
 	ROUTE_DISABLED = 42, // custom message routing: given route no longer affecting that channel
+	SELF_COMMAND_SCRIPT = 43, // self command scripts
 	ENCRYPTION = 50,
 	CUSTOM_START = 63,
 	UNHANDLED = 255
diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts
index a5c4c136..9b1c494e 100644
--- a/util/src/entities/User.ts
+++ b/util/src/entities/User.ts
@@ -163,6 +163,10 @@ export class User extends BaseClass {
 
 	@Column({ type: "simple-json", select: false })
 	settings: UserSettings;
+		
+	// workaround to prevent fossord-unaware clients from deleting settings not used by them
+	@Column({ type: "simple-json", select: false })
+	extended_settings: string;
 
 	@Column({ type: "simple-json" })
 	notes: { [key: string]: string };	//key is ID of user
@@ -273,6 +277,7 @@ export class User extends BaseClass {
 				valid_tokens_since: new Date(),
 			},
 			settings: { ...defaultSettings, locale: language },
+			extended_settings: {},
 			fingerprints: [],
 			notes: {},
 		});
diff --git a/util/src/entities/UserGroup.ts b/util/src/entities/UserGroup.ts
new file mode 100644
index 00000000..709b9d0b
--- /dev/null
+++ b/util/src/entities/UserGroup.ts
@@ -0,0 +1,37 @@
+import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
+
+import { BaseClass } from "./BaseClass";
+import { Guild } from "./Guild";
+import { User } from "./User";
+
+@Entity("groups")
+export class UserGroup extends BaseClass {
+	@Column()
+	color: number;
+
+	@Column()
+	hoist: boolean;
+	
+	@JoinColumn({ name: "controller", referencedColumnName: "id" })
+	@ManyToOne(() => User)
+	controller?: User;
+	 
+	@Column()
+	mentionable_by?: string;
+
+	@Column()
+	name: string;
+
+	@Column()
+	rights: string;
+
+	@Column({ nullable: true })
+	icon: string;
+	
+	@Column({ nullable: true })
+	parent?: string;
+	
+	@Column({ type: "simple-array", nullable: true})
+	associciations: string[];
+
+}
diff --git a/util/src/util/Constants.ts b/util/src/util/Constants.ts
index 8d61b9b4..a5d3fcd2 100644
--- a/util/src/util/Constants.ts
+++ b/util/src/util/Constants.ts
@@ -727,21 +727,23 @@ export const DiscordApiErrors = {
  * An error encountered while performing an API request (Fosscord only). Here are the potential errors:
  */
 export const FosscordApiErrors = {
-	MANUALLY_TRIGGERED_ERROR: new ApiError("This is an artificial error", 1),
+	MANUALLY_TRIGGERED_ERROR: new ApiError("This is an artificial error", 1, 500),
 	PREMIUM_DISABLED_FOR_GUILD: new ApiError("This guild cannot be boosted", 25001),
 	NO_FURTHER_PREMIUM: new ApiError("This guild does not receive further boosts", 25002),
-	GUILD_PREMIUM_DISABLED_FOR_YOU: new ApiError("This guild cannot be boosted by you", 25003),
+	GUILD_PREMIUM_DISABLED_FOR_YOU: new ApiError("This guild cannot be boosted by you", 25003, 403),
 	CANNOT_FRIEND_SELF: new ApiError("Cannot friend oneself", 25009),
 	USER_SPECIFIC_INVITE_WRONG_RECIPIENT: new ApiError("This invite is not meant for you", 25010),
 	USER_SPECIFIC_INVITE_FAILED: new ApiError("Failed to invite user", 25011),
-	CANNOT_MODIFY_USER_GROUP: new ApiError("This user cannot manipulate this group", 25050),
+	CANNOT_MODIFY_USER_GROUP: new ApiError("This user cannot manipulate this group", 25050, 403),
 	CANNOT_REMOVE_SELF_FROM_GROUP: new ApiError("This user cannot remove oneself from user group", 25051),
 	CANNOT_BAN_OPERATOR: new ApiError("Non-OPERATOR cannot ban OPERATOR from instance", 25052),
-	CANNOT_LEAVE_GUILD: new ApiError("You are not allowed to leave guilds that you joined by yourself", 25059),
-	EDITS_DISABLED: new ApiError("You are not allowed to edit your own messages", 25060),
-	DELETE_MESSAGE_DISABLED: new ApiError("You are not allowed to delete your own messages", 25061),
-	FEATURE_PERMANENTLY_DISABLED: new ApiError("This feature has been disabled server-side", 45006),
+	CANNOT_LEAVE_GUILD: new ApiError("You are not allowed to leave guilds that you joined by yourself", 25059, 403),
+	EDITS_DISABLED: new ApiError("You are not allowed to edit your own messages", 25060, 403),
+	DELETE_MESSAGE_DISABLED: new ApiError("You are not allowed to delete your own messages", 25061, 403),
+	FEATURE_PERMANENTLY_DISABLED: new ApiError("This feature has been disabled server-side", 45006, 501),
 	MISSING_RIGHTS: new ApiError("You lack rights to perform that action ({})", 50013, undefined, [""]),
+	CANNOT_REPLACE_BY_BACKFILL: new ApiError("Cannot backfill to message ID that already exists", 55002, 409),
+	CANNOT_BACKFILL_TO_THE_FUTURE: new ApiError("You cannot backfill messages in the future", 55003),
 	CANNOT_GRANT_PERMISSIONS_EXCEEDING_RIGHTS: new ApiError("You cannot grant permissions exceeding your own rights", 50050),
 	ROUTES_LOOPING: new ApiError("Loops in the route definition ({})", 50060, undefined, [""]),
 	CANNOT_REMOVE_ROUTE: new ApiError("Cannot remove message route while it is in effect and being used", 50061),
@@ -787,3 +789,4 @@ function keyMirror(arr: string[]) {
 	for (const value of arr) tmp[value] = value;
 	return tmp;
 }
+
diff --git a/util/src/util/Email.ts b/util/src/util/Email.ts
index b1a7599b..6885da33 100644
--- a/util/src/util/Email.ts
+++ b/util/src/util/Email.ts
@@ -13,7 +13,12 @@ export function adjustEmail(email?: string): string | undefined {
 	// TODO: check accounts with uncommon email domains
 	if (domain === "gmail.com" || domain === "googlemail.com") {
 		// replace .dots and +alternatives -> Gmail Dot Trick https://support.google.com/mail/answer/7436150 and https://generator.email/blog/gmail-generator
-		return user.replace(/[.]|(\+.*)/g, "") + "@gmail.com";
+		let v = user.replace(/[.]|(\+.*)/g, "") + "@gmail.com";
+	}
+	
+	if (domain === "google.com") {
+		// replace .dots and +alternatives -> Google Staff GMail Dot Trick
+		let v = user.replace(/[.]|(\+.*)/g, "") + "@google.com";
 	}
 
 	return email;
diff --git a/util/src/util/Intents.ts b/util/src/util/Intents.ts
index 943b29cf..1e840b76 100644
--- a/util/src/util/Intents.ts
+++ b/util/src/util/Intents.ts
@@ -2,20 +2,33 @@ import { BitField } from "./BitField";
 
 export class Intents extends BitField {
 	static FLAGS = {
-		GUILDS: BigInt(1) << BigInt(0),
-		GUILD_MEMBERS: BigInt(1) << BigInt(1),
-		GUILD_BANS: BigInt(1) << BigInt(2),
-		GUILD_EMOJIS: BigInt(1) << BigInt(3),
-		GUILD_INTEGRATIONS: BigInt(1) << BigInt(4),
-		GUILD_WEBHOOKS: BigInt(1) << BigInt(5),
-		GUILD_INVITES: BigInt(1) << BigInt(6),
-		GUILD_VOICE_STATES: BigInt(1) << BigInt(7),
-		GUILD_PRESENCES: BigInt(1) << BigInt(8),
-		GUILD_MESSAGES: BigInt(1) << BigInt(9),
-		GUILD_MESSAGE_REACTIONS: BigInt(1) << BigInt(10),
-		GUILD_MESSAGE_TYPING: BigInt(1) << BigInt(11),
-		DIRECT_MESSAGES: BigInt(1) << BigInt(12),
-		DIRECT_MESSAGE_REACTIONS: BigInt(1) << BigInt(13),
-		DIRECT_MESSAGE_TYPING: BigInt(1) << BigInt(14),
+		GUILDS: BigInt(1) << BigInt(0), // guilds and guild merge-split events affecting the user
+		GUILD_MEMBERS: BigInt(1) << BigInt(1), // memberships
+		GUILD_BANS: BigInt(1) << BigInt(2), // bans and ban lists
+		GUILD_EMOJIS: BigInt(1) << BigInt(3), // custom emojis
+		GUILD_INTEGRATIONS: BigInt(1) << BigInt(4), // applications
+		GUILD_WEBHOOKS: BigInt(1) << BigInt(5), // webhooks
+		GUILD_INVITES: BigInt(1) << BigInt(6), // mass invites (no user can receive user specific invites of another user)
+		GUILD_VOICE_STATES: BigInt(1) << BigInt(7), // voice updates
+		GUILD_PRESENCES: BigInt(1) << BigInt(8), // presence updates
+		GUILD_MESSAGES_METADATA: BigInt(1) << BigInt(9), // guild message metadata
+		GUILD_MESSAGE_REACTIONS: BigInt(1) << BigInt(10), // guild message reactions
+		GUILD_MESSAGE_TYPING: BigInt(1) << BigInt(11), // guild channel typing notifications
+		DIRECT_MESSAGES: BigInt(1) << BigInt(12), // DM or orphan channels
+		DIRECT_MESSAGE_REACTIONS: BigInt(1) << BigInt(13), // DM or orphan channel message reactions
+		DIRECT_MESSAGE_TYPING: BigInt(1) << BigInt(14), // DM typing notifications
+		GUILD_MESSAGES_CONTENT: BigInt(1) << BigInt(15), // guild message content
+		GUILD_POLICIES: BigInt(1) << BigInt(20), // guild policies
+		GUILD_POLICY_EXECUTION: BigInt(1) << BigInt(21), // guild policy execution
+		LIVE_MESSAGE_COMPOSITION: BigInt(1) << BigInt(32), // allow composing messages using the gateway
+		GUILD_ROUTES: BigInt(1) << BigInt(41), // message routes affecting the guild
+		DIRECT_MESSAGES_THREADS: BigInt(1) << BigInt(42),  // direct message threads
+		JUMBO_EVENTS: BigInt(1) << BigInt(43), // jumbo events (size limits to be defined later)
+		LOBBIES: BigInt(1) << BigInt(44), // lobbies
+		INSTANCE_ROUTES: BigInt(1) << BigInt(60), // all message route changes 
+		INSTANCE_GUILD_CHANGES: BigInt(1) << BigInt(61), // all guild create, guild object patch, split, merge and delete events
+		INSTANCE_POLICY_UPDATES: BigInt(1) << BigInt(62), // all instance policy updates
+		INSTANCE_USER_UPDATES: BigInt(1) << BigInt(63) // all instance user updates
 	};
 }
+
diff --git a/util/src/util/MessageFlags.ts b/util/src/util/MessageFlags.ts
index c76be4c8..b59295c4 100644
--- a/util/src/util/MessageFlags.ts
+++ b/util/src/util/MessageFlags.ts
@@ -1,5 +1,5 @@
-// https://github.com/discordjs/discord.js/blob/master/src/util/MessageFlags.js
-// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah
+// based on https://github.com/discordjs/discord.js/blob/master/src/util/MessageFlags.js
+// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah, 2022 Erkin Alp Güney
 
 import { BitField } from "./BitField";
 
@@ -8,7 +8,13 @@ export class MessageFlags extends BitField {
 		CROSSPOSTED: BigInt(1) << BigInt(0),
 		IS_CROSSPOST: BigInt(1) << BigInt(1),
 		SUPPRESS_EMBEDS: BigInt(1) << BigInt(2),
-		SOURCE_MESSAGE_DELETED: BigInt(1) << BigInt(3),
+		// SOURCE_MESSAGE_DELETED: BigInt(1) << BigInt(3), // fosscord will delete them from destination too, making this redundant
 		URGENT: BigInt(1) << BigInt(4),
+		// HAS_THREAD: BigInt(1) << BigInt(5) // does not apply to fosscord due to infrastructural differences
+		PRIVATE_ROUTE: BigInt(1) << BigInt(6), // it that has been routed to only some of the users that can see the channel
+		INTERACTION_WAIT: BigInt(1) << BigInt(7), // discord.com calls this LOADING
+		// FAILED_TO_MENTION_SOME_ROLES_IN_THREAD: BigInt(1) << BigInt(8)
+		SCRIPT_WAIT: BigInt(1) << BigInt(24), // waiting for the self command to complete
+		IMPORT_WAIT: BigInt(1) << BigInt(25), // latest message of a bulk import, waiting for the rest of the channel to be backfilled
 	};
 }
diff --git a/util/src/util/Rights.ts b/util/src/util/Rights.ts
index 35ad9514..b28c75b7 100644
--- a/util/src/util/Rights.ts
+++ b/util/src/util/Rights.ts
@@ -71,6 +71,8 @@ export class Rights extends BitField {
 		INITIATE_INTERACTIONS: BitFlag(40), // can initiate interactions
 		RESPOND_TO_INTERACTIONS: BitFlag(41), // can respond to interactions
 		SEND_BACKDATED_EVENTS: BitFlag(42), // can send backdated events
+		USE_MASS_INVITES: BitFlag(43), // added per @xnacly's request — can accept mass invites
+		ACCEPT_INVITES: BitFlag(44) // added per @xnacly's request — can accept user-specific invites and DM requests
 	};
 
 	any(permission: RightResolvable, checkOperator = true) {
diff --git a/util/src/util/Token.ts b/util/src/util/Token.ts
index 7c4cc61d..500ace45 100644
--- a/util/src/util/Token.ts
+++ b/util/src/util/Token.ts
@@ -6,7 +6,12 @@ export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] };
 
 export function checkToken(token: string, jwtSecret: string): Promise<any> {
 	return new Promise((res, rej) => {
-		token = token.replace("Bot ", ""); // TODO: proper bot support
+		token = token.replace("Bot ", "");
+		/**
+		in fosscord, even with instances that have bot distinction; we won't enforce "Bot" prefix,
+		as we don't really have separate pathways for bots 
+		**/
+		
 		jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => {
 			if (err || !decoded) return rej("Invalid Token");