mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-22 10:22:39 +01:00
Make ConfigValue a directory, move defaults to those classes instead of a separate object
This commit is contained in:
parent
127aa3a68d
commit
fefcb31135
@ -6,13 +6,12 @@ import {
|
||||
emitEvent,
|
||||
Guild,
|
||||
Member,
|
||||
Region,
|
||||
VoiceServerUpdateEvent,
|
||||
VoiceState,
|
||||
VoiceStateUpdateEvent,
|
||||
VoiceStateUpdateSchema,
|
||||
} 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.
|
||||
|
22
src/util/config/Config.ts
Normal file
22
src/util/config/Config.ts
Normal file
@ -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();
|
||||
}
|
2
src/util/config/index.ts
Normal file
2
src/util/config/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./Config";
|
||||
export * from "./types/index";
|
5
src/util/config/types/ApiConfiguration.ts
Normal file
5
src/util/config/types/ApiConfiguration.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class ApiConfiguration {
|
||||
defaultVersion: string = "9";
|
||||
activeVersions: string[] = ["6", "7", "8", "9"];
|
||||
useFosscordEnhancements: boolean = true;
|
||||
}
|
8
src/util/config/types/ClientConfiguration.ts
Normal file
8
src/util/config/types/ClientConfiguration.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { ClientReleaseConfiguration } from ".";
|
||||
|
||||
export class ClientConfiguration {
|
||||
//classes
|
||||
releases: ClientReleaseConfiguration = new ClientReleaseConfiguration();
|
||||
//base types
|
||||
useTestClient: boolean = true;
|
||||
}
|
5
src/util/config/types/DefaultsConfiguration.ts
Normal file
5
src/util/config/types/DefaultsConfiguration.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { GuildDefaults } from ".";
|
||||
|
||||
export class DefaultsConfiguration {
|
||||
guild: GuildDefaults = new GuildDefaults();
|
||||
}
|
5
src/util/config/types/EndpointConfiguration.ts
Normal file
5
src/util/config/types/EndpointConfiguration.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class EndpointConfiguration {
|
||||
endpointClient: string | null = null;
|
||||
endpointPrivate: string | null = null;
|
||||
endpointPublic: string | null = null;
|
||||
}
|
12
src/util/config/types/GeneralConfiguration.ts
Normal file
12
src/util/config/types/GeneralConfiguration.ts
Normal file
@ -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();
|
||||
}
|
5
src/util/config/types/GifConfiguration.ts
Normal file
5
src/util/config/types/GifConfiguration.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class GifConfiguration {
|
||||
enabled: boolean = true;
|
||||
provider: "tenor" = "tenor"; // more coming soon
|
||||
apiKey?: string = "LIVDSRZULELA";
|
||||
}
|
6
src/util/config/types/GuildConfiguration.ts
Normal file
6
src/util/config/types/GuildConfiguration.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { DiscoveryConfiguration, AutoJoinConfiguration } from ".";
|
||||
|
||||
export class GuildConfiguration {
|
||||
discovery: DiscoveryConfiguration = new DiscoveryConfiguration();
|
||||
autoJoin: AutoJoinConfiguration = new AutoJoinConfiguration();
|
||||
}
|
5
src/util/config/types/KafkaConfiguration.ts
Normal file
5
src/util/config/types/KafkaConfiguration.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { KafkaBroker } from ".";
|
||||
|
||||
export class KafkaConfiguration {
|
||||
brokers: KafkaBroker[] | null = null;
|
||||
}
|
9
src/util/config/types/LimitConfigurations.ts
Normal file
9
src/util/config/types/LimitConfigurations.ts
Normal file
@ -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();
|
||||
}
|
3
src/util/config/types/LoginConfiguration.ts
Normal file
3
src/util/config/types/LoginConfiguration.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export class LoginConfiguration {
|
||||
requireCaptcha: boolean = false;
|
||||
}
|
3
src/util/config/types/MetricsConfiguration.ts
Normal file
3
src/util/config/types/MetricsConfiguration.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export class MetricsConfiguration {
|
||||
timeout: number = 30000;
|
||||
}
|
3
src/util/config/types/RabbitMQConfiguration.ts
Normal file
3
src/util/config/types/RabbitMQConfiguration.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export class RabbitMQConfiguration {
|
||||
host: string | null = null;
|
||||
}
|
16
src/util/config/types/RegionConfiguration.ts
Normal file
16
src/util/config/types/RegionConfiguration.ts
Normal file
@ -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,
|
||||
},
|
||||
];
|
||||
}
|
18
src/util/config/types/RegisterConfiguration.ts
Normal file
18
src/util/config/types/RegisterConfiguration.ts
Normal file
@ -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";
|
||||
}
|
17
src/util/config/types/SecurityConfiguration.ts
Normal file
17
src/util/config/types/SecurityConfiguration.ts
Normal file
@ -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";
|
||||
}
|
8
src/util/config/types/SentryConfiguration.ts
Normal file
8
src/util/config/types/SentryConfiguration.ts
Normal file
@ -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();
|
||||
}
|
6
src/util/config/types/TemplateConfiguration.ts
Normal file
6
src/util/config/types/TemplateConfiguration.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export class TemplateConfiguration {
|
||||
enabled: boolean = true;
|
||||
allowTemplateCreation: boolean = true;
|
||||
allowDiscordTemplates: boolean = true;
|
||||
allowRaws: boolean = true;
|
||||
}
|
18
src/util/config/types/index.ts
Normal file
18
src/util/config/types/index.ts
Normal file
@ -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";
|
@ -0,0 +1,4 @@
|
||||
export class ClientReleaseConfiguration {
|
||||
useLocalRelease: boolean = true; //TODO
|
||||
upstreamVersion: string = "0.0.264";
|
||||
}
|
1
src/util/config/types/subconfigurations/client/index.ts
Normal file
1
src/util/config/types/subconfigurations/client/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./ClientReleaseConfiguration";
|
@ -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;
|
||||
}
|
@ -0,0 +1 @@
|
||||
export * from "./GuildDefaults";
|
@ -0,0 +1,5 @@
|
||||
export class AutoJoinConfiguration {
|
||||
enabled: boolean = true;
|
||||
guilds: string[] = [];
|
||||
canLeave: boolean = true;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
export class DiscoveryConfiguration {
|
||||
showAllGuilds: boolean = false;
|
||||
useRecommendation: boolean = false; // TODO: Recommendation, privacy concern?
|
||||
offset: number = 0;
|
||||
limit: number = 24;
|
||||
}
|
2
src/util/config/types/subconfigurations/guild/index.ts
Normal file
2
src/util/config/types/subconfigurations/guild/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./AutoJoin";
|
||||
export * from "./Discovery";
|
8
src/util/config/types/subconfigurations/index.ts
Normal file
8
src/util/config/types/subconfigurations/index.ts
Normal file
@ -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";
|
@ -0,0 +1,4 @@
|
||||
export interface KafkaBroker {
|
||||
ip: string;
|
||||
port: number;
|
||||
}
|
1
src/util/config/types/subconfigurations/kafka/index.ts
Normal file
1
src/util/config/types/subconfigurations/kafka/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./KafkaBroker";
|
@ -0,0 +1,5 @@
|
||||
export class ChannelLimits {
|
||||
maxPins: number = 500;
|
||||
maxTopic: number = 1024;
|
||||
maxWebhooks: number = 100;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
18
src/util/config/types/subconfigurations/limits/RateLimits.ts
Normal file
18
src/util/config/types/subconfigurations/limits/RateLimits.ts
Normal file
@ -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;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
export class UserLimits {
|
||||
maxGuilds: number = 1048576;
|
||||
maxUsername: number = 127;
|
||||
maxFriends: number = 5000;
|
||||
}
|
6
src/util/config/types/subconfigurations/limits/index.ts
Normal file
6
src/util/config/types/subconfigurations/limits/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export * from "./ChannelLimits";
|
||||
export * from "./GuildLimits";
|
||||
export * from "./MessageLimits";
|
||||
export * from "./RateLimits";
|
||||
export * from "./UserLimits";
|
||||
export * from "./ratelimits/index";
|
@ -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
|
||||
};
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
export interface RateLimitOptions {
|
||||
bot?: number;
|
||||
count: number;
|
||||
window: number;
|
||||
onyIp?: boolean;
|
||||
}
|
@ -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
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export * from "./Auth";
|
||||
export * from "./RateLimitOptions";
|
||||
export * from "./Route";
|
12
src/util/config/types/subconfigurations/region/Region.ts
Normal file
12
src/util/config/types/subconfigurations/region/Region.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export interface Region {
|
||||
id: string;
|
||||
name: string;
|
||||
endpoint: string;
|
||||
location?: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
vip: boolean;
|
||||
custom: boolean;
|
||||
deprecated: boolean;
|
||||
}
|
1
src/util/config/types/subconfigurations/region/index.ts
Normal file
1
src/util/config/types/subconfigurations/region/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./Region";
|
@ -0,0 +1,4 @@
|
||||
export class DateOfBirthConfiguration {
|
||||
required: boolean = true;
|
||||
minimum: number = 13; // in years
|
||||
}
|
@ -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"),
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
export class PasswordConfiguration {
|
||||
required: boolean = false;
|
||||
minLength: number = 8;
|
||||
minNumbers: number = 2;
|
||||
minUpperCase: number =2;
|
||||
minSymbols: number = 0;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export * from "./DateOfBirth";
|
||||
export * from "./Email";
|
||||
export * from "./Password";
|
@ -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;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export class TwoFactorConfiguration {
|
||||
generateBackupCodes: boolean = true;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
export * from "./Captcha";
|
||||
export * from "./TwoFactor";
|
@ -1,8 +1,5 @@
|
||||
import { Column, Entity } from "typeorm";
|
||||
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
|
||||
import crypto from "crypto";
|
||||
import { Snowflake } from "../util/Snowflake";
|
||||
import { hostname } from "os";
|
||||
|
||||
@Entity("config")
|
||||
export class ConfigEntity extends BaseClassWithoutId {
|
||||
@ -12,414 +9,3 @@ 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;
|
||||
resizeHeightMax: number | null;
|
||||
resizeWidthMax: number | null;
|
||||
imagorServerUrl: 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;
|
||||
defaultRights: string;
|
||||
};
|
||||
login: {
|
||||
requireCaptcha: boolean;
|
||||
};
|
||||
register: {
|
||||
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;
|
||||
};
|
||||
defaultFeatures: string[];
|
||||
};
|
||||
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;
|
||||
};
|
||||
external: {
|
||||
twitter: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
export const DefaultConfigOptions: ConfigValue = {
|
||||
gateway: {
|
||||
endpointClient: null,
|
||||
endpointPrivate: null,
|
||||
endpointPublic: null,
|
||||
},
|
||||
cdn: {
|
||||
endpointClient: null,
|
||||
endpointPrivate: null,
|
||||
endpointPublic: null,
|
||||
resizeHeightMax: 1000,
|
||||
resizeWidthMax: 1000,
|
||||
imagorServerUrl: 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",
|
||||
defaultRights: "30644591655940", // See `npm run generate:rights`
|
||||
},
|
||||
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,
|
||||
},
|
||||
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: [],
|
||||
},
|
||||
defaultFeatures: [],
|
||||
},
|
||||
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(),
|
||||
},
|
||||
external: {
|
||||
twitter: null,
|
||||
}
|
||||
};
|
||||
|
@ -1,11 +1,6 @@
|
||||
import "missing-native-js-functions";
|
||||
import {
|
||||
ConfigValue,
|
||||
ConfigEntity,
|
||||
DefaultConfigOptions,
|
||||
} from "../entities/Config";
|
||||
import path from "path";
|
||||
import { ConfigEntity } from "../entities/Config";
|
||||
import fs from "fs";
|
||||
import { ConfigValue } from "../config";
|
||||
|
||||
// TODO: yaml instead of json
|
||||
const overridePath = process.env.CONFIG_PATH ?? "";
|
||||
@ -19,9 +14,10 @@ var 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());
|
||||
|
||||
if (process.env.CONFIG_PATH) {
|
||||
console.log(`[Config] Using config path from environment rather than database.`);
|
||||
|
Loading…
Reference in New Issue
Block a user