summary refs log tree commit diff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/config/Config.ts8
-rw-r--r--src/util/entities/Channel.ts4
-rw-r--r--src/util/entities/Guild.ts4
-rw-r--r--src/util/entities/Invite.ts2
-rw-r--r--src/util/entities/PluginConfig.ts2
-rw-r--r--src/util/entities/Session.ts6
-rw-r--r--src/util/entities/User.ts2
-rw-r--r--src/util/entities/VoiceState.ts2
-rw-r--r--src/util/entities/index.ts6
-rw-r--r--src/util/index.ts3
-rw-r--r--src/util/migrations/mariadb/1660404644371-PluginConfigs.ts27
-rw-r--r--src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts135
-rw-r--r--src/util/migrations/postgres/1660404619978-PluginConfigs.ts15
-rw-r--r--src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts91
-rw-r--r--src/util/migrations/sqlite/1660565540177-sync_rebase_15aug2022.ts15
-rw-r--r--src/util/plugin/Plugin.ts210
-rw-r--r--src/util/plugin/PluginConfig.ts35
-rw-r--r--src/util/plugin/PluginEventHandler.ts161
-rw-r--r--src/util/plugin/PluginLoader.ts30
-rw-r--r--src/util/plugin/PluginManifest.ts18
-rw-r--r--src/util/plugin/PluginStore.ts7
-rw-r--r--src/util/plugin/event_types/ChannelCreateEventArgs.ts14
-rw-r--r--src/util/plugin/event_types/GuildCreateEventArgs.ts10
-rw-r--r--src/util/plugin/event_types/LoginEventArgs.ts12
-rw-r--r--src/util/plugin/event_types/MessageEventArgs.ts10
-rw-r--r--src/util/plugin/event_types/PluginLoadedEventArgs.ts4
-rw-r--r--src/util/plugin/event_types/RegisterEventArgs.ts14
-rw-r--r--src/util/plugin/event_types/StatusChangeEventArgs.ts10
-rw-r--r--src/util/plugin/event_types/TypingEventArgs.ts16
-rwxr-xr-xsrc/util/plugin/event_types/_gen.sh4
-rw-r--r--src/util/plugin/event_types/base/EventResult.ts6
-rw-r--r--src/util/plugin/event_types/index.ts2
-rw-r--r--src/util/plugin/index.ts2
-rw-r--r--src/util/schemas/ActivitySchema.ts2
-rw-r--r--src/util/schemas/ChannelPermissionOverwriteSchema.ts2
-rw-r--r--src/util/schemas/MessageCreateSchema.ts2
-rw-r--r--src/util/schemas/RelationshipPutSchema.ts2
-rw-r--r--src/util/schemas/UserSettingsSchema.ts2
-rw-r--r--src/util/schemas/VoiceStateUpdateSchema.ts2
-rw-r--r--src/util/util/Base64.ts47
-rw-r--r--src/util/util/Config.ts1
-rw-r--r--src/util/util/Environment.ts2
-rw-r--r--src/util/util/Logo.ts65
-rw-r--r--src/util/util/Permissions.ts7
-rw-r--r--src/util/util/RandomInviteID.ts31
-rw-r--r--src/util/util/Rights.ts2
-rw-r--r--src/util/util/String.ts17
-rw-r--r--src/util/util/index.ts5
-rw-r--r--src/util/util/ipAddress.ts99
-rw-r--r--src/util/util/passwordStrength.ts59
50 files changed, 757 insertions, 477 deletions
diff --git a/src/util/config/Config.ts b/src/util/config/Config.ts

