diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
index 08be1e02..4bf81901 100644
--- a/util/src/entities/Channel.ts
+++ b/util/src/entities/Channel.ts
@@ -20,13 +20,17 @@ export enum ChannelType {
GROUP_DM = 3, // a direct message between multiple users
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 game on Discord
+ 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
}
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 928a25d7..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()
- 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 ed7bd4ce..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();
diff --git a/util/src/interfaces/Event.ts b/util/src/interfaces/Event.ts
index a5253c09..416082ed 100644
--- a/util/src/interfaces/Event.ts
+++ b/util/src/interfaces/Event.ts
@@ -623,6 +623,7 @@ export type EVENT =
| "PRESENCE_UPDATE"
| "TYPING_START"
| "USER_UPDATE"
+ | "USER_NOTE_UPDATE"
| "WEBHOOKS_UPDATE"
| "INTERACTION_CREATE"
| "VOICE_STATE_UPDATE"
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..d9a60e4a 100644
--- a/util/src/util/Intents.ts
+++ b/util/src/util/Intents.ts
@@ -2,20 +2,31 @@ 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
+ 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/Rights.ts b/util/src/util/Rights.ts
index db5384d0..35ad9514 100644
--- a/util/src/util/Rights.ts
+++ b/util/src/util/Rights.ts
@@ -1,6 +1,7 @@
import { BitField } from "./BitField";
import "missing-native-js-functions";
import { BitFieldResolvable, BitFlag } from "./BitField";
+import { User } from "../entities";
var HTTPError: any;
@@ -85,6 +86,15 @@ export class Rights extends BitField {
// @ts-ignore
throw new HTTPError(`You are missing the following rights ${permission}`, 403);
}
+
}
const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce((total, val) => total | val, BigInt(0));
+
+export async function getRights( user_id: string
+ /**, opts: {
+ in_behalf?: (keyof User)[];
+ } = {} **/) {
+ let user = await User.findOneOrFail({ where: { id: user_id } });
+ return new Rights(user.rights);
+}
|