regex fixes

This commit is contained in:
zkldi
2021-05-04 16:28:23 +01:00
parent 864c574e92
commit 07f8cd99e1
15 changed files with 55 additions and 28 deletions
+4 -4
View File
@@ -15,7 +15,7 @@ import ResetDBState from "../test-utils/reset-db-state";
t.test("#CreateAPIKey", (t) => {
t.match(
CreateAPIKey(),
/[0-9a-f]{20}/,
/[0-9a-f]{20}/u,
"Should return a 20 character long lowercase hex string."
);
@@ -34,7 +34,7 @@ t.test("#AddNewUserAPIKey", (t) => {
data,
{
_id: Prudence.any, // lazy, should be isObjID? @todo
apiKey: Prudence.regex(/[0-9a-f]{20}/),
apiKey: Prudence.regex(/[0-9a-f]{20}/u),
assignedTo: Prudence.is(1),
expireTime: Prudence.is(3176708633264),
permissions: {
@@ -86,7 +86,7 @@ t.test("#ReinstateInvite", (t) => {
});
t.test("#CreateInviteCode", (t) => {
t.match(CreateInviteCode(), /^[0-9a-f]{40}$/, "Invite should be a 40 character hex string.");
t.match(CreateInviteCode(), /^[0-9a-f]{40}$/u, "Invite should be a 40 character hex string.");
t.end();
});
@@ -105,7 +105,7 @@ t.test("#AddNewInvite", (t) => {
// was created +/- 6 seconds from now. This is perhaps too lenient, but we're only really testing its just around now ish.
t.ok(Math.abs(result.createdOn - Date.now()) <= 6000, "Invite was created roughly now.");
t.match(result.code, /^[0-9a-f]{40}$/, "Invite code should be a 40 character hex string.");
t.match(result.code, /^[0-9a-f]{40}$/u, "Invite code should be a 40 character hex string.");
});
t.end();
+1 -1
View File
@@ -20,7 +20,7 @@ t.test("#GetNextCounterValue", (t) => {
});
t.rejects(
async () => await GetNextCounterValue("fake-counter"),
() => GetNextCounterValue("fake-counter"),
"Could not find sequence document for fake-counter."
);
+1 -1
View File
@@ -74,7 +74,7 @@ export function PRIVATEINFO_GetUserWithID(userID: integer) {
*/
export function ResolveUser(usernameOrID: string) {
// user ID passed
if (usernameOrID.match(/^[0-9]$/)) {
if (usernameOrID.match(/^[0-9]$/u)) {
let intID = Number(usernameOrID);
return db.users.findOne(
+2
View File
@@ -9,6 +9,7 @@ import {
InviteCodeDocument,
MilestoneDocument,
NotificationDocument,
FolderChartLookup,
PrivateUserDocument,
PublicAPIKeyDocument,
ScoreDocument,
@@ -95,6 +96,7 @@ const db = {
scores: monkDB.get<ScoreDocument>("scores"),
"score-pbs": monkDB.get<PBScoreDocument>("score-pbs"),
folders: monkDB.get<FolderDocument>("folders"),
"folder-chart-lookup": monkDB.get<FolderChartLookup>("folder-chart-lookup"),
goals: monkDB.get<GoalDocument>("goals"),
"user-goals": monkDB.get<UserGoalDocument>("user-goals"),
milestones: monkDB.get<MilestoneDocument>("milestones"),
+31 -3
View File
@@ -7,15 +7,15 @@ import {
validHitData,
validDifficulties,
validPlaytypes,
supportedGames,
} from "kamaitachi-common/js/config";
import p, { PrudenceSchema, ValidSchemaValue } from "prudence";
// eslint-disable-next-line no-useless-escape
const LAZY_EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const LAZY_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/u;
export const PRUDENCE_PUBLIC_USER: PrudenceSchema = {
_id: p.any,
username: p.regex(/^[a-zA-Z_-][a-zA-Z0-9_-]{2,20}$/),
username: p.regex(/^[a-zA-Z_-][a-zA-Z0-9_-]{2,20}$/u),
usernameLowercase: (self, parent) => self === (parent!.username as string).toLowerCase(),
id: p.isPositiveInteger,
settings: {
@@ -402,6 +402,32 @@ export const PRUDENCE_SONG_SCHEMAS: Record<Game, PrudenceSchema> = {
usc: CreatePrSong({ sdvxEquiv: p.isPositiveInteger }),
};
const PRUDENCE_FOLDER_CHART_LOOKUP: PrudenceSchema = {
chartID: "string",
folderID: "string",
};
const PRUDENCE_FOLDER: PrudenceSchema = {
title: "string",
game: p.isIn(supportedGames),
playtype: (self, parent) => p.isIn(validPlaytypes[parent.game as Game])(self),
folderID: "string",
table: "string",
tableIndex: "number",
type: p.isIn("songs", "charts", "static"),
data: (self, parent) => {
if (parent.type === "static") {
return Array.isArray(self) && self.every((e) => typeof e === "string");
}
// this is a temp hackjob, it should technically
// check whether this document matches a
// partialised chart/song doc
// but.. can be done later.
return typeof self === "object" && !!self; // whatever
},
};
/**
* Schemas that are "static", i.e. the content of the document
* does not depend on fields in the document (such as score docs)
@@ -413,4 +439,6 @@ export const STATIC_SCHEMAS = {
counters: PRUDENCE_COUNTER,
charts: PRUDENCE_CHART_SCHEMAS,
songs: PRUDENCE_SONG_SCHEMAS,
"folder-chart-lookup": PRUDENCE_FOLDER_CHART_LOOKUP,
folders: PRUDENCE_FOLDER,
};
+3 -5
View File
@@ -19,9 +19,7 @@ const logger = CreateLogCtx("auth.ts");
const router = Router({ mergeParams: true });
// ??? eslint cant parse this regex.
// eslint-disable-next-line no-useless-escape
const LAZY_EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const LAZY_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/u;
const BASE_DOMAIN = process.env.NODE_ENV === "production" ? ".kamaitachi.xyz" : "127.0.0.1";
const SHOULD_COOKIES_SECURE = process.env.NODE_ENV === "production";
@@ -34,7 +32,7 @@ router.post(
"/login",
prValidate(
{
username: Prudence.regex(/^[a-zA-Z_-][a-zA-Z0-9_-]{2,20}$/),
username: Prudence.regex(/^[a-zA-Z_-][a-zA-Z0-9_-]{2,20}$/u),
password: ValidatePassword,
captcha: "string",
},
@@ -153,7 +151,7 @@ router.post(
"/register",
prValidate(
{
username: Prudence.regex(/^[a-zA-Z_-][a-zA-Z0-9_-]{2,20}$/),
username: Prudence.regex(/^[a-zA-Z_-][a-zA-Z0-9_-]{2,20}$/u),
password: ValidatePassword,
email: Prudence.regex(LAZY_EMAIL_REGEX),
inviteCode: "string",
+2 -2
View File
@@ -67,8 +67,8 @@ router.post(
try {
let importType = req.body.importType as FileUploadImportTypes;
const inputParser = async (logger: Logger) =>
await ResolveFileUploadData(importType, req.file, req.body, logger);
const inputParser = (logger: Logger) =>
ResolveFileUploadData(importType, req.file, req.body, logger);
const userDoc = await GetUserWithID(req.session.ktchi!.userID);
@@ -4,7 +4,7 @@ import prValidate from "./prudence-validate";
import Prudence from "prudence";
t.test("#PrudenceMiddleware", (t) => {
const mw = prValidate({ foo: Prudence.regex(/^baz$/) }, { foo: "example error message" });
const mw = prValidate({ foo: Prudence.regex(/^baz$/u) }, { foo: "example error message" });
t.test("Should return 400 on invalid prudence validation", async (t) => {
let { res } = await expMiddlewareMock(mw, {
@@ -42,7 +42,7 @@ const OVERRIDE_RATING_FUNCTIONS: Partial<Record<Game, any>> = {
/**
* Calculates the rating for a score. Listens to the override functions declared above.
*/
async function CalculateRating<G extends Game>(
function CalculateRating<G extends Game>(
dryScore: DryScore,
game: G,
playtype: Playtypes[G],
@@ -56,7 +56,7 @@ async function CalculateRating<G extends Game>(
return 0; // go to default kamaitachi rating fn ?
}
return await OverrideFunction(dryScore, chart);
return OverrideFunction(dryScore, chart);
}
// stub
@@ -68,9 +68,9 @@ export function CalculateBPI(
wrEx: integer,
yourEx: integer,
max: integer,
powCoef: number | null
pc: number | null
) {
powCoef ??= 1.175;
let powCoef = pc ?? 1.175;
const yourPGF = BPIPikaGreatFn(yourEx, max);
const kaidenPGF = BPIPikaGreatFn(kaidenEx, max);
const wrPGF = BPIPikaGreatFn(wrEx, max);
@@ -1,6 +1,6 @@
import { InvalidScoreFailure } from "../score-importing/converter-failures";
const isIntegerRegex = /^-?\d+$/;
const isIntegerRegex = /^-?\d+$/u;
export function AssertStrAsPositiveInt(strVal: string, errorMessage: string) {
let isInt = isIntegerRegex.test(strVal);
@@ -45,5 +45,4 @@ export async function ProcessPBs(
// originally we returned nUpserted from this function, but it's not
// very useful to anyone, tbh.
return;
}
@@ -13,7 +13,7 @@ const MAX_PIPELINE_LENGTH = 500;
* @returns True on success, The amount of scores inserted on auto-pipeline-flush, and null if
* the score provided is already loaded.
*/
export async function QueueScoreInsert(score: ScoreDocument) {
export function QueueScoreInsert(score: ScoreDocument) {
if (ScoreIDs.has(score.scoreID)) {
// skip
logger.verbose(`Triggered skip for ID ${score.scoreID}`);
@@ -25,7 +25,7 @@ export async function QueueScoreInsert(score: ScoreDocument) {
if (ScoreQueue.length >= MAX_PIPELINE_LENGTH) {
logger.verbose(`Triggered pipeline flush with len ${ScoreQueue.length}.`);
return await InsertQueue();
return InsertQueue();
}
return true;
@@ -23,7 +23,7 @@ t.test("#CreateScoreID", (t) => {
t.match(
scoreID,
/^R[0-9a-f]{40}/,
/^R[0-9a-f]{40}/u,
"Should return an R followed by 40 characters of lowercase hex as scoreID."
);
@@ -233,8 +233,8 @@ const ConverterFn: ConverterFunction<IIDXEamusementCSVData, IIDXEamusementCSVCon
// if pre-HV, leggendarias were stored in a wacky form.
if (!context.hasBeginnerAndLegg) {
// hack fix for legacy LEGGENDARIA titles
if (data.title.match(/(†|†LEGGENDARIA)$/)) {
data.title = data.title.replace(/(†|†LEGGENDARIA)$/, "").trimEnd();
if (data.title.match(/(†|†LEGGENDARIA)$/u)) {
data.title = data.title.replace(/(†|†LEGGENDARIA)$/u, "").trimEnd();
isLegacyLeggendaria = true;
}
}