summary refs log tree commit diff
path: root/src/util/entities/Config.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/entities/Config.ts')
-rw-r--r--src/util/entities/Config.ts416
1 files changed, 416 insertions, 0 deletions
diff --git a/src/util/entities/Config.ts b/src/util/entities/Config.ts
new file mode 100644
index 00000000..9aabc1a8
--- /dev/null
+++ b/src/util/entities/Config.ts
@@ -0,0 +1,416 @@
+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";
+import { Rights } from "../util/Rights";
+
+@Entity("config")
+export class ConfigEntity extends BaseClassWithoutId {
+	@PrimaryIdColumn()
+	key: string;
+
+	@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;
+	};
+	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;
+	};
+}
+
+export const DefaultConfigOptions: ConfigValue = {
+	gateway: {
+		endpointClient: null,
+		endpointPrivate: null,
+		endpointPublic: null,
+	},
+	cdn: {
+		endpointClient: null,
+		endpointPrivate: null,
+		endpointPublic: null,
+		resizeHeightMax: 1000,
+		resizeWidthMax: 1000,
+	},
+	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: "30644591655936",	// See util/scripts/rights.js
+	},
+	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()
+	}
+};
\ No newline at end of file