index 36c4509d..562d589a 100644 --- a/src/util/config/Config.ts +++ b/src/util/config/Config.ts
@@ -20,12 +20,12 @@ import { export class ConfigValue { gateway: EndpointConfiguration = { - endpointPublic: '${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}', - endpointPrivate: `ws://localhost:3001` + endpointPrivate: `ws://localhost:3001`, + endpointPublic: '${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}' }; cdn: EndpointConfiguration = { - endpointPublic: "${location.host}", - endpointPrivate: `http://localhost:3001` + endpointPrivate: `http://localhost:3001`, + endpointPublic: "${location.host}" }; api: ApiConfiguration = new ApiConfiguration(); general: GeneralConfiguration = new GeneralConfiguration(); diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts
index b17fdba0..c803b1b2 100644 --- a/src/util/entities/Channel.ts +++ b/src/util/entities/Channel.ts
@@ -359,8 +359,8 @@ export class Channel extends BaseClass { } static async deleteChannel(channel: Channel) { - await Message.delete({ channel_id: channel.id }); //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util - //TODO before deleting the channel we should check and delete other relations + await Message.delete({ channel_id: channel.id }); //TODO: we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util + //TODO: before deleting the channel we should check and delete other relations await Channel.delete({ id: channel.id }); } diff --git a/src/util/entities/Guild.ts b/src/util/entities/Guild.ts
index cd7fa561..9edd3753 100644 --- a/src/util/entities/Guild.ts +++ b/src/util/entities/Guild.ts
@@ -18,7 +18,7 @@ import { Webhook } from "./Webhook"; // TODO: guild_scheduled_events // TODO: stage_instances // TODO: threads -// TODO: +// TODO: implement keywords // "keywords": [ // "Genshin Impact", // "Paimon", @@ -75,7 +75,7 @@ export class Guild extends BaseClass { explicit_content_filter?: number = Config.get().defaults.guild.explicitContentFilter; @Column({ type: "simple-array" }) - features: string[]; //TODO use enum + features: string[]; //TODO: use enum //TODO: https://discord.com/developers/docs/resources/guild#guild-object-guild-features @Column({ nullable: true }) diff --git a/src/util/entities/Invite.ts b/src/util/entities/Invite.ts
index f6ba85d7..ccb0099a 100644 --- a/src/util/entities/Invite.ts +++ b/src/util/entities/Invite.ts
@@ -1,5 +1,5 @@ -import { random } from "@fosscord/api"; import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, RelationId } from "typeorm"; +import { random } from ".."; import { BaseClassWithoutId } from "./BaseClass"; import { Channel } from "./Channel"; import { Guild } from "./Guild"; diff --git a/src/util/entities/PluginConfig.ts b/src/util/entities/PluginConfig.ts
index 87de5167..2fb0c0c2 100644 --- a/src/util/entities/PluginConfig.ts +++ b/src/util/entities/PluginConfig.ts
@@ -8,4 +8,4 @@ export class PluginConfigEntity extends BaseClassWithoutId { @Column({ type: "simple-json", nullable: true }) value: number | boolean | null | string | Date | undefined; -} \ No newline at end of file +} diff --git a/src/util/entities/Session.ts b/src/util/entities/Session.ts
index 0cb4c309..43945466 100644 --- a/src/util/entities/Session.ts +++ b/src/util/entities/Session.ts
@@ -4,7 +4,7 @@ import { Status } from "../interfaces/Status"; import { BaseClass } from "./BaseClass"; import { User } from "./User"; -//TODO we need to remove all sessions on server start because if the server crashes without closing websockets it won't delete them +//TODO: we need to remove all sessions on server start because if the server crashes without closing websockets it won't delete them @Entity("sessions") export class Session extends BaseClass { @@ -18,7 +18,7 @@ export class Session extends BaseClass { }) user: User; - //TODO check, should be 32 char long hex string + //TODO: check, should be 32 char long hex string @Column({ nullable: false, select: false }) session_id: string; @@ -34,7 +34,7 @@ export class Session extends BaseClass { }; @Column({ nullable: false, type: "varchar" }) - status: Status; //TODO enum + status: Status; //TODO: enum } export const PrivateSessionProjection: (keyof Session)[] = ["user_id", "session_id", "activities", "client_info", "status"]; diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index 57afb132..21ed14f4 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts
@@ -250,7 +250,7 @@ export class User extends BaseClass { * date_of_birth, * req, * } - * @return {*} + * @return {*} * @memberof User */ static async register({ diff --git a/src/util/entities/VoiceState.ts b/src/util/entities/VoiceState.ts
index baf2c687..23cab248 100644 --- a/src/util/entities/VoiceState.ts +++ b/src/util/entities/VoiceState.ts
@@ -42,7 +42,7 @@ export class VoiceState extends BaseClass { // @ManyToOne(() => Member, { // onDelete: "CASCADE", // }) - //TODO find a way to make it work without breaking Guild.voice_states + //TODO: find a way to make it work without breaking Guild.voice_states member: Member; @Column() diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts
index 444a7e49..d2820c58 100644 --- a/src/util/entities/index.ts +++ b/src/util/entities/index.ts
@@ -16,6 +16,7 @@ export * from "./Member"; export * from "./Message"; export * from "./Migration"; export * from "./Note"; +export * from "./PluginConfig"; export * from "./RateLimit"; export * from "./ReadState"; export * from "./Recipient"; @@ -31,8 +32,3 @@ export * from "./User"; export * from "./UserSettings"; export * from "./VoiceState"; export * from "./Webhook"; -export * from "./ClientRelease"; -export * from "./BackupCodes"; -export * from "./Note"; -export * from "./UserSettings"; -export * from "./PluginConfig"; diff --git a/src/util/index.ts b/src/util/index.ts
index 0cf30a71..b8707c3e 100644 --- a/src/util/index.ts +++ b/src/util/index.ts
@@ -4,8 +4,7 @@ export * from "./config/index"; export * from "./dtos/index"; export * from "./entities/index"; export * from "./interfaces/index"; +export * from "./plugin"; export * from "./schemas"; export * from "./util/index"; export * from "./util/MFA"; -export * from "./schemas"; -export * from "./plugin"; \ No newline at end of file diff --git a/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts b/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts
index 73953ca8..6cbc594c 100644 --- a/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts +++ b/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts
@@ -1,42 +1,41 @@ import { MigrationInterface, QueryRunner } from "typeorm"; export class PluginConfigs1660404644371 implements MigrationInterface { - name = 'PluginConfigs1660404644371' + name = "PluginConfigs1660404644371"; - public async up(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` DROP INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE \`plugin_config\` ( \`key\` varchar(255) NOT NULL, \`value\` text NULL, PRIMARY KEY (\`key\`) ) ENGINE = InnoDB `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` ADD \`flags\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` ADD \`default_thread_rate_limit_per_user\` int NULL `); - } + } - public async down(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` ALTER TABLE \`channels\` DROP COLUMN \`default_thread_rate_limit_per_user\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` DROP COLUMN \`flags\` `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE \`plugin_config\` `); - await queryRunner.query(` + await queryRunner.query(` CREATE UNIQUE INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` (\`settingsId\`) `); - } - + } } diff --git a/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts b/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts
index d799fe80..eee8c39c 100644 --- a/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts +++ b/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts
@@ -1,229 +1,228 @@ import { MigrationInterface, QueryRunner } from "typeorm"; export class UpdateMigrations1660534571948 implements MigrationInterface { - name = 'UpdateMigrations1660534571948' + name = "UpdateMigrations1660534571948"; - public async up(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_e5bf78cdbbe9ba91062d74c5aba\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` `); - await queryRunner.query(` + await queryRunner.query(` DROP INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE \`plugin_config\` ( \`key\` varchar(255) NOT NULL, \`value\` text NULL, PRIMARY KEY (\`key\`) ) ENGINE = InnoDB `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`rpc_origins\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`primary_sku_id\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`slug\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`guild_id\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`type\` text NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`hook\` tinyint NOT NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`redirect_uris\` text NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`rpc_application_state\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`store_application_state\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`verification_state\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`interactions_endpoint_url\` varchar(255) NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`integration_public\` tinyint NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`integration_require_code_grant\` tinyint NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`discoverability_state\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`discovery_eligibility_flags\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`tags\` text NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`install_params\` text NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`bot_user_id\` varchar(255) NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD UNIQUE INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` (\`bot_user_id\`) `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` ADD \`flags\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` ADD \`default_thread_rate_limit_per_user\` int NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` CHANGE \`description\` \`description\` varchar(255) NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`flags\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`flags\` int NOT NULL `); - await queryRunner.query(` + await queryRunner.query(` CREATE UNIQUE INDEX \`REL_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` (\`bot_user_id\`) `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD CONSTRAINT \`FK_2ce5a55796fe4c2f77ece57a647\` FOREIGN KEY (\`bot_user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`invites\` ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION `); - } + } - public async down(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_2ce5a55796fe4c2f77ece57a647\` `); - await queryRunner.query(` + await queryRunner.query(` DROP INDEX \`REL_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`flags\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`flags\` varchar(255) NOT NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` CHANGE \`description\` \`description\` varchar(255) NOT NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` DROP COLUMN \`default_thread_rate_limit_per_user\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`channels\` DROP COLUMN \`flags\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`bot_user_id\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`install_params\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`tags\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`discovery_eligibility_flags\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`discoverability_state\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`integration_require_code_grant\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`integration_public\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`interactions_endpoint_url\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`verification_state\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`store_application_state\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`rpc_application_state\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`redirect_uris\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`hook\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` DROP COLUMN \`type\` `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`guild_id\` varchar(255) NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`slug\` varchar(255) NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`primary_sku_id\` varchar(255) NULL `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD \`rpc_origins\` text NULL `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE \`plugin_config\` `); - await queryRunner.query(` + await queryRunner.query(` CREATE UNIQUE INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` (\`settingsId\`) `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`invites\` ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE \`applications\` ADD CONSTRAINT \`FK_e5bf78cdbbe9ba91062d74c5aba\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION `); - } - + } } diff --git a/src/util/migrations/postgres/1660404619978-PluginConfigs.ts b/src/util/migrations/postgres/1660404619978-PluginConfigs.ts
index d8a5ab4d..21d4757c 100644 --- a/src/util/migrations/postgres/1660404619978-PluginConfigs.ts +++ b/src/util/migrations/postgres/1660404619978-PluginConfigs.ts
@@ -1,22 +1,21 @@ import { MigrationInterface, QueryRunner } from "typeorm"; export class PluginConfigs1660404619978 implements MigrationInterface { - name = 'PluginConfigs1660404619978' + name = "PluginConfigs1660404619978"; - public async up(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` CREATE TABLE "plugin_config" ( "key" character varying NOT NULL, "value" text, CONSTRAINT "PK_aa929ece56c59233b85a16f62ef" PRIMARY KEY ("key") ) `); - } + } - public async down(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` DROP TABLE "plugin_config" `); - } - + } } diff --git a/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts b/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts
index 54a59fab..8f5e364b 100644 --- a/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts +++ b/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts
@@ -1,10 +1,10 @@ import { MigrationInterface, QueryRunner } from "typeorm"; export class UpdateMigrations1660534525799 implements MigrationInterface { - name = 'UpdateMigrations1660534525799' + name = "UpdateMigrations1660534525799"; - public async up(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` CREATE TABLE "temporary_applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -28,7 +28,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "temporary_applications"( "id", "name", @@ -69,14 +69,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "guild_id" FROM "applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "temporary_applications" RENAME TO "applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "temporary_applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -96,7 +96,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "temporary_applications"( "id", "name", @@ -129,14 +129,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "team_id" FROM "applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "temporary_applications" RENAME TO "applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "temporary_applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -171,7 +171,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "temporary_applications"( "id", "name", @@ -204,14 +204,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "team_id" FROM "applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "temporary_applications" RENAME TO "applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "temporary_applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -246,7 +246,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "temporary_applications"( "id", "name", @@ -307,14 +307,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "bot_user_id" FROM "applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "temporary_applications" RENAME TO "applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "temporary_applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -350,7 +350,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_2ce5a55796fe4c2f77ece57a647" FOREIGN KEY ("bot_user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "temporary_applications"( "id", "name", @@ -411,21 +411,21 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "bot_user_id" FROM "applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "temporary_applications" RENAME TO "applications" `); - } + } - public async down(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` ALTER TABLE "applications" RENAME TO "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -460,7 +460,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "applications"( "id", "name", @@ -521,14 +521,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "bot_user_id" FROM "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "applications" RENAME TO "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -563,7 +563,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "applications"( "id", "name", @@ -624,14 +624,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "bot_user_id" FROM "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "applications" RENAME TO "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -651,7 +651,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "applications"( "id", "name", @@ -684,14 +684,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "team_id" FROM "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "applications" RENAME TO "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -715,7 +715,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "applications"( "id", "name", @@ -748,14 +748,14 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "team_id" FROM "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` ALTER TABLE "applications" RENAME TO "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` CREATE TABLE "applications" ( "id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, @@ -780,7 +780,7 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION ) `); - await queryRunner.query(` + await queryRunner.query(` INSERT INTO "applications"( "id", "name", @@ -821,9 +821,8 @@ export class UpdateMigrations1660534525799 implements MigrationInterface { "guild_id" FROM "temporary_applications" `); - await queryRunner.query(` + await queryRunner.query(` DROP TABLE "temporary_applications" `); - } - + } } diff --git a/src/util/migrations/sqlite/1660565540177-sync_rebase_15aug2022.ts b/src/util/migrations/sqlite/1660565540177-sync_rebase_15aug2022.ts
index 665df6c5..17f1fb16 100644 --- a/src/util/migrations/sqlite/1660565540177-sync_rebase_15aug2022.ts +++ b/src/util/migrations/sqlite/1660565540177-sync_rebase_15aug2022.ts
@@ -1,18 +1,17 @@ import { MigrationInterface, QueryRunner } from "typeorm"; export class syncRebase15aug20221660565540177 implements MigrationInterface { - name = 'syncRebase15aug20221660565540177' + name = "syncRebase15aug20221660565540177"; - public async up(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` CREATE TABLE "plugin_config" ("key" varchar PRIMARY KEY NOT NULL, "value" text) `); - } + } - public async down(queryRunner: QueryRunner): Promise<void> { - await queryRunner.query(` + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` DROP TABLE "plugin_config" `); - } - + } } diff --git a/src/util/plugin/Plugin.ts b/src/util/plugin/Plugin.ts
index 6a6f03f4..9bccba9d 100644 --- a/src/util/plugin/Plugin.ts +++ b/src/util/plugin/Plugin.ts
@@ -1,14 +1,27 @@ -import EventEmitter from "events"; -import { PluginLoadedEventArgs, PluginManifest, TypedEventEmitter } from "@fosscord/util"; -import { PluginConfig } from "./PluginConfig"; -import { PreRegisterEventArgs, PreRegisterEventResult, OnRegisterEventArgs } from '.'; -import { PreMessageEventArgs, PreMessageEventResult, OnMessageEventArgs } from '.'; -import { PreLoginEventArgs, PreLoginEventResult, OnLoginEventArgs } from '.'; -import { PreGuildCreateEventArgs, PreGuildCreateEventResult, OnGuildCreateEventArgs } from '.'; -import { PreChannelCreateEventArgs, PreChannelCreateEventResult, OnChannelCreateEventArgs } from '.'; -import { PreTypingEventArgs, PreTypingEventResult, OnTypingEventArgs } from '.'; -import { PreStatusChangeEventArgs, PreStatusChangeEventResult, OnStatusChangeEventArgs } from '.'; - +import { + OnChannelCreateEventArgs, + OnGuildCreateEventArgs, + OnLoginEventArgs, + OnMessageEventArgs, + OnRegisterEventArgs, + OnStatusChangeEventArgs, + OnTypingEventArgs, + PreChannelCreateEventArgs, + PreChannelCreateEventResult, + PreGuildCreateEventArgs, + PreGuildCreateEventResult, + PreLoginEventArgs, + PreLoginEventResult, + PreMessageEventArgs, + PreMessageEventResult, + PreRegisterEventArgs, + PreRegisterEventResult, + PreStatusChangeEventArgs, + PreStatusChangeEventResult, + PreTypingEventArgs, + PreTypingEventResult +} from "."; +import { PluginLoadedEventArgs, PluginManifest } from ".."; /*type PluginEvents = { error: (error: Error | unknown) => void; @@ -27,134 +40,131 @@ export class Plugin { pluginPath?: string; pluginManifest?: PluginManifest; /** - * + * * * @param {PluginLoadedEventArgs} args Info about plugin environment * @memberof Plugin */ - async onPluginLoaded?(args?: PluginLoadedEventArgs) { - - } + async onPluginLoaded?(args?: PluginLoadedEventArgs) {} //generated /** - * RegisterEvent: document me - * - * @param {OnRegisterEventArgs} args Info about what's going on - * @memberof Plugin - */ + * RegisterEvent: document me + * + * @param {OnRegisterEventArgs} args Info about what's going on + * @memberof Plugin + */ async onRegister?(args: OnRegisterEventArgs): Promise<void>; /** - * RegisterEvent: Executed before changes are announced - * document me. - * - * @param {PreRegisterEventArgs} args Info about what's going on - * @return {PreRegisterEventResult} How event should be handled - * @memberof Plugin - */ + * RegisterEvent: Executed before changes are announced + * document me. + * + * @param {PreRegisterEventArgs} args Info about what's going on + * @return {PreRegisterEventResult} How event should be handled + * @memberof Plugin + */ async onPreRegister?(args: PreRegisterEventArgs): Promise<PreRegisterEventResult>; /** - * MessageEvent: document me - * - * @param {OnMessageEventArgs} args Info about what's going on - * @memberof Plugin - */ + * MessageEvent: document me + * + * @param {OnMessageEventArgs} args Info about what's going on + * @memberof Plugin + */ async onMessage?(args: OnMessageEventArgs): Promise<void>; /** - * MessageEvent: Executed before changes are announced - * document me. - * - * @param {PreMessageEventArgs} args Info about what's going on - * @return {PreMessageEventResult} How event should be handled - * @memberof Plugin - */ + * MessageEvent: Executed before changes are announced + * document me. + * + * @param {PreMessageEventArgs} args Info about what's going on + * @return {PreMessageEventResult} How event should be handled + * @memberof Plugin + */ async onPreMessage?(args: PreMessageEventArgs): Promise<PreMessageEventResult>; /** - * LoginEvent: document me - * - * @param {OnLoginEventArgs} args Info about what's going on - * @memberof Plugin - */ + * LoginEvent: document me + * + * @param {OnLoginEventArgs} args Info about what's going on + * @memberof Plugin + */ async onLogin?(args: OnLoginEventArgs): Promise<void>; /** - * LoginEvent: Executed before changes are announced - * document me. - * - * @param {PreLoginEventArgs} args Info about what's going on - * @return {PreLoginEventResult} How event should be handled - * @memberof Plugin - */ + * LoginEvent: Executed before changes are announced + * document me. + * + * @param {PreLoginEventArgs} args Info about what's going on + * @return {PreLoginEventResult} How event should be handled + * @memberof Plugin + */ async onPreLogin?(args: PreLoginEventArgs): Promise<PreLoginEventResult>; /** - * GuildCreateEvent: document me - * - * @param {OnGuildCreateEventArgs} args Info about what's going on - * @memberof Plugin - */ + * GuildCreateEvent: document me + * + * @param {OnGuildCreateEventArgs} args Info about what's going on + * @memberof Plugin + */ async onGuildCreate?(args: OnGuildCreateEventArgs): Promise<void>; /** - * GuildCreateEvent: Executed before changes are announced - * document me. - * - * @param {PreGuildCreateEventArgs} args Info about what's going on - * @return {PreGuildCreateEventResult} How event should be handled - * @memberof Plugin - */ + * GuildCreateEvent: Executed before changes are announced + * document me. + * + * @param {PreGuildCreateEventArgs} args Info about what's going on + * @return {PreGuildCreateEventResult} How event should be handled + * @memberof Plugin + */ async onPreGuildCreate?(args: PreGuildCreateEventArgs): Promise<PreGuildCreateEventResult>; /** - * ChannelCreateEvent: document me - * - * @param {OnChannelCreateEventArgs} args Info about what's going on - * @memberof Plugin - */ + * ChannelCreateEvent: document me + * + * @param {OnChannelCreateEventArgs} args Info about what's going on + * @memberof Plugin + */ async onChannelCreate?(args: OnChannelCreateEventArgs): Promise<void>; /** - * ChannelCreateEvent: Executed before changes are announced - * document me. - * - * @param {PreChannelCreateEventArgs} args Info about what's going on - * @return {PreChannelCreateEventResult} How event should be handled - * @memberof Plugin - */ + * ChannelCreateEvent: Executed before changes are announced + * document me. + * + * @param {PreChannelCreateEventArgs} args Info about what's going on + * @return {PreChannelCreateEventResult} How event should be handled + * @memberof Plugin + */ async onPreChannelCreate?(args: PreChannelCreateEventArgs): Promise<PreChannelCreateEventResult>; /** - * TypingEvent: document me - * - * @param {OnTypingEventArgs} args Info about what's going on - * @memberof Plugin - */ + * TypingEvent: document me + * + * @param {OnTypingEventArgs} args Info about what's going on + * @memberof Plugin + */ async onTyping?(args: OnTypingEventArgs): Promise<void>; /** - * TypingEvent: Executed before changes are announced - * document me. - * - * @param {PreTypingEventArgs} args Info about what's going on - * @return {PreTypingEventResult} How event should be handled - * @memberof Plugin - */ + * TypingEvent: Executed before changes are announced + * document me. + * + * @param {PreTypingEventArgs} args Info about what's going on + * @return {PreTypingEventResult} How event should be handled + * @memberof Plugin + */ async onPreTyping?(args: PreTypingEventArgs): Promise<PreTypingEventResult>; /** - * StatusChangeEvent: document me - * - * @param {OnStatusChangeEventArgs} args Info about what's going on - * @memberof Plugin - */ + * StatusChangeEvent: document me + * + * @param {OnStatusChangeEventArgs} args Info about what's going on + * @memberof Plugin + */ async onStatusChange?(args: OnStatusChangeEventArgs): Promise<void>; /** - * StatusChangeEvent: Executed before changes are announced - * document me. - * - * @param {PreStatusChangeEventArgs} args Info about what's going on - * @return {PreStatusChangeEventResult} How event should be handled - * @memberof Plugin - */ + * StatusChangeEvent: Executed before changes are announced + * document me. + * + * @param {PreStatusChangeEventArgs} args Info about what's going on + * @return {PreStatusChangeEventResult} How event should be handled + * @memberof Plugin + */ async onPreStatusChange?(args: PreStatusChangeEventArgs): Promise<PreStatusChangeEventResult>; - } diff --git a/src/util/plugin/PluginConfig.ts b/src/util/plugin/PluginConfig.ts
index 883bca7c..b9c8aef0 100644 --- a/src/util/plugin/PluginConfig.ts +++ b/src/util/plugin/PluginConfig.ts
@@ -1,6 +1,6 @@ import fs from "fs"; -import { OrmUtils, Environment } from ".."; -import { PluginConfigEntity } from "util/entities/PluginConfig"; +import { Environment } from ".."; +import { PluginConfigEntity } from "../entities/PluginConfig"; // TODO: yaml instead of json const overridePath = process.env.PLUGIN_CONFIG_PATH ?? ""; @@ -14,26 +14,28 @@ let pairs: PluginConfigEntity[]; export const PluginConfig = { init: async function init() { if (config) return config; - console.log('[PluginConfig] Loading configuration...') + console.log("[PluginConfig] Loading configuration..."); pairs = await PluginConfigEntity.find(); config = pairsToConfig(pairs); //config = (config || {}).merge(new ConfigValue()); //config = OrmUtils.mergeDeep(new ConfigValue(), config) - if(process.env.PLUGIN_CONFIG_PATH) + if (process.env.PLUGIN_CONFIG_PATH) try { const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" })); config = overrideConfig.merge(config); } catch (error) { fs.writeFileSync(overridePath, JSON.stringify(config, null, 4)); } - + return this.set(config); }, get: function get() { - if(!config) { - if(Environment.isDebug) - console.log("Oops.. trying to get config without config existing... Returning defaults... (Is the database still initialising?)"); + if (!config) { + if (Environment.isDebug) + console.log( + "Oops.. trying to get config without config existing... Returning defaults... (Is the database still initialising?)" + ); return {}; } return config; @@ -43,7 +45,7 @@ export const PluginConfig = { config = val.merge(config); return applyConfig(config); - }, + } }; function applyConfig(val: any) { @@ -56,17 +58,14 @@ function applyConfig(val: any) { pair.key = key; pair.value = obj; - if(!pair.key || pair.key == null) { - console.log(`[PluginConfig] WARN: Empty key`) + if (!pair.key || pair.key == null) { + console.log(`[PluginConfig] WARN: Empty key`); console.log(pair); - if(Environment.isDebug) debugger; - } - else - return pair.save(); + if (Environment.isDebug) debugger; + } else return pair.save(); } - if(process.env.PLUGIN_CONFIG_PATH) { - if(Environment.isDebug) - console.log(`Writing config: ${process.env.PLUGIN_CONFIG_PATH}`) + if (process.env.PLUGIN_CONFIG_PATH) { + if (Environment.isDebug) console.log(`Writing config: ${process.env.PLUGIN_CONFIG_PATH}`); fs.writeFileSync(overridePath, JSON.stringify(val, null, 4)); } diff --git a/src/util/plugin/PluginEventHandler.ts b/src/util/plugin/PluginEventHandler.ts
index d5fc67f4..3ed1efa6 100644 --- a/src/util/plugin/PluginEventHandler.ts +++ b/src/util/plugin/PluginEventHandler.ts
@@ -1,67 +1,102 @@ -import { PreRegisterEventArgs, OnRegisterEventArgs, PreRegisterEventResult } from './event_types'; -import { PreMessageEventArgs, OnMessageEventArgs, PreMessageEventResult } from './event_types'; -import { PreLoginEventArgs, OnLoginEventArgs, PreLoginEventResult } from './event_types'; -import { PreGuildCreateEventArgs, OnGuildCreateEventArgs, PreGuildCreateEventResult } from './event_types'; -import { PreChannelCreateEventArgs, OnChannelCreateEventArgs, PreChannelCreateEventResult } from './event_types'; -import { PreTypingEventArgs, OnTypingEventArgs, PreTypingEventResult } from './event_types'; -import { PreStatusChangeEventArgs, OnStatusChangeEventArgs, PreStatusChangeEventResult } from './event_types'; import { PluginStore } from "."; +import { + OnChannelCreateEventArgs, + OnGuildCreateEventArgs, + OnLoginEventArgs, + OnMessageEventArgs, + OnRegisterEventArgs, + OnStatusChangeEventArgs, + OnTypingEventArgs, + PreChannelCreateEventArgs, + PreChannelCreateEventResult, + PreGuildCreateEventArgs, + PreGuildCreateEventResult, + PreLoginEventArgs, + PreLoginEventResult, + PreMessageEventArgs, + PreMessageEventResult, + PreRegisterEventArgs, + PreRegisterEventResult, + PreStatusChangeEventArgs, + PreStatusChangeEventResult, + PreTypingEventArgs, + PreTypingEventResult +} from "./event_types"; export class PluginEventHandler { - public static async preRegisterEvent(args: PreRegisterEventArgs): Promise<PreRegisterEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreRegister).map(x=>x.onPreRegister && x.onPreRegister(args)))).filter(x=>x) as PreRegisterEventResult[]; - } - - public static async onRegisterEvent(args: OnRegisterEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onRegister).map(x=>x.onRegister && x.onRegister(args))); - } - - public static async preMessageEvent(args: PreMessageEventArgs): Promise<PreMessageEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreMessage).map(x=>x.onPreMessage && x.onPreMessage(args)))).filter(x=>x) as PreMessageEventResult[]; - } - - public static async onMessageEvent(args: OnMessageEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onMessage).map(x=>x.onMessage && x.onMessage(args))); - } - - public static async preLoginEvent(args: PreLoginEventArgs): Promise<PreLoginEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreLogin).map(x=>x.onPreLogin && x.onPreLogin(args)))).filter(x=>x) as PreLoginEventResult[]; - } - - public static async onLoginEvent(args: OnLoginEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onLogin).map(x=>x.onLogin && x.onLogin(args))); - } - - public static async preGuildCreateEvent(args: PreGuildCreateEventArgs): Promise<PreGuildCreateEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreGuildCreate).map(x=>x.onPreGuildCreate && x.onPreGuildCreate(args)))).filter(x=>x) as PreGuildCreateEventResult[]; - } - - public static async onGuildCreateEvent(args: OnGuildCreateEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onGuildCreate).map(x=>x.onGuildCreate && x.onGuildCreate(args))); - } - - public static async preChannelCreateEvent(args: PreChannelCreateEventArgs): Promise<PreChannelCreateEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreChannelCreate).map(x=>x.onPreChannelCreate && x.onPreChannelCreate(args)))).filter(x=>x) as PreChannelCreateEventResult[]; - } - - public static async onChannelCreateEvent(args: OnChannelCreateEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onChannelCreate).map(x=>x.onChannelCreate && x.onChannelCreate(args))); - } - - public static async preTypingEvent(args: PreTypingEventArgs): Promise<PreTypingEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreTyping).map(x=>x.onPreTyping && x.onPreTyping(args)))).filter(x=>x) as PreTypingEventResult[]; - } - - public static async onTypingEvent(args: OnTypingEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onTyping).map(x=>x.onTyping && x.onTyping(args))); - } - - public static async preStatusChangeEvent(args: PreStatusChangeEventArgs): Promise<PreStatusChangeEventResult[]> { - return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreStatusChange).map(x=>x.onPreStatusChange && x.onPreStatusChange(args)))).filter(x=>x) as PreStatusChangeEventResult[]; - } - - public static async onStatusChangeEvent(args: OnStatusChangeEventArgs): Promise<void> { - await Promise.all(PluginStore.plugins.filter(x=>x.onStatusChange).map(x=>x.onStatusChange && x.onStatusChange(args))); - } - + public static async preRegisterEvent(args: PreRegisterEventArgs): Promise<PreRegisterEventResult[]> { + return ( + await Promise.all(PluginStore.plugins.filter((x) => x.onPreRegister).map((x) => x.onPreRegister && x.onPreRegister(args))) + ).filter((x) => x) as PreRegisterEventResult[]; + } + + public static async onRegisterEvent(args: OnRegisterEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onRegister).map((x) => x.onRegister && x.onRegister(args))); + } + + public static async preMessageEvent(args: PreMessageEventArgs): Promise<PreMessageEventResult[]> { + return ( + await Promise.all(PluginStore.plugins.filter((x) => x.onPreMessage).map((x) => x.onPreMessage && x.onPreMessage(args))) + ).filter((x) => x) as PreMessageEventResult[]; + } + + public static async onMessageEvent(args: OnMessageEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onMessage).map((x) => x.onMessage && x.onMessage(args))); + } + + public static async preLoginEvent(args: PreLoginEventArgs): Promise<PreLoginEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter((x) => x.onPreLogin).map((x) => x.onPreLogin && x.onPreLogin(args)))).filter( + (x) => x + ) as PreLoginEventResult[]; + } + + public static async onLoginEvent(args: OnLoginEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onLogin).map((x) => x.onLogin && x.onLogin(args))); + } + + public static async preGuildCreateEvent(args: PreGuildCreateEventArgs): Promise<PreGuildCreateEventResult[]> { + return ( + await Promise.all( + PluginStore.plugins.filter((x) => x.onPreGuildCreate).map((x) => x.onPreGuildCreate && x.onPreGuildCreate(args)) + ) + ).filter((x) => x) as PreGuildCreateEventResult[]; + } + + public static async onGuildCreateEvent(args: OnGuildCreateEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onGuildCreate).map((x) => x.onGuildCreate && x.onGuildCreate(args))); + } + + public static async preChannelCreateEvent(args: PreChannelCreateEventArgs): Promise<PreChannelCreateEventResult[]> { + return ( + await Promise.all( + PluginStore.plugins.filter((x) => x.onPreChannelCreate).map((x) => x.onPreChannelCreate && x.onPreChannelCreate(args)) + ) + ).filter((x) => x) as PreChannelCreateEventResult[]; + } + + public static async onChannelCreateEvent(args: OnChannelCreateEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onChannelCreate).map((x) => x.onChannelCreate && x.onChannelCreate(args))); + } + + public static async preTypingEvent(args: PreTypingEventArgs): Promise<PreTypingEventResult[]> { + return ( + await Promise.all(PluginStore.plugins.filter((x) => x.onPreTyping).map((x) => x.onPreTyping && x.onPreTyping(args))) + ).filter((x) => x) as PreTypingEventResult[]; + } + + public static async onTypingEvent(args: OnTypingEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onTyping).map((x) => x.onTyping && x.onTyping(args))); + } + + public static async preStatusChangeEvent(args: PreStatusChangeEventArgs): Promise<PreStatusChangeEventResult[]> { + return ( + await Promise.all( + PluginStore.plugins.filter((x) => x.onPreStatusChange).map((x) => x.onPreStatusChange && x.onPreStatusChange(args)) + ) + ).filter((x) => x) as PreStatusChangeEventResult[]; + } + + public static async onStatusChangeEvent(args: OnStatusChangeEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter((x) => x.onStatusChange).map((x) => x.onStatusChange && x.onStatusChange(args))); + } } diff --git a/src/util/plugin/PluginLoader.ts b/src/util/plugin/PluginLoader.ts
index 4dc0129a..9f37ed87 100644 --- a/src/util/plugin/PluginLoader.ts +++ b/src/util/plugin/PluginLoader.ts
@@ -1,16 +1,16 @@ -import path from "path"; import fs from "fs"; -import { Plugin, PluginLoadedEventArgs, PluginManifest, PluginStore } from "./"; -import { PluginIndex } from "plugins/PluginIndex"; +import path from "path"; +import { OrmUtils } from ".."; +import { PluginIndex } from "../../plugins/PluginIndex"; +import { PluginLoadedEventArgs, PluginManifest, PluginStore } from "./"; import { PluginConfig } from "./PluginConfig"; -import { OrmUtils, PluginConfigEntity } from ".."; const root = process.env.PLUGIN_LOCATION || "dist/plugins"; let pluginsLoaded = false; export class PluginLoader { public static async loadPlugins() { - if(pluginsLoaded) return; + if (pluginsLoaded) return; PluginConfig.init(); console.log(`Plugin root directory: ${path.resolve(root)}`); const dirs = fs.readdirSync(root).filter((x) => { @@ -33,33 +33,31 @@ export class PluginLoader { `Plugin info: ${manifest.name} (${manifest.id}), written by ${manifest.authors}, available at ${manifest.repository}` ); const module_ = PluginIndex[manifest.id]; - + module_.pluginPath = modPath; module_.pluginManifest = manifest; Object.freeze(module_.pluginPath); Object.freeze(module_.pluginManifest); - - if(module_.onPluginLoaded) await module_.onPluginLoaded({} as PluginLoadedEventArgs); + + if (module_.onPluginLoaded) await module_.onPluginLoaded({} as PluginLoadedEventArgs); PluginStore.plugins.push(module_); }); console.log(`Done loading ${PluginStore.plugins.length} plugins!`); } - + public static getPluginConfig(id: string, defaults?: any): any { let cfg = PluginConfig.get()[id]; - if(defaults) { - if(cfg) - cfg = OrmUtils.mergeDeep(defaults, cfg); - else - cfg = defaults; + if (defaults) { + if (cfg) cfg = OrmUtils.mergeDeep(defaults, cfg); + else cfg = defaults; this.setPluginConfig(id, cfg); } - if(!cfg) console.log(`[PluginConfig/WARN] Getting plugin settings for '${id}' returned null! (Did you forget to add settings?)`); + if (!cfg) console.log(`[PluginConfig/WARN] Getting plugin settings for '${id}' returned null! (Did you forget to add settings?)`); return cfg; } public static async setPluginConfig(id: string, config: Partial<any>): Promise<void> { - if(!config) console.log(`[PluginConfig/WARN] ${id} tried to set config=null!`); + if (!config) console.log(`[PluginConfig/WARN] ${id} tried to set config=null!`); await PluginConfig.set({ [id]: OrmUtils.mergeDeep(PluginLoader.getPluginConfig(id) || {}, config) }); } } diff --git a/src/util/plugin/PluginManifest.ts b/src/util/plugin/PluginManifest.ts
index 79ecc465..518202ec 100644 --- a/src/util/plugin/PluginManifest.ts +++ b/src/util/plugin/PluginManifest.ts
@@ -1,10 +1,10 @@ export class PluginManifest { - id: string; - name: string; - authors: string[]; - repository: string; - license: string; - version: string // semver - versionCode: number // integer - mainClass: string; -} \ No newline at end of file + id: string; + name: string; + authors: string[]; + repository: string; + license: string; + version: string; // semver + versionCode: number; // integer + mainClass: string; +} diff --git a/src/util/plugin/PluginStore.ts b/src/util/plugin/PluginStore.ts
index 60d7f7b7..8b02f157 100644 --- a/src/util/plugin/PluginStore.ts +++ b/src/util/plugin/PluginStore.ts
@@ -1,9 +1,4 @@ -import path from "path"; -import fs from "fs"; -import { Plugin, PluginLoadedEventArgs, PluginManifest } from "./"; -import { PluginIndex } from "plugins/PluginIndex"; -import { PluginConfig } from "./PluginConfig"; -import { OrmUtils, PluginConfigEntity } from ".."; +import { Plugin } from "./"; const root = process.env.PLUGIN_LOCATION || "dist/plugins"; diff --git a/src/util/plugin/event_types/ChannelCreateEventArgs.ts b/src/util/plugin/event_types/ChannelCreateEventArgs.ts
index 87fa3691..eb103346 100644 --- a/src/util/plugin/event_types/ChannelCreateEventArgs.ts +++ b/src/util/plugin/event_types/ChannelCreateEventArgs.ts
@@ -2,16 +2,16 @@ import { Channel, Guild, User } from "util/entities"; import { EventResult } from "."; export interface PreChannelCreateEventArgs { - channel: Channel, - guild: Guild, - user: User + channel: Channel; + guild: Guild; + user: User; } export interface PreChannelCreateEventResult extends EventResult { - channel: Partial<Channel> + channel: Partial<Channel>; } export interface OnChannelCreateEventArgs { - channel: Channel, - guild: Guild, - user: User + channel: Channel; + guild: Guild; + user: User; } diff --git a/src/util/plugin/event_types/GuildCreateEventArgs.ts b/src/util/plugin/event_types/GuildCreateEventArgs.ts
index 7724b4f3..0df9beb1 100644 --- a/src/util/plugin/event_types/GuildCreateEventArgs.ts +++ b/src/util/plugin/event_types/GuildCreateEventArgs.ts
@@ -2,14 +2,14 @@ import { Guild, User } from "util/entities"; import { EventResult } from "."; export interface PreGuildCreateEventArgs { - user: User, - guild: Guild + user: User; + guild: Guild; } export interface PreGuildCreateEventResult extends EventResult { - guild: Partial<Guild> + guild: Partial<Guild>; } export interface OnGuildCreateEventArgs { - user: User, - guild: Guild + user: User; + guild: Guild; } diff --git a/src/util/plugin/event_types/LoginEventArgs.ts b/src/util/plugin/event_types/LoginEventArgs.ts
index 8f80b69f..4f10e451 100644 --- a/src/util/plugin/event_types/LoginEventArgs.ts +++ b/src/util/plugin/event_types/LoginEventArgs.ts
@@ -2,14 +2,12 @@ import { User } from "util/entities"; import { EventResult } from "."; export interface PreLoginEventArgs { - ip: String, - user: User -} -export interface PreLoginEventResult extends EventResult { - + ip: String; + user: User; } +export interface PreLoginEventResult extends EventResult {} export interface OnLoginEventArgs { - ip: String, - user: User + ip: String; + user: User; } diff --git a/src/util/plugin/event_types/MessageEventArgs.ts b/src/util/plugin/event_types/MessageEventArgs.ts
index ab276429..01df9b75 100644 --- a/src/util/plugin/event_types/MessageEventArgs.ts +++ b/src/util/plugin/event_types/MessageEventArgs.ts
@@ -2,14 +2,14 @@ import { Message, User } from "util/entities"; import { EventResult } from "."; export interface PreMessageEventArgs { - user: User, - message: Message; + user: User; + message: Message; } export interface PreMessageEventResult extends EventResult { - message: Partial<Message> + message: Partial<Message>; } export interface OnMessageEventArgs { - user: User, - message: Message + user: User; + message: Message; } diff --git a/src/util/plugin/event_types/PluginLoadedEventArgs.ts b/src/util/plugin/event_types/PluginLoadedEventArgs.ts
index 58829f15..a585675b 100644 --- a/src/util/plugin/event_types/PluginLoadedEventArgs.ts +++ b/src/util/plugin/event_types/PluginLoadedEventArgs.ts
@@ -1,3 +1 @@ -export interface PluginLoadedEventArgs { - -} \ No newline at end of file +export interface PluginLoadedEventArgs {} diff --git a/src/util/plugin/event_types/RegisterEventArgs.ts b/src/util/plugin/event_types/RegisterEventArgs.ts
index d36d7e64..f3e0fdd4 100644 --- a/src/util/plugin/event_types/RegisterEventArgs.ts +++ b/src/util/plugin/event_types/RegisterEventArgs.ts
@@ -2,16 +2,16 @@ import { User } from "util/entities"; import { EventResult } from "."; export interface PreRegisterEventArgs { - age: any, - user: User, - ip: String + age: any; + user: User; + ip: String; } export interface PreRegisterEventResult extends EventResult { - user: Partial<User> + user: Partial<User>; } export interface OnRegisterEventArgs { - age: any, - user: User, - ip: String + age: any; + user: User; + ip: String; } diff --git a/src/util/plugin/event_types/StatusChangeEventArgs.ts b/src/util/plugin/event_types/StatusChangeEventArgs.ts
index c1a67112..b412cffa 100644 --- a/src/util/plugin/event_types/StatusChangeEventArgs.ts +++ b/src/util/plugin/event_types/StatusChangeEventArgs.ts
@@ -3,14 +3,14 @@ import { Presence } from "util/interfaces"; import { EventResult } from "."; export interface PreStatusChangeEventArgs { - user: User, - presence: Presence + user: User; + presence: Presence; } export interface PreStatusChangeEventResult extends EventResult { - presence: Partial<Presence> + presence: Partial<Presence>; } export interface OnStatusChangeEventArgs { - user: User, - presence: Presence + user: User; + presence: Presence; } diff --git a/src/util/plugin/event_types/TypingEventArgs.ts b/src/util/plugin/event_types/TypingEventArgs.ts
index 3ac59b41..694ef83b 100644 --- a/src/util/plugin/event_types/TypingEventArgs.ts +++ b/src/util/plugin/event_types/TypingEventArgs.ts
@@ -2,16 +2,14 @@ import { Channel, Guild, User } from "util/entities"; import { EventResult } from "."; export interface PreTypingEventArgs { - channel: Channel, - guild: Guild, - user: User -} -export interface PreTypingEventResult extends EventResult { - + channel: Channel; + guild: Guild; + user: User; } +export interface PreTypingEventResult extends EventResult {} export interface OnTypingEventArgs { - channel: Channel, - guild: Guild, - user: User + channel: Channel; + guild: Guild; + user: User; } diff --git a/src/util/plugin/event_types/_gen.sh b/src/util/plugin/event_types/_gen.sh
index 9f761d1e..f8769301 100755 --- a/src/util/plugin/event_types/_gen.sh +++ b/src/util/plugin/event_types/_gen.sh
@@ -48,8 +48,8 @@ do echo " async onPre${event}?(args: Pre${event}EventArgs): Promise<Pre${event}EventResult>;" ) >> ../plugin.eventfuncs.generated - echo "import { Pre${event}EventArgs, On${event}EventArgs, Pre${event}EventResult } from './event_types';" >> ../PluginEventHandler.ts.1 - echo "import { Pre${event}EventArgs, Pre${event}EventResult, On${event}EventArgs } from '.';" >> ../plugin.imports.generated + echo "import { Pre${event}EventArgs, On${event}EventArgs, Pre${event}EventResult } from \"./event_types\";" >> ../PluginEventHandler.ts.1 + echo "import { Pre${event}EventArgs, Pre${event}EventResult, On${event}EventArgs } from \".\";" >> ../plugin.imports.generated cmp --silent "${event}EventArgs.ts" "${event}EventArgs.ts.generated" && rm -f "${event}EventArgs.ts.generated" done < _pdo diff --git a/src/util/plugin/event_types/base/EventResult.ts b/src/util/plugin/event_types/base/EventResult.ts
index f18837cd..7acaa775 100644 --- a/src/util/plugin/event_types/base/EventResult.ts +++ b/src/util/plugin/event_types/base/EventResult.ts
@@ -1,4 +1,4 @@ export interface EventResult { - cancel?: boolean; - blockReason?: string; -} \ No newline at end of file + cancel?: boolean; + blockReason?: string; +} diff --git a/src/util/plugin/event_types/index.ts b/src/util/plugin/event_types/index.ts
index 4a585dc0..773e8dc9 100644 --- a/src/util/plugin/event_types/index.ts +++ b/src/util/plugin/event_types/index.ts
@@ -1,3 +1,4 @@ +export * from "./base/index"; export * from "./ChannelCreateEventArgs"; export * from "./GuildCreateEventArgs"; export * from "./LoginEventArgs"; @@ -6,4 +7,3 @@ export * from "./PluginLoadedEventArgs"; export * from "./RegisterEventArgs"; export * from "./StatusChangeEventArgs"; export * from "./TypingEventArgs"; -export * from "./base/index"; diff --git a/src/util/plugin/index.ts b/src/util/plugin/index.ts
index 7a297981..ffc7803e 100644 --- a/src/util/plugin/index.ts +++ b/src/util/plugin/index.ts
@@ -1,7 +1,7 @@ +export * from "./event_types/index"; export * from "./Plugin"; export * from "./PluginConfig"; export * from "./PluginEventHandler"; export * from "./PluginLoader"; export * from "./PluginManifest"; export * from "./PluginStore"; -export * from "./event_types/index"; diff --git a/src/util/schemas/ActivitySchema.ts b/src/util/schemas/ActivitySchema.ts
index d94557ea..a572b01a 100644 --- a/src/util/schemas/ActivitySchema.ts +++ b/src/util/schemas/ActivitySchema.ts
@@ -1,4 +1,4 @@ -import { Activity, Status } from "@fosscord/util"; +import { Activity, Status } from ".."; export const ActivitySchema = { afk: Boolean, diff --git a/src/util/schemas/ChannelPermissionOverwriteSchema.ts b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
index e8bc13bb..faa957dd 100644 --- a/src/util/schemas/ChannelPermissionOverwriteSchema.ts +++ b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
@@ -1,4 +1,4 @@ -import { ChannelPermissionOverwrite } from "@fosscord/util"; +import { ChannelPermissionOverwrite } from ".."; // TODO: Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel) diff --git a/src/util/schemas/MessageCreateSchema.ts b/src/util/schemas/MessageCreateSchema.ts
index bf3470bb..62c93754 100644 --- a/src/util/schemas/MessageCreateSchema.ts +++ b/src/util/schemas/MessageCreateSchema.ts
@@ -1,4 +1,4 @@ -import { Embed } from "@fosscord/util"; +import { Embed } from ".."; export interface MessageCreateSchema { type?: number; diff --git a/src/util/schemas/RelationshipPutSchema.ts b/src/util/schemas/RelationshipPutSchema.ts
index 0a7f9720..f90c0d56 100644 --- a/src/util/schemas/RelationshipPutSchema.ts +++ b/src/util/schemas/RelationshipPutSchema.ts
@@ -1,4 +1,4 @@ -import { RelationshipType } from "@fosscord/util"; +import { RelationshipType } from ".."; export interface RelationshipPutSchema { type?: RelationshipType; diff --git a/src/util/schemas/UserSettingsSchema.ts b/src/util/schemas/UserSettingsSchema.ts
index eb9b316d..657f483e 100644 --- a/src/util/schemas/UserSettingsSchema.ts +++ b/src/util/schemas/UserSettingsSchema.ts
@@ -1,3 +1,3 @@ -import { UserSettings } from "@fosscord/util"; +import { UserSettings } from ".."; export interface UserSettingsSchema extends Partial<UserSettings> {} diff --git a/src/util/schemas/VoiceStateUpdateSchema.ts b/src/util/schemas/VoiceStateUpdateSchema.ts
index ea286b1a..0dec6383 100644 --- a/src/util/schemas/VoiceStateUpdateSchema.ts +++ b/src/util/schemas/VoiceStateUpdateSchema.ts
@@ -6,7 +6,7 @@ export const VoiceStateUpdateSchema = { self_video: Boolean }; -//TODO need more testing when community guild and voice stage channel are working +//TODO: need more testing when community guild and voice stage channel are working export interface VoiceStateUpdateSchema { channel_id: string; guild_id?: string; diff --git a/src/util/util/Base64.ts b/src/util/util/Base64.ts new file mode 100644
index 00000000..46cff77a --- /dev/null +++ b/src/util/util/Base64.ts
@@ -0,0 +1,47 @@ +const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+"; + +// binary to string lookup table +const b2s = alphabet.split(""); + +// string to binary lookup table +// 123 == 'z'.charCodeAt(0) + 1 +const s2b = new Array(123); +for (let i = 0; i < alphabet.length; i++) { + s2b[alphabet.charCodeAt(i)] = i; +} + +// number to base64 +export const ntob = (n: number): string => { + if (n < 0) return `-${ntob(-n)}`; + + let lo = n >>> 0; + let hi = (n / 4294967296) >>> 0; + + let right = ""; + while (hi > 0) { + right = b2s[0x3f & lo] + right; + lo >>>= 6; + lo |= (0x3f & hi) << 26; + hi >>>= 6; + } + + let left = ""; + do { + left = b2s[0x3f & lo] + left; + lo >>>= 6; + } while (lo > 0); + + return left + right; +}; + +// base64 to number +export const bton = (base64: string) => { + let number = 0; + const sign = base64.charAt(0) === "-" ? 1 : 0; + + for (let i = sign; i < base64.length; i++) { + number = number * 64 + s2b[base64.charCodeAt(i)]; + } + + return sign ? -number : number; +}; diff --git a/src/util/util/Config.ts b/src/util/util/Config.ts
index cc7090a6..49a1f3f8 100644 --- a/src/util/util/Config.ts +++ b/src/util/util/Config.ts
@@ -4,7 +4,6 @@ import { OrmUtils } from "."; import { ConfigValue } from "../config"; import { ConfigEntity } from "../entities/Config"; -// TODO: yaml instead of json const overridePath = process.env.CONFIG_PATH ?? ""; let config: ConfigValue; diff --git a/src/util/util/Environment.ts b/src/util/util/Environment.ts
index a6d68785..3ebeb56c 100644 --- a/src/util/util/Environment.ts +++ b/src/util/util/Environment.ts
@@ -1,3 +1,3 @@ export class Environment { - static isDebug: boolean = /--debug|--inspect/.test(process.execArgv.join(' ')); + static isDebug: boolean = /--debug|--inspect/.test(process.execArgv.join(" ")); } diff --git a/src/util/util/Logo.ts b/src/util/util/Logo.ts
index b1627198..3e108af2 100644 --- a/src/util/util/Logo.ts +++ b/src/util/util/Logo.ts
@@ -1,41 +1,40 @@ -import { existsSync } from "fs"; import { execSync } from "child_process"; +import { existsSync } from "fs"; export class Logo { - public static printLogo(){ - if(existsSync("/usr/bin/chafa")) - return execSync("chafa https://raw.githubusercontent.com/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Wordmark-Orange.svg", { - env: process.env, - encoding: "utf-8", - stdio: "inherit", - - }); - else console.log(Logo.logoVersions['1'] as string) - } - private static getConsoleColors(): number { - return 1; - if(!process.env.TERM) return 1; - else { - switch (process.env.TERM) { - case "": - - break; - - default: - break; - } - } - return 1; - } - private static logoVersions: any = { - '1': - `███████╗ ██████╗ ███████╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ + public static printLogo() { + if (existsSync("/usr/bin/chafa")) + return execSync( + "chafa https://raw.githubusercontent.com/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Wordmark-Orange.svg", + { + env: process.env, + encoding: "utf-8", + stdio: "inherit" + } + ); + else console.log(Logo.logoVersions["1"] as string); + } + private static getConsoleColors(): number { + return 1; + if (!process.env.TERM) return 1; + else { + switch (process.env.TERM) { + case "": + break; + + default: + break; + } + } + return 1; + } + private static logoVersions: any = { + "1": `███████╗ ██████╗ ███████╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██╔════╝██╔═══██╗██╔════╝██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗ █████╗ ██║ ██║███████╗███████╗██║ ██║ ██║██████╔╝██║ ██║ ██╔══╝ ██║ ██║╚════██║╚════██║██║ ██║ ██║██╔══██╗██║ ██║ ██║ ╚██████╔╝███████║███████║╚██████╗╚██████╔╝██║ ██║██████╔╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝`, - '2':`` - - } -} \ No newline at end of file + "2": `` + }; +} diff --git a/src/util/util/Permissions.ts b/src/util/util/Permissions.ts
index b8d0d8ae..bc98edb3 100644 --- a/src/util/util/Permissions.ts +++ b/src/util/util/Permissions.ts
@@ -55,11 +55,14 @@ export class Permissions extends BitField { MANAGE_EMOJIS_AND_STICKERS: BitFlag(30), USE_APPLICATION_COMMANDS: BitFlag(31), REQUEST_TO_SPEAK: BitFlag(32), - // TODO: what is permission 33? + MANAGE_EVENTS: BitFlag(33), MANAGE_THREADS: BitFlag(34), USE_PUBLIC_THREADS: BitFlag(35), USE_PRIVATE_THREADS: BitFlag(36), - USE_EXTERNAL_STICKERS: BitFlag(37) + USE_EXTERNAL_STICKERS: BitFlag(37), + SEND_MESSAGES_IN_THREADS: BitFlag(38), + START_VOICE_ACTIVITIES: BitFlag(39), + MODERATE_MEMBERS: BitFlag(40) /** * CUSTOM PERMISSIONS ideas: diff --git a/src/util/util/RandomInviteID.ts b/src/util/util/RandomInviteID.ts new file mode 100644
index 00000000..8ffca06b --- /dev/null +++ b/src/util/util/RandomInviteID.ts
@@ -0,0 +1,31 @@ +import { Snowflake } from "."; + +export function random(length = 6) { + // Declare all characters + let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + // Pick characers randomly + let str = ""; + for (let i = 0; i < length; i++) { + str += chars.charAt(Math.floor(Math.random() * chars.length)); + } + + return str; +} + +export function snowflakeBasedInvite() { + // Declare all characters + let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + let base = BigInt(chars.length); + let snowflake = Snowflake.generateWorkerProcess(); + + // snowflakes hold ~10.75 characters worth of entropy; + // safe to generate a 8-char invite out of them + let str = ""; + for (let i = 0; i < 10; i++) { + str.concat(chars.charAt(Number(snowflake % base))); + snowflake = snowflake / base; + } + + return str.substr(3, 8).split("").reverse().join(""); +} diff --git a/src/util/util/Rights.ts b/src/util/util/Rights.ts
index 236bfea7..d2a7f1f7 100644 --- a/src/util/util/Rights.ts +++ b/src/util/util/Rights.ts
@@ -5,7 +5,7 @@ import { BitField, BitFieldResolvable, BitFlag } from "./BitField"; export type RightResolvable = bigint | number | Rights | RightResolvable[] | RightString; type RightString = keyof typeof Rights.FLAGS; -// TODO: just like roles for members, users should have privilidges which combine multiple rights into one and make it easy to assign +// TODO: just like roles for members, users should have privilides which combine multiple rights into one and make it easy to assign export class Rights extends BitField { constructor(bits: BitFieldResolvable = 0) { diff --git a/src/util/util/String.ts b/src/util/util/String.ts
index 55f11e8d..5e6bfb6f 100644 --- a/src/util/util/String.ts +++ b/src/util/util/String.ts
@@ -1,3 +1,5 @@ +import { Request } from "express"; +import { FieldErrors, ntob } from "."; import { SPECIAL_CHAR } from "./Regex"; export function trimSpecial(str?: string): string { @@ -5,3 +7,18 @@ export function trimSpecial(str?: string): string { if (!str) return; return str.replace(SPECIAL_CHAR, "").trim(); } + +export function checkLength(str: string, min: number, max: number, key: string, req: Request) { + if (str.length < min || str.length > max) { + throw FieldErrors({ + [key]: { + code: "BASE_TYPE_BAD_LENGTH", + message: req.t("common:field.BASE_TYPE_BAD_LENGTH", { length: `${min} - ${max}` }) + } + }); + } +} + +export function generateCode() { + return ntob(Date.now() + Math.randomIntBetween(0, 10000)); +} diff --git a/src/util/util/index.ts b/src/util/util/index.ts
index 4135f44e..b13fe9ad 100644 --- a/src/util/util/index.ts +++ b/src/util/util/index.ts
@@ -1,5 +1,6 @@ export * from "./ApiError"; export * from "./Array"; +export * from "./Base64"; export * from "./BitField"; //export * from "./Categories"; export * from "./cdn"; @@ -7,6 +8,7 @@ export * from "./Config"; export * from "./Constants"; export * from "./Database"; export * from "./Email"; +export * from "./Environment"; export * from "./Event"; export * from "./FieldError"; export * from "./imports/HTTPError"; @@ -14,9 +16,12 @@ export * from "./imports/index"; export * from "./imports/OrmUtils"; export * from "./Intents"; export * from "./InvisibleCharacters"; +export * from "./ipAddress"; +export * from "./Logo"; export * from "./MessageFlags"; export * from "./Permissions"; export * from "./RabbitMQ"; +export * from "./RandomInviteID"; export * from "./Regex"; export * from "./Rights"; export * from "./Snowflake"; diff --git a/src/util/util/ipAddress.ts b/src/util/util/ipAddress.ts new file mode 100644
index 00000000..925c62e5 --- /dev/null +++ b/src/util/util/ipAddress.ts
@@ -0,0 +1,99 @@ +import { Request } from "express"; +import { Config } from "."; +// use ipdata package instead of simple fetch because of integrated caching +import fetch from "node-fetch"; + +const exampleData = { + ip: "", + is_eu: true, + city: "", + region: "", + region_code: "", + country_name: "", + country_code: "", + continent_name: "", + continent_code: "", + latitude: 0, + longitude: 0, + postal: "", + calling_code: "", + flag: "", + emoji_flag: "", + emoji_unicode: "", + asn: { + asn: "", + name: "", + domain: "", + route: "", + type: "isp" + }, + languages: [ + { + name: "", + native: "" + } + ], + currency: { + name: "", + code: "", + symbol: "", + native: "", + plural: "" + }, + time_zone: { + name: "", + abbr: "", + offset: "", + is_dst: true, + current_time: "" + }, + threat: { + is_tor: false, + is_proxy: false, + is_anonymous: false, + is_known_attacker: false, + is_known_abuser: false, + is_threat: false, + is_bogon: false + }, + count: 0, + status: 200 +}; + +//TODO: add function that support both ip and domain names +export async function IPAnalysis(ip: string): Promise<typeof exampleData> { + const { ipdataApiKey } = Config.get().security; + if (!ipdataApiKey) return { ...exampleData, ip }; + + return (await fetch(`https://api.ipdata.co/${ip}?api-key=${ipdataApiKey}`)).json() as any; +} + +export function isProxy(data: typeof exampleData) { + if (!data || !data.asn || !data.threat) return false; + if (data.asn.type !== "isp") return true; + if (Object.values(data.threat).some((x) => x)) return true; + + return false; +} + +export function getIpAdress(req: Request): string { + // @ts-ignore + return ( + req.headers[Config.get().security.forwadedFor as string] || + req.headers[Config.get().security.forwadedFor?.toLowerCase() as string] || + req.socket.remoteAddress + ); +} + +export function distanceBetweenLocations(loc1: any, loc2: any): number { + return distanceBetweenCoords(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude); +} + +//Haversine function +function distanceBetweenCoords(lat1: number, lon1: number, lat2: number, lon2: number) { + const p = 0.017453292519943295; // Math.PI / 180 + const c = Math.cos; + const a = 0.5 - c((lat2 - lat1) * p) / 2 + (c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p))) / 2; + + return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km +} diff --git a/src/util/util/passwordStrength.ts b/src/util/util/passwordStrength.ts new file mode 100644
index 00000000..1026a07e --- /dev/null +++ b/src/util/util/passwordStrength.ts
@@ -0,0 +1,59 @@ +import { Config } from "."; + +const reNUMBER = /[0-9]/g; +const reUPPERCASELETTER = /[A-Z]/g; +const reSYMBOLS = /[A-Z,a-z,0-9]/g; + +const blocklist: string[] = []; // TODO: update ones passwordblocklist is stored in db +/* + * https://en.wikipedia.org/wiki/Password_policy + * password must meet following criteria, to be perfect: + * - min <n> chars + * - min <n> numbers + * - min <n> symbols + * - min <n> uppercase chars + * - shannon entropy folded into [0, 1) interval + * + * Returns: 0 > pw > 1 + */ +export function checkPassword(password: string): number { + const { minLength, minNumbers, minUpperCase, minSymbols } = Config.get().register.password; + let strength = 0; + + // checks for total password len + if (password.length >= minLength - 1) { + strength += 0.05; + } + + // checks for amount of Numbers + if (password.count(reNUMBER) >= minNumbers - 1) { + strength += 0.05; + } + + // checks for amount of Uppercase Letters + if (password.count(reUPPERCASELETTER) >= minUpperCase - 1) { + strength += 0.05; + } + + // checks for amount of symbols + if (password.replace(reSYMBOLS, "").length >= minSymbols - 1) { + strength += 0.05; + } + + // checks if password only consists of numbers or only consists of chars + if (password.length == password.count(reNUMBER) || password.length === password.count(reUPPERCASELETTER)) { + strength = 0; + } + + let entropyMap: { [key: string]: number } = {}; + for (let i = 0; i < password.length; i++) { + if (entropyMap[password[i]]) entropyMap[password[i]]++; + else entropyMap[password[i]] = 1; + } + + let entropies = Object.values(entropyMap); + + entropies.map((x) => x / entropyMap.length); + strength += entropies.reduceRight((a: number, x: number) => a - x * Math.log2(x)) / Math.log2(password.length); + return strength; +}