diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2022-08-11 23:11:48 +0200 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2022-08-13 21:57:51 +0200 |
commit | 34ca1a8a6c1b195c45f13ebd3b29064a9623af6f (patch) | |
tree | 26314ecd6bf95d5f8783744340e30fa0cdfc2811 | |
parent | Make fosscord read config from json if CONFIG_PATH is set (diff) | |
download | server-34ca1a8a6c1b195c45f13ebd3b29064a9623af6f.tar.xz |
Make ConfigValue a directory, move defaults to those classes instead of a separate object
52 files changed, 364 insertions, 409 deletions
diff --git a/gateway/src/opcodes/VoiceStateUpdate.ts b/gateway/src/opcodes/VoiceStateUpdate.ts index d62425f3..8c430d56 100644 --- a/gateway/src/opcodes/VoiceStateUpdate.ts +++ b/gateway/src/opcodes/VoiceStateUpdate.ts @@ -7,12 +7,12 @@ import { emitEvent, Guild, Member, - Region, VoiceServerUpdateEvent, VoiceState, VoiceStateUpdateEvent, } from "@fosscord/util"; import { OrmUtils } from "@fosscord/util"; +import { Region } from "@fosscord/util/src/config"; // TODO: check if a voice server is setup // Notice: Bot users respect the voice channel's user limit, if set. When the voice channel is full, you will not receive the Voice State Update or Voice Server Update events in response to your own Voice State Update. Having MANAGE_CHANNELS permission bypasses this limit and allows you to join regardless of the channel being full or not. diff --git a/util/src/config/Config.ts b/util/src/config/Config.ts new file mode 100644 index 00000000..b703040f --- /dev/null +++ b/util/src/config/Config.ts @@ -0,0 +1,22 @@ +import { ApiConfiguration, ClientConfiguration, DefaultsConfiguration, EndpointConfiguration, GeneralConfiguration, GifConfiguration, GuildConfiguration, KafkaConfiguration, LimitsConfiguration, LoginConfiguration, MetricsConfiguration, RabbitMQConfiguration, RegionConfiguration, RegisterConfiguration, SecurityConfiguration, SentryConfiguration, TemplateConfiguration } from "../config"; + +export class ConfigValue { + gateway: EndpointConfiguration = new EndpointConfiguration(); + cdn: EndpointConfiguration = new EndpointConfiguration(); + api: ApiConfiguration = new ApiConfiguration(); + general: GeneralConfiguration = new GeneralConfiguration(); + limits: LimitsConfiguration = new LimitsConfiguration(); + security: SecurityConfiguration = new SecurityConfiguration(); + login: LoginConfiguration = new LoginConfiguration(); + register: RegisterConfiguration = new RegisterConfiguration(); + regions: RegionConfiguration = new RegionConfiguration(); + guild: GuildConfiguration = new GuildConfiguration(); + gif: GifConfiguration = new GifConfiguration(); + rabbitmq: RabbitMQConfiguration = new RabbitMQConfiguration(); + kafka: KafkaConfiguration = new KafkaConfiguration(); + templates: TemplateConfiguration = new TemplateConfiguration(); + client: ClientConfiguration = new ClientConfiguration(); + metrics: MetricsConfiguration = new MetricsConfiguration(); + sentry: SentryConfiguration = new SentryConfiguration(); + defaults: DefaultsConfiguration = new DefaultsConfiguration(); +} \ No newline at end of file diff --git a/util/src/config/index.ts b/util/src/config/index.ts new file mode 100644 index 00000000..0a9b58ae --- /dev/null +++ b/util/src/config/index.ts @@ -0,0 +1,2 @@ +export * from "./Config"; +export * from "./types/index"; diff --git a/util/src/config/types/ApiConfiguration.ts b/util/src/config/types/ApiConfiguration.ts new file mode 100644 index 00000000..16b1efba --- /dev/null +++ b/util/src/config/types/ApiConfiguration.ts @@ -0,0 +1,5 @@ +export class ApiConfiguration { + defaultVersion: string = "9"; + activeVersions: string[] = ["6", "7", "8", "9"]; + useFosscordEnhancements: boolean = true; +} \ No newline at end of file diff --git a/util/src/config/types/ClientConfiguration.ts b/util/src/config/types/ClientConfiguration.ts new file mode 100644 index 00000000..1adda1e2 --- /dev/null +++ b/util/src/config/types/ClientConfiguration.ts @@ -0,0 +1,8 @@ +import { ClientReleaseConfiguration } from "."; + +export class ClientConfiguration { + //classes + releases: ClientReleaseConfiguration = new ClientReleaseConfiguration(); + //base types + useTestClient: boolean = true; +} \ No newline at end of file diff --git a/util/src/config/types/DefaultsConfiguration.ts b/util/src/config/types/DefaultsConfiguration.ts new file mode 100644 index 00000000..c3171a01 --- /dev/null +++ b/util/src/config/types/DefaultsConfiguration.ts @@ -0,0 +1,5 @@ +import { GuildDefaults } from "."; + +export class DefaultsConfiguration { + guild: GuildDefaults = new GuildDefaults(); +} \ No newline at end of file diff --git a/util/src/config/types/EndpointConfiguration.ts b/util/src/config/types/EndpointConfiguration.ts new file mode 100644 index 00000000..87baea31 --- /dev/null +++ b/util/src/config/types/EndpointConfiguration.ts @@ -0,0 +1,5 @@ +export class EndpointConfiguration { + endpointClient: string | null = null; + endpointPrivate: string | null = null; + endpointPublic: string | null = null; +} \ No newline at end of file diff --git a/util/src/config/types/GeneralConfiguration.ts b/util/src/config/types/GeneralConfiguration.ts new file mode 100644 index 00000000..55848b44 --- /dev/null +++ b/util/src/config/types/GeneralConfiguration.ts @@ -0,0 +1,12 @@ +import { Snowflake } from "../../util"; + +export class GeneralConfiguration { + instanceName: string = "Fosscord Instance"; + instanceDescription: string | null = "This is a Fosscord instance made in the pre-release days"; + frontPage: string | null = null; + tosPage: string | null = null; + correspondenceEmail: string | null = "noreply@localhost.local"; + correspondenceUserID: string | null = null; + image: string | null = null; + instanceId: string = Snowflake.generate(); +} \ No newline at end of file diff --git a/util/src/config/types/GifConfiguration.ts b/util/src/config/types/GifConfiguration.ts new file mode 100644 index 00000000..6a2d520d --- /dev/null +++ b/util/src/config/types/GifConfiguration.ts @@ -0,0 +1,5 @@ +export class GifConfiguration { + enabled: boolean = true; + provider: "tenor" = "tenor"; // more coming soon + apiKey?: string = "LIVDSRZULELA"; +} \ No newline at end of file diff --git a/util/src/config/types/GuildConfiguration.ts b/util/src/config/types/GuildConfiguration.ts new file mode 100644 index 00000000..3d43b368 --- /dev/null +++ b/util/src/config/types/GuildConfiguration.ts @@ -0,0 +1,6 @@ +import { DiscoveryConfiguration, AutoJoinConfiguration } from "."; + +export class GuildConfiguration { + discovery: DiscoveryConfiguration = new DiscoveryConfiguration(); + autoJoin: AutoJoinConfiguration = new AutoJoinConfiguration(); +} diff --git a/util/src/config/types/KafkaConfiguration.ts b/util/src/config/types/KafkaConfiguration.ts new file mode 100644 index 00000000..7932f49e --- /dev/null +++ b/util/src/config/types/KafkaConfiguration.ts @@ -0,0 +1,5 @@ +import { KafkaBroker } from "."; + +export class KafkaConfiguration { + brokers: KafkaBroker[] | null = null; +} \ No newline at end of file diff --git a/util/src/config/types/LimitConfigurations.ts b/util/src/config/types/LimitConfigurations.ts new file mode 100644 index 00000000..bcc2e7e2 --- /dev/null +++ b/util/src/config/types/LimitConfigurations.ts @@ -0,0 +1,9 @@ +import { ChannelLimits, GuildLimits, MessageLimits, RateLimits, UserLimits } from "."; + +export class LimitsConfiguration { + user: UserLimits = new UserLimits(); + guild: GuildLimits = new GuildLimits(); + message: MessageLimits = new MessageLimits(); + channel: ChannelLimits = new ChannelLimits(); + rate: RateLimits = new RateLimits(); +} \ No newline at end of file diff --git a/util/src/config/types/LoginConfiguration.ts b/util/src/config/types/LoginConfiguration.ts new file mode 100644 index 00000000..255c9451 --- /dev/null +++ b/util/src/config/types/LoginConfiguration.ts @@ -0,0 +1,3 @@ +export class LoginConfiguration { + requireCaptcha: boolean = false; +} \ No newline at end of file diff --git a/util/src/config/types/MetricsConfiguration.ts b/util/src/config/types/MetricsConfiguration.ts new file mode 100644 index 00000000..d7cd4937 --- /dev/null +++ b/util/src/config/types/MetricsConfiguration.ts @@ -0,0 +1,3 @@ +export class MetricsConfiguration { + timeout: number = 30000; +} \ No newline at end of file diff --git a/util/src/config/types/RabbitMQConfiguration.ts b/util/src/config/types/RabbitMQConfiguration.ts new file mode 100644 index 00000000..ce4a9123 --- /dev/null +++ b/util/src/config/types/RabbitMQConfiguration.ts @@ -0,0 +1,3 @@ +export class RabbitMQConfiguration { + host: string | null = null; +} \ No newline at end of file diff --git a/util/src/config/types/RegionConfiguration.ts b/util/src/config/types/RegionConfiguration.ts new file mode 100644 index 00000000..09d9271c --- /dev/null +++ b/util/src/config/types/RegionConfiguration.ts @@ -0,0 +1,16 @@ +import { Region } from "."; + +export class RegionConfiguration { + default: string = "fosscord"; + useDefaultAsOptimal: boolean = true; + available: Region[] = [ + { + id: "fosscord", + name: "Fosscord", + endpoint: "127.0.0.1:3004", + vip: false, + custom: false, + deprecated: false, + }, + ]; +} \ No newline at end of file diff --git a/util/src/config/types/RegisterConfiguration.ts b/util/src/config/types/RegisterConfiguration.ts new file mode 100644 index 00000000..a0dc97c5 --- /dev/null +++ b/util/src/config/types/RegisterConfiguration.ts @@ -0,0 +1,18 @@ +import { DateOfBirthConfiguration, EmailConfiguration, PasswordConfiguration } from "."; + +export class RegisterConfiguration { + //classes + email: EmailConfiguration = new EmailConfiguration(); + dateOfBirth: DateOfBirthConfiguration = new DateOfBirthConfiguration(); + password: PasswordConfiguration = new PasswordConfiguration(); + //base types + disabled: boolean = false; + requireCaptcha: boolean = true; + requireInvite: boolean = false; + guestsRequireInvite: boolean = true; + allowNewRegistration: boolean = true; + allowMultipleAccounts: boolean = true; + blockProxies: boolean = true; + incrementingDiscriminators: boolean = false; // random otherwise + defaultRights: string = "0"; +} diff --git a/util/src/config/types/SecurityConfiguration.ts b/util/src/config/types/SecurityConfiguration.ts new file mode 100644 index 00000000..405b86ac --- /dev/null +++ b/util/src/config/types/SecurityConfiguration.ts @@ -0,0 +1,17 @@ +import crypto from "crypto"; +import { CaptchaConfiguration, TwoFactorConfiguration } from "."; + +export class SecurityConfiguration { + //classes + captcha: CaptchaConfiguration = new CaptchaConfiguration(); + twoFactor: TwoFactorConfiguration = new TwoFactorConfiguration(); + //base types + autoUpdate: boolean | number = true; + requestSignature: string = crypto.randomBytes(32).toString("base64"); + jwtSecret: string = crypto.randomBytes(256).toString("base64"); + // header to get the real user ip address + // X-Forwarded-For for nginx/reverse proxies + // CF-Connecting-IP for cloudflare + forwadedFor: string | null = null; + ipdataApiKey: string | null = "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9"; +} diff --git a/util/src/config/types/SentryConfiguration.ts b/util/src/config/types/SentryConfiguration.ts new file mode 100644 index 00000000..836094a1 --- /dev/null +++ b/util/src/config/types/SentryConfiguration.ts @@ -0,0 +1,8 @@ +import { hostname } from "os"; + +export class SentryConfiguration { + enabled: boolean = false; + endpoint: string = "https://05e8e3d005f34b7d97e920ae5870a5e5@sentry.thearcanebrony.net/6"; + traceSampleRate: number = 1.0; + environment: string = hostname(); +} \ No newline at end of file diff --git a/util/src/config/types/TemplateConfiguration.ts b/util/src/config/types/TemplateConfiguration.ts new file mode 100644 index 00000000..4a9aa8f2 --- /dev/null +++ b/util/src/config/types/TemplateConfiguration.ts @@ -0,0 +1,6 @@ +export class TemplateConfiguration { + enabled: boolean = true; + allowTemplateCreation: boolean = true; + allowDiscordTemplates: boolean = true; + allowRaws: boolean = true; +} \ No newline at end of file diff --git a/util/src/config/types/index.ts b/util/src/config/types/index.ts new file mode 100644 index 00000000..608503a0 --- /dev/null +++ b/util/src/config/types/index.ts @@ -0,0 +1,18 @@ +export * from "./ApiConfiguration"; +export * from "./ClientConfiguration"; +export * from "./DefaultsConfiguration"; +export * from "./EndpointConfiguration"; +export * from "./GeneralConfiguration"; +export * from "./GifConfiguration"; +export * from "./GuildConfiguration"; +export * from "./KafkaConfiguration"; +export * from "./LimitConfigurations"; +export * from "./LoginConfiguration"; +export * from "./MetricsConfiguration"; +export * from "./RabbitMQConfiguration"; +export * from "./RegionConfiguration"; +export * from "./RegisterConfiguration"; +export * from "./SecurityConfiguration"; +export * from "./SentryConfiguration"; +export * from "./TemplateConfiguration"; +export * from "./subconfigurations/index"; diff --git a/util/src/config/types/subconfigurations/client/ClientReleaseConfiguration.ts b/util/src/config/types/subconfigurations/client/ClientReleaseConfiguration.ts new file mode 100644 index 00000000..54e7f365 --- /dev/null +++ b/util/src/config/types/subconfigurations/client/ClientReleaseConfiguration.ts @@ -0,0 +1,4 @@ +export class ClientReleaseConfiguration { + useLocalRelease: boolean = true; //TODO + upstreamVersion: string = "0.0.264"; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/client/index.ts b/util/src/config/types/subconfigurations/client/index.ts new file mode 100644 index 00000000..96bbb0ca --- /dev/null +++ b/util/src/config/types/subconfigurations/client/index.ts @@ -0,0 +1 @@ +export * from "./ClientReleaseConfiguration"; diff --git a/util/src/config/types/subconfigurations/defaults/GuildDefaults.ts b/util/src/config/types/subconfigurations/defaults/GuildDefaults.ts new file mode 100644 index 00000000..d6ff7697 --- /dev/null +++ b/util/src/config/types/subconfigurations/defaults/GuildDefaults.ts @@ -0,0 +1,8 @@ +export class GuildDefaults { + maxPresences: number = 250000; + maxVideoChannelUsers: number = 200; + afkTimeout: number = 300; + defaultMessageNotifications: number = 1; + explicitContentFilter: number = 0; + test: number = 123; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/defaults/index.ts b/util/src/config/types/subconfigurations/defaults/index.ts new file mode 100644 index 00000000..f40c5cd2 --- /dev/null +++ b/util/src/config/types/subconfigurations/defaults/index.ts @@ -0,0 +1 @@ +export * from "./GuildDefaults"; diff --git a/util/src/config/types/subconfigurations/guild/AutoJoin.ts b/util/src/config/types/subconfigurations/guild/AutoJoin.ts new file mode 100644 index 00000000..47dfe5ec --- /dev/null +++ b/util/src/config/types/subconfigurations/guild/AutoJoin.ts @@ -0,0 +1,5 @@ +export class AutoJoinConfiguration { + enabled: boolean = true; + guilds: string[] = []; + canLeave: boolean = true; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/guild/Discovery.ts b/util/src/config/types/subconfigurations/guild/Discovery.ts new file mode 100644 index 00000000..59d8a8ae --- /dev/null +++ b/util/src/config/types/subconfigurations/guild/Discovery.ts @@ -0,0 +1,6 @@ +export class DiscoveryConfiguration { + showAllGuilds: boolean = false; + useRecommendation: boolean = false; // TODO: Recommendation, privacy concern? + offset: number = 0; + limit: number = 24; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/guild/index.ts b/util/src/config/types/subconfigurations/guild/index.ts new file mode 100644 index 00000000..e9614856 --- /dev/null +++ b/util/src/config/types/subconfigurations/guild/index.ts @@ -0,0 +1,2 @@ +export * from "./AutoJoin"; +export * from "./Discovery"; diff --git a/util/src/config/types/subconfigurations/index.ts b/util/src/config/types/subconfigurations/index.ts new file mode 100644 index 00000000..bfbadc92 --- /dev/null +++ b/util/src/config/types/subconfigurations/index.ts @@ -0,0 +1,8 @@ +export * from "./client/index"; +export * from "./defaults/index"; +export * from "./guild/index"; +export * from "./kafka/index"; +export * from "./limits/index"; +export * from "./region/index"; +export * from "./register/index"; +export * from "./security/index"; diff --git a/util/src/config/types/subconfigurations/kafka/KafkaBroker.ts b/util/src/config/types/subconfigurations/kafka/KafkaBroker.ts new file mode 100644 index 00000000..4f9a5e51 --- /dev/null +++ b/util/src/config/types/subconfigurations/kafka/KafkaBroker.ts @@ -0,0 +1,4 @@ +export interface KafkaBroker { + ip: string; + port: number; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/kafka/index.ts b/util/src/config/types/subconfigurations/kafka/index.ts new file mode 100644 index 00000000..2c633950 --- /dev/null +++ b/util/src/config/types/subconfigurations/kafka/index.ts @@ -0,0 +1 @@ +export * from "./KafkaBroker"; diff --git a/util/src/config/types/subconfigurations/limits/ChannelLimits.ts b/util/src/config/types/subconfigurations/limits/ChannelLimits.ts new file mode 100644 index 00000000..2f8f9485 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/ChannelLimits.ts @@ -0,0 +1,5 @@ +export class ChannelLimits { + maxPins: number = 500; + maxTopic: number = 1024; + maxWebhooks: number = 100; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/GuildLimits.ts b/util/src/config/types/subconfigurations/limits/GuildLimits.ts new file mode 100644 index 00000000..91ad39ae --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/GuildLimits.ts @@ -0,0 +1,8 @@ +export class GuildLimits { + maxRoles: number = 1000; + maxEmojis: number = 2000; + maxMembers: number = 25000000; + maxChannels: number = 65535; + maxChannelsInCategory: number = 65535; + hideOfflineMember: number = 3; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/MessageLimits.ts b/util/src/config/types/subconfigurations/limits/MessageLimits.ts new file mode 100644 index 00000000..51576b90 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/MessageLimits.ts @@ -0,0 +1,8 @@ +export class MessageLimits { + maxCharacters: number = 1048576; + maxTTSCharacters: number = 160; + maxReactions: number = 2048; + maxAttachmentSize: number = 1024 * 1024 * 1024; + maxBulkDelete: number = 1000; + maxEmbedDownloadSize: number = 1024 * 1024 * 5; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/RateLimits.ts b/util/src/config/types/subconfigurations/limits/RateLimits.ts new file mode 100644 index 00000000..25e7a1e0 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/RateLimits.ts @@ -0,0 +1,18 @@ +import { RouteRateLimit, RateLimitOptions } from "."; + +export class RateLimits { + disabled: boolean = true; + ip: Omit<RateLimitOptions, "bot_count"> = { + count: 500, + window: 5 + }; + global: RateLimitOptions = { + count: 250, + window: 5 + }; + error: RateLimitOptions = { + count: 10, + window: 5 + }; + routes: RouteRateLimit; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/UserLimits.ts b/util/src/config/types/subconfigurations/limits/UserLimits.ts new file mode 100644 index 00000000..0d10e0b3 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/UserLimits.ts @@ -0,0 +1,5 @@ +export class UserLimits { + maxGuilds: number = 1048576; + maxUsername: number = 127; + maxFriends: number = 5000; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/index.ts b/util/src/config/types/subconfigurations/limits/index.ts new file mode 100644 index 00000000..0b7304f6 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/index.ts @@ -0,0 +1,6 @@ +export * from "./ChannelLimits"; +export * from "./GuildLimits"; +export * from "./MessageLimits"; +export * from "./RateLimits"; +export * from "./UserLimits"; +export * from "./ratelimits/index"; diff --git a/util/src/config/types/subconfigurations/limits/ratelimits/Auth.ts b/util/src/config/types/subconfigurations/limits/ratelimits/Auth.ts new file mode 100644 index 00000000..df171044 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/ratelimits/Auth.ts @@ -0,0 +1,12 @@ +import { RateLimitOptions } from "./RateLimitOptions"; + +export class AuthRateLimit { + login: RateLimitOptions = { + count: 5, + window: 60 + }; + register: RateLimitOptions = { + count: 2, + window: 60 * 60 * 12 + }; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts b/util/src/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts new file mode 100644 index 00000000..7089e28e --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts @@ -0,0 +1,6 @@ +export interface RateLimitOptions { + bot?: number; + count: number; + window: number; + onyIp?: boolean; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/ratelimits/Route.ts b/util/src/config/types/subconfigurations/limits/ratelimits/Route.ts new file mode 100644 index 00000000..3012a8a8 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/ratelimits/Route.ts @@ -0,0 +1,19 @@ +import { AuthRateLimit } from "."; +import { RateLimitOptions } from "./RateLimitOptions"; + +export class RouteRateLimit { + guild: RateLimitOptions = { + count: 5, + window: 5 + }; + webhook: RateLimitOptions = { + count: 10, + window: 5 + }; + channel: RateLimitOptions = { + count: 10, + window: 5 + }; + auth: AuthRateLimit; + // TODO: rate limit configuration for all routes +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/limits/ratelimits/index.ts b/util/src/config/types/subconfigurations/limits/ratelimits/index.ts new file mode 100644 index 00000000..432eb601 --- /dev/null +++ b/util/src/config/types/subconfigurations/limits/ratelimits/index.ts @@ -0,0 +1,3 @@ +export * from "./Auth"; +export * from "./RateLimitOptions"; +export * from "./Route"; diff --git a/util/src/config/types/subconfigurations/region/Region.ts b/util/src/config/types/subconfigurations/region/Region.ts new file mode 100644 index 00000000..a8717e1f --- /dev/null +++ b/util/src/config/types/subconfigurations/region/Region.ts @@ -0,0 +1,12 @@ +export interface Region { + id: string; + name: string; + endpoint: string; + location?: { + latitude: number; + longitude: number; + }; + vip: boolean; + custom: boolean; + deprecated: boolean; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/region/index.ts b/util/src/config/types/subconfigurations/region/index.ts new file mode 100644 index 00000000..2beb8de7 --- /dev/null +++ b/util/src/config/types/subconfigurations/region/index.ts @@ -0,0 +1 @@ +export * from "./Region"; diff --git a/util/src/config/types/subconfigurations/register/DateOfBirth.ts b/util/src/config/types/subconfigurations/register/DateOfBirth.ts new file mode 100644 index 00000000..5a3c4e9d --- /dev/null +++ b/util/src/config/types/subconfigurations/register/DateOfBirth.ts @@ -0,0 +1,4 @@ +export class DateOfBirthConfiguration { + required: boolean = true; + minimum: number = 13; // in years +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/register/Email.ts b/util/src/config/types/subconfigurations/register/Email.ts new file mode 100644 index 00000000..115d49e0 --- /dev/null +++ b/util/src/config/types/subconfigurations/register/Email.ts @@ -0,0 +1,7 @@ +export class EmailConfiguration { + required: boolean = false; + allowlist: boolean = false; + blocklist: boolean = true; + domains: string[] = [];// TODO: efficiently save domain blocklist in database + // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/register/Password.ts b/util/src/config/types/subconfigurations/register/Password.ts new file mode 100644 index 00000000..977473ac --- /dev/null +++ b/util/src/config/types/subconfigurations/register/Password.ts @@ -0,0 +1,7 @@ +export class PasswordConfiguration { + required: boolean = false; + minLength: number = 8; + minNumbers: number = 2; + minUpperCase: number =2; + minSymbols: number = 0; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/register/index.ts b/util/src/config/types/subconfigurations/register/index.ts new file mode 100644 index 00000000..d9738120 --- /dev/null +++ b/util/src/config/types/subconfigurations/register/index.ts @@ -0,0 +1,3 @@ +export * from "./DateOfBirth"; +export * from "./Email"; +export * from "./Password"; diff --git a/util/src/config/types/subconfigurations/security/Captcha.ts b/util/src/config/types/subconfigurations/security/Captcha.ts new file mode 100644 index 00000000..ad6aa762 --- /dev/null +++ b/util/src/config/types/subconfigurations/security/Captcha.ts @@ -0,0 +1,6 @@ +export class CaptchaConfiguration { + enabled: boolean = false; + service: "recaptcha" | "hcaptcha" | null = null; // TODO: hcaptcha, custom + sitekey: string | null = null; + secret: string | null = null; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/security/TwoFactor.ts b/util/src/config/types/subconfigurations/security/TwoFactor.ts new file mode 100644 index 00000000..33a47385 --- /dev/null +++ b/util/src/config/types/subconfigurations/security/TwoFactor.ts @@ -0,0 +1,3 @@ +export class TwoFactorConfiguration { + generateBackupCodes: boolean = true; +} \ No newline at end of file diff --git a/util/src/config/types/subconfigurations/security/index.ts b/util/src/config/types/subconfigurations/security/index.ts new file mode 100644 index 00000000..17619589 --- /dev/null +++ b/util/src/config/types/subconfigurations/security/index.ts @@ -0,0 +1,2 @@ +export * from "./Captcha"; +export * from "./TwoFactor"; diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts index 901a5e54..606fe901 100644 --- a/util/src/entities/Config.ts +++ b/util/src/entities/Config.ts @@ -1,9 +1,5 @@ import { Column, Entity } from "typeorm"; import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass"; -import crypto from "crypto"; -import { Snowflake } from "../util/Snowflake"; -import { SessionsReplace } from ".."; -import { hostname } from "os"; @Entity("config") export class ConfigEntity extends BaseClassWithoutId { @@ -12,404 +8,4 @@ export class ConfigEntity extends BaseClassWithoutId { @Column({ type: "simple-json", nullable: true }) value: number | boolean | null | string | undefined; -} - -export interface RateLimitOptions { - bot?: number; - count: number; - window: number; - onyIp?: boolean; -} - -export interface Region { - id: string; - name: string; - endpoint: string; - location?: { - latitude: number; - longitude: number; - }; - vip: boolean; - custom: boolean; - deprecated: boolean; -} - -export interface KafkaBroker { - ip: string; - port: number; -} - -export interface ConfigValue { - gateway: { - endpointClient: string | null; - endpointPrivate: string | null; - endpointPublic: string | null; - }; - cdn: { - endpointClient: string | null; - endpointPublic: string | null; - endpointPrivate: string | null; - }; - api: { - defaultVersion: string; - activeVersions: string[]; - useFosscordEnhancements: boolean; - }; - general: { - instanceName: string; - instanceDescription: string | null; - frontPage: string | null; - tosPage: string | null; - correspondenceEmail: string | null; - correspondenceUserID: string | null; - image: string | null; - instanceId: string; - }; - limits: { - user: { - maxGuilds: number; - maxUsername: number; - maxFriends: number; - }; - guild: { - maxRoles: number; - maxEmojis: number; - maxMembers: number; - maxChannels: number; - maxChannelsInCategory: number; - hideOfflineMember: number; - }; - message: { - maxCharacters: number; - maxTTSCharacters: number; - maxReactions: number; - maxAttachmentSize: number; - maxBulkDelete: number; - maxEmbedDownloadSize: number; - }; - channel: { - maxPins: number; - maxTopic: number; - maxWebhooks: number; - }; - rate: { - disabled: boolean; - ip: Omit<RateLimitOptions, "bot_count">; - global: RateLimitOptions; - error: RateLimitOptions; - routes: { - guild: RateLimitOptions; - webhook: RateLimitOptions; - channel: RateLimitOptions; - auth: { - login: RateLimitOptions; - register: RateLimitOptions; - }; - // TODO: rate limit configuration for all routes - }; - }; - }; - security: { - autoUpdate: boolean | number; - requestSignature: string; - jwtSecret: string; - forwadedFor: string | null; // header to get the real user ip address - captcha: { - enabled: boolean; - service: "recaptcha" | "hcaptcha" | null; // TODO: hcaptcha, custom - sitekey: string | null; - secret: string | null; - }; - ipdataApiKey: string | null; - twoFactor: { - generateBackupCodes: boolean; - }; - }; - login: { - requireCaptcha: boolean; - }; - register: { - defaultRights: string; - email: { - required: boolean; - allowlist: boolean; - blocklist: boolean; - domains: string[]; - }; - dateOfBirth: { - required: boolean; - minimum: number; // in years - }; - disabled: boolean; - requireCaptcha: boolean; - requireInvite: boolean; - guestsRequireInvite: boolean; - allowNewRegistration: boolean; - allowMultipleAccounts: boolean; - blockProxies: boolean; - password: { - required: boolean; - minLength: number; - minNumbers: number; - minUpperCase: number; - minSymbols: number; - }; - incrementingDiscriminators: boolean; // random otherwise - }; - regions: { - default: string; - useDefaultAsOptimal: boolean; - available: Region[]; - }; - guild: { - discovery: { - showAllGuilds: boolean; - useRecommendation: boolean; // TODO: Recommendation, privacy concern? - offset: number; - limit: number; - }; - autoJoin: { - enabled: boolean; - guilds: string[]; - canLeave: boolean; - }; - }; - gif: { - enabled: boolean; - provider: "tenor"; // more coming soon - apiKey?: string; - }; - rabbitmq: { - host: string | null; - }; - kafka: { - brokers: KafkaBroker[] | null; - }; - templates: { - enabled: Boolean; - allowTemplateCreation: Boolean; - allowDiscordTemplates: Boolean; - allowRaws: Boolean; - }, - client: { - useTestClient: Boolean; - releases: { - useLocalRelease: Boolean; //TODO - upstreamVersion: string; - } - }, - metrics: { - timeout: number; - }, - sentry: { - enabled: boolean; - endpoint: string; - traceSampleRate: number; - environment: string; - } -} - -export const DefaultConfigOptions: ConfigValue = { - gateway: { - endpointClient: null, - endpointPrivate: null, - endpointPublic: null, - }, - cdn: { - endpointClient: null, - endpointPrivate: null, - endpointPublic: null, - }, - api: { - defaultVersion: "9", - activeVersions: ["6", "7", "8", "9"], - useFosscordEnhancements: true, - }, - general: { - instanceName: "Fosscord Instance", - instanceDescription: "This is a Fosscord instance made in pre-release days", - frontPage: null, - tosPage: null, - correspondenceEmail: "noreply@localhost.local", - correspondenceUserID: null, - image: null, - instanceId: Snowflake.generate(), - }, - limits: { - user: { - maxGuilds: 1048576, - maxUsername: 127, - maxFriends: 5000, - }, - guild: { - maxRoles: 1000, - maxEmojis: 2000, - maxMembers: 25000000, - maxChannels: 65535, - maxChannelsInCategory: 65535, - hideOfflineMember: 3, - }, - message: { - maxCharacters: 1048576, - maxTTSCharacters: 160, - maxReactions: 2048, - maxAttachmentSize: 1024 * 1024 * 1024, - maxEmbedDownloadSize: 1024 * 1024 * 5, - maxBulkDelete: 1000, - }, - channel: { - maxPins: 500, - maxTopic: 1024, - maxWebhooks: 100, - }, - rate: { - disabled: true, - ip: { - count: 500, - window: 5, - }, - global: { - count: 250, - window: 5, - }, - error: { - count: 10, - window: 5, - }, - routes: { - guild: { - count: 5, - window: 5, - }, - webhook: { - count: 10, - window: 5, - }, - channel: { - count: 10, - window: 5, - }, - auth: { - login: { - count: 5, - window: 60, - }, - register: { - count: 2, - window: 60 * 60 * 12, - }, - }, - }, - }, - }, - security: { - autoUpdate: true, - requestSignature: crypto.randomBytes(32).toString("base64"), - jwtSecret: crypto.randomBytes(256).toString("base64"), - forwadedFor: null, - // forwadedFor: "X-Forwarded-For" // nginx/reverse proxy - // forwadedFor: "CF-Connecting-IP" // cloudflare: - captcha: { - enabled: false, - service: null, - sitekey: null, - secret: null, - }, - ipdataApiKey: "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9", - twoFactor: { - generateBackupCodes: true, - }, - }, - login: { - requireCaptcha: false, - }, - register: { - email: { - required: false, - allowlist: false, - blocklist: true, - domains: [], // TODO: efficiently save domain blocklist in database - // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), - }, - dateOfBirth: { - required: true, - minimum: 13, - }, - disabled: false, - requireInvite: false, - guestsRequireInvite: true, - requireCaptcha: true, - allowNewRegistration: true, - allowMultipleAccounts: true, - blockProxies: true, - password: { - required: false, - minLength: 8, - minNumbers: 2, - minUpperCase: 2, - minSymbols: 0, - }, - incrementingDiscriminators: false, - defaultRights: "0" - }, - regions: { - default: "fosscord", - useDefaultAsOptimal: true, - available: [ - { - id: "fosscord", - name: "Fosscord", - endpoint: "127.0.0.1:3004", - vip: false, - custom: false, - deprecated: false, - }, - ], - }, - guild: { - discovery: { - showAllGuilds: false, - useRecommendation: false, - offset: 0, - limit: 24, - }, - autoJoin: { - enabled: true, - canLeave: true, - guilds: [], - }, - }, - gif: { - enabled: true, - provider: "tenor", - apiKey: "LIVDSRZULELA", - }, - rabbitmq: { - host: null, - }, - kafka: { - brokers: null, - }, - templates: { - enabled: true, - allowTemplateCreation: true, - allowDiscordTemplates: true, - allowRaws: false - }, - client: { - useTestClient: true, - releases: { - useLocalRelease: true, - upstreamVersion: "0.0.264" - } - }, - metrics: { - timeout: 30000 - }, - sentry: { - enabled: false, - endpoint: "https://05e8e3d005f34b7d97e920ae5870a5e5@sentry.thearcanebrony.net/6", - traceSampleRate: 1.0, - environment: hostname() - } -}; +} \ No newline at end of file diff --git a/util/src/util/Config.ts b/util/src/util/Config.ts index 925cb243..0b55ca4b 100644 --- a/util/src/util/Config.ts +++ b/util/src/util/Config.ts @@ -1,6 +1,7 @@ -import { ConfigValue, ConfigEntity, DefaultConfigOptions } from "../entities/Config"; -import path from "path"; +import { ConfigEntity } from "../entities/Config"; import fs from "fs"; +import { ConfigValue } from "../config"; +import { OrmUtils } from "."; // TODO: yaml instead of json const overridePath = process.env.CONFIG_PATH ?? ""; @@ -14,9 +15,11 @@ let pairs: ConfigEntity[]; export const Config = { init: async function init() { if (config) return config; + console.log('[Config] Loading configuration...') pairs = await ConfigEntity.find(); config = pairsToConfig(pairs); - config = (config || {}).merge(DefaultConfigOptions); + //config = (config || {}).merge(new ConfigValue()); + config = OrmUtils.mergeDeep(new ConfigValue(), config) if(process.env.CONFIG_PATH) try { @@ -30,6 +33,11 @@ export const Config = { return this.set(config); }, get: function get() { + if(!config) { + if(/--debug|--inspect/.test(process.execArgv.join(' '))) + console.log("Oops.. trying to get config without config existing... Returning defaults... (Is the database still initialising?)"); + return new ConfigValue(); + } return config; }, set: function set(val: Partial<ConfigValue>) { |