Merge branch 'master' of https://github.com/discord-open-source/discord-api into master
This commit is contained in:
		
						commit
						7058118de6
					
				
							
								
								
									
										10
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| { | ||||
| 	"name": "discord-server-opensource", | ||||
| 	"name": "discord-api", | ||||
| 	"version": "1.0.0", | ||||
| 	"lockfileVersion": 1, | ||||
| 	"requires": true, | ||||
| @ -466,6 +466,14 @@ | ||||
| 			"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"discord-server-util": { | ||||
| 			"version": "git+https://github.com/discord-open-source/discord-server-util.git#7e3d6d1d9d53cedd329b59529575d67198826b50", | ||||
| 			"from": "git+https://github.com/discord-open-source/discord-server-util.git", | ||||
| 			"requires": { | ||||
| 				"jsonwebtoken": "^8.5.1", | ||||
| 				"lambert-db": "^1.1.4" | ||||
| 			} | ||||
| 		}, | ||||
| 		"ecdsa-sig-formatter": { | ||||
| 			"version": "1.0.11", | ||||
| 			"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| { | ||||
| 	"name": "discord-server-opensource", | ||||
| 	"name": "discord-api", | ||||
| 	"version": "1.0.0", | ||||
| 	"description": "", | ||||
| 	"main": "index.js", | ||||
| @ -10,18 +10,19 @@ | ||||
| 	}, | ||||
| 	"repository": { | ||||
| 		"type": "git", | ||||
| 		"url": "git+https://github.com/Trenite/discord-server-opensource.git" | ||||
| 		"url": "git+https://github.com/discord-open-source/discord-api.git" | ||||
| 	}, | ||||
| 	"keywords": [], | ||||
| 	"author": "", | ||||
| 	"license": "ISC", | ||||
| 	"bugs": { | ||||
| 		"url": "https://github.com/Trenite/discord-server-opensource/issues" | ||||
| 		"url": "https://github.com/discord-open-source/discord-api/issues" | ||||
| 	}, | ||||
| 	"homepage": "https://github.com/Trenite/discord-server-opensource#readme", | ||||
| 	"homepage": "https://github.com/discord-open-source/discord-api#readme", | ||||
| 	"dependencies": { | ||||
| 		"bcrypt": "^5.0.0", | ||||
| 		"body-parser": "^1.19.0", | ||||
| 		"discord-server-util": "git+https://github.com/discord-open-source/discord-server-util.git", | ||||
| 		"express": "^4.17.1", | ||||
| 		"express-validator": "^6.9.2", | ||||
| 		"i18next": "^19.8.5", | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| import { Request, Response, Router } from "express"; | ||||
| import db from "../../../../util/Database"; | ||||
| import { check, FieldErrors, Length } from "../../../../util/instanceOf"; | ||||
| import bcrypt from "bcrypt"; | ||||
| import jwt from "jsonwebtoken"; | ||||
| import Config from "../../../../util/Config"; | ||||
| import { User } from "../../../../models/User"; | ||||
| import { adjustEmail } from "./register"; | ||||
| import { db } from "discord-server-util"; | ||||
| 
 | ||||
| const router: Router = Router(); | ||||
| export default router; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { NextFunction, Request, Response, Router } from "express"; | ||||
| import Config from "../../../../util/Config"; | ||||
| import db from "../../../../util/Database"; | ||||
| import { db } from "discord-server-util"; | ||||
| import bcrypt from "bcrypt"; | ||||
| import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "../../../../util/instanceOf"; | ||||
| import { Snowflake } from "../../../../util/Snowflake"; | ||||
|  | ||||
| @ -1,25 +1,166 @@ | ||||
| import "missing-native-js-functions"; | ||||
| import db from "./Database"; | ||||
| import { DefaultOptions } from "./Constants"; | ||||
| import { ProviderCache } from "lambert-db"; | ||||
| var Config: ProviderCache; | ||||
| 
 | ||||
| async function init() { | ||||
| 	Config = db.data.config({}).cache(); | ||||
| 	await Config.init(); | ||||
| 	await Config.set(DefaultOptions.merge(Config.cache || {})); | ||||
| } | ||||
| 
 | ||||
| function get() { | ||||
| 	return <DefaultOptions>Config.get(); | ||||
| } | ||||
| 
 | ||||
| function set(val: any) { | ||||
| 	return Config.set(val); | ||||
| } | ||||
| import { Config } from "discord-server-util"; | ||||
| import crypto from "crypto"; | ||||
| import fs from "fs"; | ||||
| 
 | ||||
| export default { | ||||
| 	init, | ||||
| 	get: get, | ||||
| 	set: set, | ||||
| 	init() { | ||||
| 		return Config.init({ api: DefaultOptions }); | ||||
| 	}, | ||||
| 	get() { | ||||
| 		return Config.getAll().api; | ||||
| 	}, | ||||
| 	set(val: any) { | ||||
| 		return Config.setAll({ api: val }); | ||||
| 	}, | ||||
| 	getAll: Config.getAll, | ||||
| 	setAll: Config.setAll, | ||||
| }; | ||||
| 
 | ||||
| export interface RateLimit { | ||||
| 	count: number; | ||||
| 	timespan: number; | ||||
| } | ||||
| 
 | ||||
| export interface DefaultOptions { | ||||
| 	limits: { | ||||
| 		user: { | ||||
| 			maxGuilds: number; | ||||
| 			maxUsername: number; | ||||
| 			maxFriends: number; | ||||
| 		}; | ||||
| 		guild: { | ||||
| 			maxRoles: number; | ||||
| 			maxMembers: number; | ||||
| 			maxChannels: number; | ||||
| 			maxChannelsInCategory: number; | ||||
| 			hideOfflineMember: number; | ||||
| 		}; | ||||
| 		message: { | ||||
| 			characters: number; | ||||
| 			ttsCharacters: number; | ||||
| 			maxReactions: number; | ||||
| 			maxAttachmentSize: number; | ||||
| 		}; | ||||
| 		channel: { | ||||
| 			maxPins: number; | ||||
| 			maxTopic: number; | ||||
| 		}; | ||||
| 		rate: { | ||||
| 			ip: { | ||||
| 				enabled: boolean; | ||||
| 				count: number; | ||||
| 				timespan: number; | ||||
| 			}; | ||||
| 			routes: { | ||||
| 				auth?: { | ||||
| 					login?: RateLimit; | ||||
| 					register?: RateLimit; | ||||
| 				}; | ||||
| 				channel?: {}; | ||||
| 				// TODO: rate limit configuration for all routes
 | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| 	security: { | ||||
| 		jwtSecret: string; | ||||
| 		forwadedFor: string | null; | ||||
| 		captcha: { | ||||
| 			enabled: boolean; | ||||
| 			service: "recaptcha" | null; // TODO: hcaptcha, custom
 | ||||
| 			sitekey: string | null; | ||||
| 		}; | ||||
| 	}; | ||||
| 	register: { | ||||
| 		email: { | ||||
| 			required: boolean; | ||||
| 			allowlist: boolean; | ||||
| 			blocklist: boolean; | ||||
| 			domains: string[]; | ||||
| 		}; | ||||
| 		dateOfBirth: { | ||||
| 			required: boolean; | ||||
| 			minimum: number; // in years
 | ||||
| 		}; | ||||
| 		requireCaptcha: boolean; | ||||
| 		requireInvite: boolean; | ||||
| 		allowNewRegistration: boolean; | ||||
| 		allowMultipleAccounts: boolean; | ||||
| 		password: { | ||||
| 			minLength: number; | ||||
| 			minNumbers: number; | ||||
| 			minUpperCase: number; | ||||
| 			minSymbols: number; | ||||
| 			blockInsecureCommonPasswords: boolean; // TODO: efficiently save password blocklist in database
 | ||||
| 		}; | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| export const DefaultOptions: DefaultOptions = { | ||||
| 	limits: { | ||||
| 		user: { | ||||
| 			maxGuilds: 100, | ||||
| 			maxUsername: 32, | ||||
| 			maxFriends: 1000, | ||||
| 		}, | ||||
| 		guild: { | ||||
| 			maxRoles: 250, | ||||
| 			maxMembers: 250000, | ||||
| 			maxChannels: 500, | ||||
| 			maxChannelsInCategory: 50, | ||||
| 			hideOfflineMember: 1000, | ||||
| 		}, | ||||
| 		message: { | ||||
| 			characters: 2000, | ||||
| 			ttsCharacters: 200, | ||||
| 			maxReactions: 20, | ||||
| 			maxAttachmentSize: 8388608, | ||||
| 		}, | ||||
| 		channel: { | ||||
| 			maxPins: 50, | ||||
| 			maxTopic: 1024, | ||||
| 		}, | ||||
| 		rate: { | ||||
| 			ip: { | ||||
| 				enabled: true, | ||||
| 				count: 1000, | ||||
| 				timespan: 1000 * 60 * 10, | ||||
| 			}, | ||||
| 			routes: {}, | ||||
| 		}, | ||||
| 	}, | ||||
| 	security: { | ||||
| 		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, | ||||
| 		}, | ||||
| 	}, | ||||
| 	register: { | ||||
| 		email: { | ||||
| 			required: true, | ||||
| 			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, | ||||
| 		}, | ||||
| 		requireInvite: false, | ||||
| 		requireCaptcha: true, | ||||
| 		allowNewRegistration: true, | ||||
| 		allowMultipleAccounts: true, | ||||
| 		password: { | ||||
| 			minLength: 8, | ||||
| 			minNumbers: 2, | ||||
| 			minUpperCase: 2, | ||||
| 			minSymbols: 0, | ||||
| 			blockInsecureCommonPasswords: false, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| @ -1,158 +1,3 @@ | ||||
| import crypto from "crypto"; | ||||
| import { VerifyOptions } from "jsonwebtoken"; | ||||
| import fs from "fs"; | ||||
| 
 | ||||
| export interface RateLimit { | ||||
| 	count: number; | ||||
| 	timespan: number; | ||||
| } | ||||
| 
 | ||||
| export interface DefaultOptions { | ||||
| 	limits: { | ||||
| 		user: { | ||||
| 			maxGuilds: number; | ||||
| 			maxUsername: number; | ||||
| 			maxFriends: number; | ||||
| 		}; | ||||
| 		guild: { | ||||
| 			maxRoles: number; | ||||
| 			maxMembers: number; | ||||
| 			maxChannels: number; | ||||
| 			maxChannelsInCategory: number; | ||||
| 			hideOfflineMember: number; | ||||
| 		}; | ||||
| 		message: { | ||||
| 			characters: number; | ||||
| 			ttsCharacters: number; | ||||
| 			maxReactions: number; | ||||
| 			maxAttachmentSize: number; | ||||
| 		}; | ||||
| 		channel: { | ||||
| 			maxPins: number; | ||||
| 			maxTopic: number; | ||||
| 		}; | ||||
| 		rate: { | ||||
| 			ip: { | ||||
| 				enabled: boolean; | ||||
| 				count: number; | ||||
| 				timespan: number; | ||||
| 			}; | ||||
| 			routes: { | ||||
| 				auth?: { | ||||
| 					login?: RateLimit; | ||||
| 					register?: RateLimit; | ||||
| 				}; | ||||
| 				channel?: {}; | ||||
| 				// TODO: rate limit configuration for all routes
 | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| 	security: { | ||||
| 		jwtSecret: string; | ||||
| 		forwadedFor: string | null; | ||||
| 		captcha: { | ||||
| 			enabled: boolean; | ||||
| 			service: "recaptcha" | null; // TODO: hcaptcha, custom
 | ||||
| 			sitekey: string | null; | ||||
| 		}; | ||||
| 	}; | ||||
| 	register: { | ||||
| 		email: { | ||||
| 			required: boolean; | ||||
| 			allowlist: boolean; | ||||
| 			blocklist: boolean; | ||||
| 			domains: string[]; | ||||
| 		}; | ||||
| 		dateOfBirth: { | ||||
| 			required: boolean; | ||||
| 			minimum: number; // in years
 | ||||
| 		}; | ||||
| 		requireCaptcha: boolean; | ||||
| 		requireInvite: boolean; | ||||
| 		allowNewRegistration: boolean; | ||||
| 		allowMultipleAccounts: boolean; | ||||
| 		password: { | ||||
| 			minLength: number; | ||||
| 			minNumbers: number; | ||||
| 			minUpperCase: number; | ||||
| 			minSymbols: number; | ||||
| 			blockInsecureCommonPasswords: boolean; // TODO: efficiently save password blocklist in database
 | ||||
| 		}; | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| export const DefaultOptions: DefaultOptions = { | ||||
| 	limits: { | ||||
| 		user: { | ||||
| 			maxGuilds: 100, | ||||
| 			maxUsername: 32, | ||||
| 			maxFriends: 1000, | ||||
| 		}, | ||||
| 		guild: { | ||||
| 			maxRoles: 250, | ||||
| 			maxMembers: 250000, | ||||
| 			maxChannels: 500, | ||||
| 			maxChannelsInCategory: 50, | ||||
| 			hideOfflineMember: 1000, | ||||
| 		}, | ||||
| 		message: { | ||||
| 			characters: 2000, | ||||
| 			ttsCharacters: 200, | ||||
| 			maxReactions: 20, | ||||
| 			maxAttachmentSize: 8388608, | ||||
| 		}, | ||||
| 		channel: { | ||||
| 			maxPins: 50, | ||||
| 			maxTopic: 1024, | ||||
| 		}, | ||||
| 		rate: { | ||||
| 			ip: { | ||||
| 				enabled: true, | ||||
| 				count: 1000, | ||||
| 				timespan: 1000 * 60 * 10, | ||||
| 			}, | ||||
| 			routes: {}, | ||||
| 		}, | ||||
| 	}, | ||||
| 	security: { | ||||
| 		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, | ||||
| 		}, | ||||
| 	}, | ||||
| 	register: { | ||||
| 		email: { | ||||
| 			required: true, | ||||
| 			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, | ||||
| 		}, | ||||
| 		requireInvite: false, | ||||
| 		requireCaptcha: true, | ||||
| 		allowNewRegistration: true, | ||||
| 		allowMultipleAccounts: true, | ||||
| 		password: { | ||||
| 			minLength: 8, | ||||
| 			minNumbers: 2, | ||||
| 			minUpperCase: 2, | ||||
| 			minSymbols: 0, | ||||
| 			blockInsecureCommonPasswords: false, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] }; | ||||
| 
 | ||||
| export const WSCodes = { | ||||
| 	1000: "WS_CLOSE_REQUESTED", | ||||
| 	4004: "TOKEN_INVALID", | ||||
|  | ||||
| @ -1,5 +0,0 @@ | ||||
| import { MongoDatabase } from "lambert-db"; | ||||
| 
 | ||||
| const db = new MongoDatabase("mongodb://127.0.0.1:27017/lambert?readPreference=secondaryPreferred"); | ||||
| 
 | ||||
| export default db; | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 xnacly
						xnacly