From 07f8cd99e1f12abb348a5731de16a1971b8a9e42 Mon Sep 17 00:00:00 2001 From: zkldi Date: Tue, 4 May 2021 16:28:23 +0100 Subject: [PATCH] regex fixes --- server/src/core/auth-core.test.ts | 8 ++--- server/src/core/db-core.test.ts | 2 +- server/src/core/user-core.ts | 2 +- server/src/db/db.ts | 2 ++ server/src/db/schemas.ts | 34 +++++++++++++++++-- server/src/internal-api/auth/auth.ts | 8 ++--- server/src/internal-api/import/import.ts | 4 +-- .../src/middleware/prudence-validate.test.ts | 2 +- .../calculated-data/calculated-data.ts | 4 +-- .../calculated-data/game-specific-stats.ts | 4 +-- .../framework/common/string-asserts.ts | 2 +- .../score-import/framework/pb/process-pbs.ts | 1 - .../framework/score-importing/insert-score.ts | 4 +-- .../score-importing/score-id.test.ts | 2 +- .../file/csv-eamusement-iidx/converter.ts | 4 +-- 15 files changed, 55 insertions(+), 28 deletions(-) diff --git a/server/src/core/auth-core.test.ts b/server/src/core/auth-core.test.ts index 8dbc42db5..655a0cd83 100644 --- a/server/src/core/auth-core.test.ts +++ b/server/src/core/auth-core.test.ts @@ -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(); diff --git a/server/src/core/db-core.test.ts b/server/src/core/db-core.test.ts index ef88f00e6..17524f579 100644 --- a/server/src/core/db-core.test.ts +++ b/server/src/core/db-core.test.ts @@ -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." ); diff --git a/server/src/core/user-core.ts b/server/src/core/user-core.ts index 39bfaf17b..40f02c0a1 100644 --- a/server/src/core/user-core.ts +++ b/server/src/core/user-core.ts @@ -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( diff --git a/server/src/db/db.ts b/server/src/db/db.ts index d632a0abe..6cb3e300a 100644 --- a/server/src/db/db.ts +++ b/server/src/db/db.ts @@ -9,6 +9,7 @@ import { InviteCodeDocument, MilestoneDocument, NotificationDocument, + FolderChartLookup, PrivateUserDocument, PublicAPIKeyDocument, ScoreDocument, @@ -95,6 +96,7 @@ const db = { scores: monkDB.get("scores"), "score-pbs": monkDB.get("score-pbs"), folders: monkDB.get("folders"), + "folder-chart-lookup": monkDB.get("folder-chart-lookup"), goals: monkDB.get("goals"), "user-goals": monkDB.get("user-goals"), milestones: monkDB.get("milestones"), diff --git a/server/src/db/schemas.ts b/server/src/db/schemas.ts index 47ece41d1..f9358f222 100644 --- a/server/src/db/schemas.ts +++ b/server/src/db/schemas.ts @@ -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 = { 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, }; diff --git a/server/src/internal-api/auth/auth.ts b/server/src/internal-api/auth/auth.ts index 89ecb900c..fbee9ac84 100644 --- a/server/src/internal-api/auth/auth.ts +++ b/server/src/internal-api/auth/auth.ts @@ -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", diff --git a/server/src/internal-api/import/import.ts b/server/src/internal-api/import/import.ts index 90763122b..57732a956 100644 --- a/server/src/internal-api/import/import.ts +++ b/server/src/internal-api/import/import.ts @@ -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); diff --git a/server/src/middleware/prudence-validate.test.ts b/server/src/middleware/prudence-validate.test.ts index 99a082a21..bc53312c0 100644 --- a/server/src/middleware/prudence-validate.test.ts +++ b/server/src/middleware/prudence-validate.test.ts @@ -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, { diff --git a/server/src/score-import/framework/calculated-data/calculated-data.ts b/server/src/score-import/framework/calculated-data/calculated-data.ts index a8357abf7..976f5096b 100644 --- a/server/src/score-import/framework/calculated-data/calculated-data.ts +++ b/server/src/score-import/framework/calculated-data/calculated-data.ts @@ -42,7 +42,7 @@ const OVERRIDE_RATING_FUNCTIONS: Partial> = { /** * Calculates the rating for a score. Listens to the override functions declared above. */ -async function CalculateRating( +function CalculateRating( dryScore: DryScore, game: G, playtype: Playtypes[G], @@ -56,7 +56,7 @@ async function CalculateRating( return 0; // go to default kamaitachi rating fn ? } - return await OverrideFunction(dryScore, chart); + return OverrideFunction(dryScore, chart); } // stub diff --git a/server/src/score-import/framework/calculated-data/game-specific-stats.ts b/server/src/score-import/framework/calculated-data/game-specific-stats.ts index 4a9bc5ec8..ddc881652 100644 --- a/server/src/score-import/framework/calculated-data/game-specific-stats.ts +++ b/server/src/score-import/framework/calculated-data/game-specific-stats.ts @@ -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); diff --git a/server/src/score-import/framework/common/string-asserts.ts b/server/src/score-import/framework/common/string-asserts.ts index 2670a4eda..3d0870dc5 100644 --- a/server/src/score-import/framework/common/string-asserts.ts +++ b/server/src/score-import/framework/common/string-asserts.ts @@ -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); diff --git a/server/src/score-import/framework/pb/process-pbs.ts b/server/src/score-import/framework/pb/process-pbs.ts index 20ce903cd..99275ce8b 100644 --- a/server/src/score-import/framework/pb/process-pbs.ts +++ b/server/src/score-import/framework/pb/process-pbs.ts @@ -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; } diff --git a/server/src/score-import/framework/score-importing/insert-score.ts b/server/src/score-import/framework/score-importing/insert-score.ts index 8f5614f9e..c6a4e832a 100644 --- a/server/src/score-import/framework/score-importing/insert-score.ts +++ b/server/src/score-import/framework/score-importing/insert-score.ts @@ -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; diff --git a/server/src/score-import/framework/score-importing/score-id.test.ts b/server/src/score-import/framework/score-importing/score-id.test.ts index f96ce5662..1bf8f7f36 100644 --- a/server/src/score-import/framework/score-importing/score-id.test.ts +++ b/server/src/score-import/framework/score-importing/score-id.test.ts @@ -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." ); diff --git a/server/src/score-import/import-types/file/csv-eamusement-iidx/converter.ts b/server/src/score-import/import-types/file/csv-eamusement-iidx/converter.ts index 932e2eb74..26fee3a04 100644 --- a/server/src/score-import/import-types/file/csv-eamusement-iidx/converter.ts +++ b/server/src/score-import/import-types/file/csv-eamusement-iidx/converter.ts @@ -233,8 +233,8 @@ const ConverterFn: ConverterFunction