diff options
Diffstat (limited to 'util/src')
-rw-r--r-- | util/src/entities/AuditLog.ts | 60 | ||||
-rw-r--r-- | util/src/entities/Channel.ts | 12 | ||||
-rw-r--r-- | util/src/entities/Config.ts | 2 | ||||
-rw-r--r-- | util/src/entities/Group.ts | 33 | ||||
-rw-r--r-- | util/src/entities/Message.ts | 4 | ||||
-rw-r--r-- | util/src/entities/User.ts | 5 | ||||
-rw-r--r-- | util/src/entities/UserGroup.ts | 37 | ||||
-rw-r--r-- | util/src/util/Constants.ts | 17 | ||||
-rw-r--r-- | util/src/util/Email.ts | 7 | ||||
-rw-r--r-- | util/src/util/Intents.ts | 43 | ||||
-rw-r--r-- | util/src/util/MessageFlags.ts | 12 | ||||
-rw-r--r-- | util/src/util/Rights.ts | 2 | ||||
-rw-r--r-- | util/src/util/Token.ts | 7 |
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"); |