This commit is contained in:
38
backend/src/constants/auto-roles.ts
Normal file
38
backend/src/constants/auto-roles.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
export default [
|
||||
"oneHourWarrior",
|
||||
"doubleDown",
|
||||
"tripleTrouble",
|
||||
"quad",
|
||||
"trueSimp",
|
||||
"bigramSalad",
|
||||
"simp",
|
||||
"antidiseWhat",
|
||||
"whatsThisWebsiteCalledAgain",
|
||||
"developd",
|
||||
"slowAndSteady",
|
||||
"speedSpacer",
|
||||
"iveGotThePower",
|
||||
"accuracyExpert",
|
||||
"accuracyMaster",
|
||||
"accuracyGod",
|
||||
"jolly",
|
||||
"gottaCatchEmAll",
|
||||
"rapGod",
|
||||
"navySeal",
|
||||
"rollercoaster",
|
||||
"oneHourMirror",
|
||||
"chooChoo",
|
||||
"earfquake",
|
||||
"simonSez",
|
||||
"accountant",
|
||||
"hidden",
|
||||
"iCanSeeTheFuture",
|
||||
"whatAreWordsAtThisPoint",
|
||||
"specials",
|
||||
"aeiou",
|
||||
"asciiWarrior",
|
||||
"iKiNdAlIkEhOwInEfFiCiEnTqWeRtYiS",
|
||||
"oneNauseousMonkey",
|
||||
"69",
|
||||
"englishMaster",
|
||||
];
|
||||
619
backend/src/constants/base-configuration.ts
Normal file
619
backend/src/constants/base-configuration.ts
Normal file
@@ -0,0 +1,619 @@
|
||||
import { Configuration } from "@monkeytype/schemas/configuration";
|
||||
|
||||
/**
|
||||
* This is the base schema for the configuration of the API backend.
|
||||
* To add a new configuration. Simply add it to this object.
|
||||
* When changing this template, please follow the principle of "Secure by default" (https://en.wikipedia.org/wiki/Secure_by_default).
|
||||
*/
|
||||
export const BASE_CONFIGURATION: Configuration = {
|
||||
maintenance: false,
|
||||
dev: {
|
||||
responseSlowdownMs: 0,
|
||||
},
|
||||
results: {
|
||||
savingEnabled: false,
|
||||
objectHashCheckEnabled: false,
|
||||
filterPresets: {
|
||||
enabled: false,
|
||||
maxPresetsPerUser: 0,
|
||||
},
|
||||
limits: {
|
||||
regularUser: 1000,
|
||||
premiumUser: 10000,
|
||||
},
|
||||
maxBatchSize: 1000,
|
||||
},
|
||||
quotes: {
|
||||
reporting: {
|
||||
enabled: false,
|
||||
maxReports: 0,
|
||||
contentReportLimit: 0,
|
||||
},
|
||||
submissionsEnabled: false,
|
||||
maxFavorites: 0,
|
||||
},
|
||||
admin: {
|
||||
endpointsEnabled: false,
|
||||
},
|
||||
apeKeys: {
|
||||
endpointsEnabled: false,
|
||||
acceptKeys: false,
|
||||
maxKeysPerUser: 0,
|
||||
apeKeyBytes: 24,
|
||||
apeKeySaltRounds: 5,
|
||||
},
|
||||
users: {
|
||||
signUp: false,
|
||||
lastHashesCheck: {
|
||||
enabled: false,
|
||||
maxHashes: 0,
|
||||
},
|
||||
discordIntegration: {
|
||||
enabled: false,
|
||||
},
|
||||
autoBan: {
|
||||
enabled: false,
|
||||
maxCount: 5,
|
||||
maxHours: 1,
|
||||
},
|
||||
profiles: {
|
||||
enabled: false,
|
||||
},
|
||||
xp: {
|
||||
enabled: false,
|
||||
funboxBonus: 0,
|
||||
gainMultiplier: 0,
|
||||
maxDailyBonus: 0,
|
||||
minDailyBonus: 0,
|
||||
streak: {
|
||||
enabled: false,
|
||||
maxStreakDays: 0,
|
||||
maxStreakMultiplier: 0,
|
||||
},
|
||||
},
|
||||
inbox: {
|
||||
enabled: false,
|
||||
maxMail: 0,
|
||||
},
|
||||
premium: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
rateLimiting: {
|
||||
badAuthentication: {
|
||||
enabled: false,
|
||||
penalty: 0,
|
||||
flaggedStatusCodes: [],
|
||||
},
|
||||
},
|
||||
dailyLeaderboards: {
|
||||
enabled: false,
|
||||
maxResults: 0,
|
||||
leaderboardExpirationTimeInDays: 0,
|
||||
validModeRules: [],
|
||||
scheduleRewardsModeRules: [],
|
||||
topResultsToAnnounce: 1, // This should never be 0. Setting to zero will announce all results.
|
||||
xpRewardBrackets: [],
|
||||
},
|
||||
leaderboards: {
|
||||
minTimeTyping: 2 * 60 * 60,
|
||||
weeklyXp: {
|
||||
enabled: false,
|
||||
expirationTimeInDays: 0, // This should atleast be 15
|
||||
xpRewardBrackets: [],
|
||||
},
|
||||
},
|
||||
connections: { enabled: false, maxPerUser: 100 },
|
||||
};
|
||||
|
||||
type BaseSchema = {
|
||||
type: string;
|
||||
label?: string;
|
||||
hint?: string;
|
||||
};
|
||||
|
||||
type NumberSchema = {
|
||||
type: "number";
|
||||
min?: number;
|
||||
} & BaseSchema;
|
||||
|
||||
type BooleanSchema = {
|
||||
type: "boolean";
|
||||
} & BaseSchema;
|
||||
|
||||
type StringSchema = {
|
||||
type: "string";
|
||||
} & BaseSchema;
|
||||
|
||||
type ArraySchema<T extends unknown[]> = {
|
||||
type: "array";
|
||||
items: Schema<T>[number];
|
||||
} & BaseSchema;
|
||||
|
||||
type ObjectSchema<T> = {
|
||||
type: "object";
|
||||
fields: Schema<T>;
|
||||
} & BaseSchema;
|
||||
|
||||
type Schema<T> = {
|
||||
[P in keyof T]: T[P] extends unknown[]
|
||||
? ArraySchema<T[P]>
|
||||
: T[P] extends number
|
||||
? NumberSchema
|
||||
: T[P] extends boolean
|
||||
? BooleanSchema
|
||||
: T[P] extends string
|
||||
? StringSchema
|
||||
: T[P] extends object
|
||||
? ObjectSchema<T[P]>
|
||||
: never;
|
||||
};
|
||||
|
||||
export const CONFIGURATION_FORM_SCHEMA: ObjectSchema<Configuration> = {
|
||||
type: "object",
|
||||
label: "Server Configuration",
|
||||
fields: {
|
||||
maintenance: {
|
||||
type: "boolean",
|
||||
label: "In Maintenance",
|
||||
},
|
||||
dev: {
|
||||
type: "object",
|
||||
label: "Development",
|
||||
fields: {
|
||||
responseSlowdownMs: {
|
||||
type: "number",
|
||||
label: "Response Slowdown (miliseconds)",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
results: {
|
||||
type: "object",
|
||||
label: "Results",
|
||||
fields: {
|
||||
savingEnabled: {
|
||||
type: "boolean",
|
||||
label: "Saving Results",
|
||||
},
|
||||
objectHashCheckEnabled: {
|
||||
type: "boolean",
|
||||
label: "Object Hash Check",
|
||||
},
|
||||
filterPresets: {
|
||||
type: "object",
|
||||
label: "Filter Presets",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
maxPresetsPerUser: {
|
||||
type: "number",
|
||||
label: "Max Presets Per User",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
limits: {
|
||||
type: "object",
|
||||
label: "maximum results",
|
||||
fields: {
|
||||
regularUser: {
|
||||
type: "number",
|
||||
label: "for regular users",
|
||||
min: 0,
|
||||
},
|
||||
premiumUser: {
|
||||
type: "number",
|
||||
label: "for premium users",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
maxBatchSize: {
|
||||
type: "number",
|
||||
label: "results endpoint max batch size",
|
||||
min: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
quotes: {
|
||||
type: "object",
|
||||
label: "Quotes",
|
||||
fields: {
|
||||
reporting: {
|
||||
type: "object",
|
||||
label: "Reporting",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
maxReports: {
|
||||
type: "number",
|
||||
label: "Max Reports",
|
||||
},
|
||||
contentReportLimit: {
|
||||
type: "number",
|
||||
label: "Content Report Limit",
|
||||
},
|
||||
},
|
||||
},
|
||||
submissionsEnabled: {
|
||||
type: "boolean",
|
||||
label: "Submissions Enabled",
|
||||
},
|
||||
maxFavorites: {
|
||||
type: "number",
|
||||
label: "Max Favorites",
|
||||
},
|
||||
},
|
||||
},
|
||||
admin: {
|
||||
type: "object",
|
||||
label: "Admin",
|
||||
fields: {
|
||||
endpointsEnabled: {
|
||||
type: "boolean",
|
||||
label: "Endpoints Enabled",
|
||||
},
|
||||
},
|
||||
},
|
||||
apeKeys: {
|
||||
type: "object",
|
||||
label: "Ape Keys",
|
||||
fields: {
|
||||
endpointsEnabled: {
|
||||
type: "boolean",
|
||||
label: "Endpoints Enabled",
|
||||
},
|
||||
acceptKeys: {
|
||||
type: "boolean",
|
||||
label: "Accept Keys",
|
||||
},
|
||||
maxKeysPerUser: {
|
||||
type: "number",
|
||||
label: "Max Keys Per User",
|
||||
min: 0,
|
||||
},
|
||||
apeKeyBytes: {
|
||||
type: "number",
|
||||
label: "Ape Key Bytes",
|
||||
min: 24,
|
||||
},
|
||||
apeKeySaltRounds: {
|
||||
type: "number",
|
||||
label: "Ape Key Salt Rounds",
|
||||
min: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
users: {
|
||||
type: "object",
|
||||
label: "Users",
|
||||
fields: {
|
||||
premium: {
|
||||
type: "object",
|
||||
label: "Premium",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
},
|
||||
},
|
||||
signUp: {
|
||||
type: "boolean",
|
||||
label: "Sign Up Enabled",
|
||||
},
|
||||
lastHashesCheck: {
|
||||
type: "object",
|
||||
label: "Last Hashes Check",
|
||||
fields: {
|
||||
enabled: { type: "boolean", label: "Enabled" },
|
||||
maxHashes: { type: "number", label: "Hashes to store" },
|
||||
},
|
||||
},
|
||||
xp: {
|
||||
type: "object",
|
||||
label: "XP",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
gainMultiplier: {
|
||||
type: "number",
|
||||
label: "Gain Multiplier",
|
||||
},
|
||||
funboxBonus: {
|
||||
type: "number",
|
||||
label: "Funbox Bonus",
|
||||
},
|
||||
maxDailyBonus: {
|
||||
type: "number",
|
||||
label: "Max Daily Bonus",
|
||||
},
|
||||
minDailyBonus: {
|
||||
type: "number",
|
||||
label: "Min Daily Bonus",
|
||||
},
|
||||
streak: {
|
||||
type: "object",
|
||||
label: "Streak",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
maxStreakDays: {
|
||||
type: "number",
|
||||
label: "Max Streak Days",
|
||||
},
|
||||
maxStreakMultiplier: {
|
||||
type: "number",
|
||||
label: "Max Streak Multiplier",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
discordIntegration: {
|
||||
type: "object",
|
||||
label: "Discord Integration",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
},
|
||||
},
|
||||
autoBan: {
|
||||
type: "object",
|
||||
label: "Auto Ban",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
maxCount: {
|
||||
type: "number",
|
||||
label: "Max Count",
|
||||
min: 0,
|
||||
},
|
||||
maxHours: {
|
||||
type: "number",
|
||||
label: "Max Hours",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
inbox: {
|
||||
type: "object",
|
||||
label: "Inbox",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
maxMail: {
|
||||
type: "number",
|
||||
label: "Max Messages",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
profiles: {
|
||||
type: "object",
|
||||
label: "User Profiles",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
rateLimiting: {
|
||||
type: "object",
|
||||
label: "Rate Limiting",
|
||||
fields: {
|
||||
badAuthentication: {
|
||||
type: "object",
|
||||
label: "Bad Authentication Rate Limiter",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
penalty: {
|
||||
type: "number",
|
||||
label: "Penalty",
|
||||
min: 0,
|
||||
},
|
||||
flaggedStatusCodes: {
|
||||
type: "array",
|
||||
label: "Flagged Status Codes",
|
||||
items: {
|
||||
label: "Status Code",
|
||||
type: "number",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dailyLeaderboards: {
|
||||
type: "object",
|
||||
label: "Daily Leaderboards",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
maxResults: {
|
||||
type: "number",
|
||||
label: "Max Results",
|
||||
min: 0,
|
||||
},
|
||||
leaderboardExpirationTimeInDays: {
|
||||
type: "number",
|
||||
label: "Leaderboard Expiration Time In Days",
|
||||
min: 0,
|
||||
},
|
||||
validModeRules: {
|
||||
type: "array",
|
||||
label: "Valid Mode Rules",
|
||||
items: {
|
||||
type: "object",
|
||||
label: "Rule",
|
||||
fields: {
|
||||
language: {
|
||||
type: "string",
|
||||
label: "Language",
|
||||
},
|
||||
mode: {
|
||||
type: "string",
|
||||
label: "Mode",
|
||||
},
|
||||
mode2: {
|
||||
type: "string",
|
||||
label: "Secondary Mode",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
scheduleRewardsModeRules: {
|
||||
type: "array",
|
||||
label: "Schedule Rewards Mode Rules",
|
||||
items: {
|
||||
type: "object",
|
||||
label: "Rule",
|
||||
fields: {
|
||||
language: {
|
||||
type: "string",
|
||||
label: "Language",
|
||||
},
|
||||
mode: {
|
||||
type: "string",
|
||||
label: "Mode",
|
||||
},
|
||||
mode2: {
|
||||
type: "string",
|
||||
label: "Secondary Mode",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
topResultsToAnnounce: {
|
||||
type: "number",
|
||||
label: "Top Results To Announce",
|
||||
min: 1,
|
||||
hint: "This should atleast be 1. Setting to zero is very bad.",
|
||||
},
|
||||
xpRewardBrackets: {
|
||||
type: "array",
|
||||
label: "XP Reward Brackets",
|
||||
items: {
|
||||
type: "object",
|
||||
label: "Bracket",
|
||||
fields: {
|
||||
minRank: {
|
||||
type: "number",
|
||||
label: "Min Rank",
|
||||
min: 1,
|
||||
},
|
||||
maxRank: {
|
||||
type: "number",
|
||||
label: "Max Rank",
|
||||
min: 1,
|
||||
},
|
||||
minReward: {
|
||||
type: "number",
|
||||
label: "Min Reward",
|
||||
min: 0,
|
||||
},
|
||||
maxReward: {
|
||||
type: "number",
|
||||
label: "Max Reward",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
leaderboards: {
|
||||
type: "object",
|
||||
label: "Leaderboards",
|
||||
fields: {
|
||||
minTimeTyping: {
|
||||
type: "number",
|
||||
label: "Minimum typing time the user needs to get on a leaderboard",
|
||||
hint: "Typing time in seconds. Change is only applied after restarting the server.",
|
||||
min: 0,
|
||||
},
|
||||
weeklyXp: {
|
||||
type: "object",
|
||||
label: "Weekly XP",
|
||||
fields: {
|
||||
enabled: {
|
||||
type: "boolean",
|
||||
label: "Enabled",
|
||||
},
|
||||
expirationTimeInDays: {
|
||||
type: "number",
|
||||
label: "Expiration time in days",
|
||||
min: 0,
|
||||
hint: "This should atleast be 15, to allow for past week queries.",
|
||||
},
|
||||
xpRewardBrackets: {
|
||||
type: "array",
|
||||
label: "XP Reward Brackets",
|
||||
items: {
|
||||
type: "object",
|
||||
label: "Bracket",
|
||||
fields: {
|
||||
minRank: {
|
||||
type: "number",
|
||||
label: "Min Rank",
|
||||
min: 1,
|
||||
},
|
||||
maxRank: {
|
||||
type: "number",
|
||||
label: "Max Rank",
|
||||
min: 1,
|
||||
},
|
||||
minReward: {
|
||||
type: "number",
|
||||
label: "Min Reward",
|
||||
min: 0,
|
||||
},
|
||||
maxReward: {
|
||||
type: "number",
|
||||
label: "Max Reward",
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
connections: {
|
||||
type: "object",
|
||||
label: "Connections",
|
||||
fields: {
|
||||
enabled: { type: "boolean", label: "Enabled" },
|
||||
maxPerUser: {
|
||||
type: "number",
|
||||
label: "Max Connections per user",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
80
backend/src/constants/monkey-status-codes.ts
Normal file
80
backend/src/constants/monkey-status-codes.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
type Status = {
|
||||
code: number;
|
||||
message: string;
|
||||
};
|
||||
|
||||
type Statuses = {
|
||||
TEST_TOO_SHORT: Status;
|
||||
RESULT_HASH_INVALID: Status;
|
||||
RESULT_DATA_INVALID: Status;
|
||||
RESULT_SPACING_INVALID: Status;
|
||||
MISSING_KEY_DATA: Status;
|
||||
BOT_DETECTED: Status;
|
||||
DUPLICATE_RESULT: Status;
|
||||
GIT_GUD: Status;
|
||||
APE_KEY_INVALID: Status;
|
||||
APE_KEY_INACTIVE: Status;
|
||||
APE_KEY_MALFORMED: Status;
|
||||
APE_KEY_RATE_LIMIT_EXCEEDED: Status;
|
||||
};
|
||||
|
||||
const statuses: Statuses = {
|
||||
TEST_TOO_SHORT: {
|
||||
code: 460,
|
||||
message: "Test too short",
|
||||
},
|
||||
RESULT_HASH_INVALID: {
|
||||
code: 461,
|
||||
message: "Result hash invalid",
|
||||
},
|
||||
RESULT_SPACING_INVALID: {
|
||||
code: 462,
|
||||
message: "Result spacing invalid",
|
||||
},
|
||||
RESULT_DATA_INVALID: {
|
||||
code: 463,
|
||||
message: "Result data invalid",
|
||||
},
|
||||
MISSING_KEY_DATA: {
|
||||
code: 464,
|
||||
message: "Missing key data",
|
||||
},
|
||||
BOT_DETECTED: {
|
||||
code: 465,
|
||||
message: "Bot detected",
|
||||
},
|
||||
DUPLICATE_RESULT: {
|
||||
code: 466,
|
||||
message: "Duplicate result",
|
||||
},
|
||||
GIT_GUD: {
|
||||
code: 469,
|
||||
message: "Git gud scrub",
|
||||
},
|
||||
APE_KEY_INVALID: {
|
||||
code: 470,
|
||||
message: "Invalid ApeKey",
|
||||
},
|
||||
APE_KEY_INACTIVE: {
|
||||
code: 471,
|
||||
message: "ApeKey is inactive",
|
||||
},
|
||||
APE_KEY_MALFORMED: {
|
||||
code: 472,
|
||||
message: "ApeKey is malformed",
|
||||
},
|
||||
APE_KEY_RATE_LIMIT_EXCEEDED: {
|
||||
code: 479,
|
||||
message: "ApeKey rate limit exceeded",
|
||||
},
|
||||
};
|
||||
|
||||
const CUSTOM_STATUS_CODES = new Set<number>(
|
||||
Object.values(statuses).map((status) => status.code),
|
||||
);
|
||||
|
||||
export function isCustomCode(code: number): boolean {
|
||||
return CUSTOM_STATUS_CODES.has(code);
|
||||
}
|
||||
|
||||
export default statuses;
|
||||
Reference in New Issue
Block a user