mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-26 04:03:03 +01:00
Make ConfigValue a directory, move defaults to those classes instead of a separate object
This commit is contained in:
parent
94b07e5efb
commit
bc669ea9e1
@ -6,13 +6,12 @@ import {
|
|||||||
emitEvent,
|
emitEvent,
|
||||||
Guild,
|
Guild,
|
||||||
Member,
|
Member,
|
||||||
Region,
|
|
||||||
VoiceServerUpdateEvent,
|
VoiceServerUpdateEvent,
|
||||||
VoiceState,
|
VoiceState,
|
||||||
VoiceStateUpdateEvent,
|
VoiceStateUpdateEvent,
|
||||||
VoiceStateUpdateSchema,
|
VoiceStateUpdateSchema,
|
||||||
} from "@fosscord/util";
|
} from "@fosscord/util";
|
||||||
|
import { Region } from "@fosscord/util/src/config";
|
||||||
// TODO: check if a voice server is setup
|
// TODO: check if a voice server is setup
|
||||||
|
|
||||||
// Notice: Bot users respect the voice channel's user limit, if set.
|
// 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 { Column, Entity } from "typeorm";
|
||||||
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
|
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
|
||||||
import crypto from "crypto";
|
|
||||||
import { Snowflake } from "../util/Snowflake";
|
|
||||||
import { hostname } from "os";
|
|
||||||
|
|
||||||
@Entity("config")
|
@Entity("config")
|
||||||
export class ConfigEntity extends BaseClassWithoutId {
|
export class ConfigEntity extends BaseClassWithoutId {
|
||||||
@ -12,414 +9,3 @@ export class ConfigEntity extends BaseClassWithoutId {
|
|||||||
@Column({ type: "simple-json", nullable: true })
|
@Column({ type: "simple-json", nullable: true })
|
||||||
value: number | boolean | null | string | undefined;
|
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 { ConfigEntity } from "../entities/Config";
|
||||||
import {
|
|
||||||
ConfigValue,
|
|
||||||
ConfigEntity,
|
|
||||||
DefaultConfigOptions,
|
|
||||||
} from "../entities/Config";
|
|
||||||
import path from "path";
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import { ConfigValue } from "../config";
|
||||||
|
|
||||||
// TODO: yaml instead of json
|
// TODO: yaml instead of json
|
||||||
const overridePath = process.env.CONFIG_PATH ?? "";
|
const overridePath = process.env.CONFIG_PATH ?? "";
|
||||||
@ -19,9 +14,10 @@ var pairs: ConfigEntity[];
|
|||||||
export const Config = {
|
export const Config = {
|
||||||
init: async function init() {
|
init: async function init() {
|
||||||
if (config) return config;
|
if (config) return config;
|
||||||
|
console.log('[Config] Loading configuration...')
|
||||||
pairs = await ConfigEntity.find();
|
pairs = await ConfigEntity.find();
|
||||||
config = pairsToConfig(pairs);
|
config = pairsToConfig(pairs);
|
||||||
config = (config || {}).merge(DefaultConfigOptions);
|
config = (config || {}).merge(new ConfigValue());
|
||||||
|
|
||||||
if (process.env.CONFIG_PATH) {
|
if (process.env.CONFIG_PATH) {
|
||||||
console.log(`[Config] Using config path from environment rather than database.`);
|
console.log(`[Config] Using config path from environment rather than database.`);
|
||||||
|
Loading…
Reference in New Issue
Block a user