From 4fa5307c1c3bdbd7605596978ae85ba28934a016 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Wed, 24 Aug 2022 21:36:46 +0200 Subject: [PATCH 1/9] feat: add basic verified_mods resource --- client/resource/verified_mods.json | 3 +++ client/verified_mods.js | 42 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 client/resource/verified_mods.json create mode 100644 client/verified_mods.js diff --git a/client/resource/verified_mods.json b/client/resource/verified_mods.json new file mode 100644 index 0000000..bb7b82e --- /dev/null +++ b/client/resource/verified_mods.json @@ -0,0 +1,3 @@ +[ + "hello there" +] \ No newline at end of file diff --git a/client/verified_mods.js b/client/verified_mods.js new file mode 100644 index 0000000..716f95a --- /dev/null +++ b/client/verified_mods.js @@ -0,0 +1,42 @@ +const path = require( "path" ) +const fs = require( "fs" ) + +const { getRatelimit } = require( "../shared/ratelimit.js" ) +const verifiedModsPath = path.join( __dirname, "resource", "verified_mods.json" ); + +// watch the JSON file so we can update it without a masterserver restart +fs.watch( verifiedModsPath, ( curr, prev ) => +{ + try + { + verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) + console.log( "Updated verified mods list successfully!" ) + } + catch ( ex ) + { + console.log( `Encountered error updating verified mods list: ${ ex }` ) + } + +} ) + +let verifiedModsList = []; +if ( fs.existsSync( verifiedModsPath ) ) + verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) + +module.exports = ( fastify, opts, done ) => +{ + // exported routes + + // GET /client/verifiedmods + // returns a list of manually-verified mods + fastify.get( "/client/verifiedmods", + { + config: { rateLimit: getRatelimit( "REQ_PER_MINUTE__CLIENT_MAINMENUPROMOS" ) }, // ratelimit + }, + async ( ) => + { + return verifiedModsList + } ) + + done() +} From 5032a30b6f276846b723bbb4a624c4d0ea8d8c32 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Wed, 24 Aug 2022 21:49:11 +0200 Subject: [PATCH 2/9] feat: add a ratelimit --- client/verified_mods.js | 2 +- dev.env | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/client/verified_mods.js b/client/verified_mods.js index 716f95a..d856247 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -31,7 +31,7 @@ module.exports = ( fastify, opts, done ) => // returns a list of manually-verified mods fastify.get( "/client/verifiedmods", { - config: { rateLimit: getRatelimit( "REQ_PER_MINUTE__CLIENT_MAINMENUPROMOS" ) }, // ratelimit + config: { rateLimit: getRatelimit( "REQ_PER_MINUTE__CLIENT_VERIFIEDMODS" ) }, // ratelimit }, async ( ) => { diff --git a/dev.env b/dev.env index cfae9c0..85722b6 100644 --- a/dev.env +++ b/dev.env @@ -22,6 +22,7 @@ REQ_PER_MINUTE__CLIENT_ORIGINAUTH=5 REQ_PER_MINUTE__CLIENT_AUTHWITHSERVER=10 REQ_PER_MINUTE__CLIENT_AUTHWITHSELF=25 REQ_PER_MINUTE__CLIENT_MAINMENUPROMOS=20 +REQ_PER_MINUTE__CLIENT_VERIFIEDMODS=1 REQ_PER_MINUTE__CLIENT_SERVERS=100 REQ_PER_MINUTE__SERVER_ADDSERVER=5 REQ_PER_MINUTE__SERVER_HEARTBEAT=60 From 01ad74380dbcac2c4b18b15b46fe950f2baf63f8 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Wed, 24 Aug 2022 22:34:48 +0200 Subject: [PATCH 3/9] refactor: fix formatting --- client/verified_mods.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/verified_mods.js b/client/verified_mods.js index d856247..bf1eed3 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -2,10 +2,10 @@ const path = require( "path" ) const fs = require( "fs" ) const { getRatelimit } = require( "../shared/ratelimit.js" ) -const verifiedModsPath = path.join( __dirname, "resource", "verified_mods.json" ); +const verifiedModsPath = path.join( __dirname, "resource", "verified_mods.json" ) // watch the JSON file so we can update it without a masterserver restart -fs.watch( verifiedModsPath, ( curr, prev ) => +fs.watch( verifiedModsPath, () => { try { @@ -16,10 +16,9 @@ fs.watch( verifiedModsPath, ( curr, prev ) => { console.log( `Encountered error updating verified mods list: ${ ex }` ) } - } ) -let verifiedModsList = []; +let verifiedModsList = [] if ( fs.existsSync( verifiedModsPath ) ) verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) From 8ac0019e77b0d1684ce0bc2f8cbd2800e666bc51 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Thu, 25 Aug 2022 08:30:14 +0200 Subject: [PATCH 4/9] feat: add methods to verify mods names --- client/verified_mods.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/client/verified_mods.js b/client/verified_mods.js index bf1eed3..ef409e4 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -1,6 +1,26 @@ const path = require( "path" ) const fs = require( "fs" ) +// Checks if a mod entry respects the mod naming convention (AuthorName-ModName-Version). +// https://northstar.thunderstore.io/package/create/docs/ (check dependencies format) +function checkModEntry (modName) { + return /^[a-zA-Z0-9\_]+-[a-zA-Z0-9\_]+-[0-9]+\.[0-9]+\.[0-9]+$/.test(modName); +} + +// Remove mod entries that do not match naming convention from exposed mods list. +function checkAllMods() { + for (const mod of verifiedModsList) { + if (!checkModEntry(mod)) { + console.warn(`Since "${mod}" does not respect mod naming convention, it was removed from verified mods list.`); + let index = verifiedModsList.indexOf(mod); + while (index !== -1) { + verifiedModsList.splice(index, 1); + index = verifiedModsList.indexOf(mod); + } + } + } +} + const { getRatelimit } = require( "../shared/ratelimit.js" ) const verifiedModsPath = path.join( __dirname, "resource", "verified_mods.json" ) From b7a502a6e5f6ffbedf0dfb1b379becb36c2e7209 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Thu, 25 Aug 2022 21:32:20 +0200 Subject: [PATCH 5/9] feat: verify all mods entries --- client/verified_mods.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/verified_mods.js b/client/verified_mods.js index ef409e4..ab0104a 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -30,6 +30,7 @@ fs.watch( verifiedModsPath, () => try { verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) + checkAllMods() console.log( "Updated verified mods list successfully!" ) } catch ( ex ) @@ -39,8 +40,10 @@ fs.watch( verifiedModsPath, () => } ) let verifiedModsList = [] -if ( fs.existsSync( verifiedModsPath ) ) +if ( fs.existsSync( verifiedModsPath ) ) { verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) + checkAllMods() +} module.exports = ( fastify, opts, done ) => { From 9e103a27980085596f6c5820732a69a1a940c86e Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Thu, 25 Aug 2022 21:35:20 +0200 Subject: [PATCH 6/9] fix: correctly remove non-valid mods from list --- client/verified_mods.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/verified_mods.js b/client/verified_mods.js index ab0104a..edbf20a 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -9,13 +9,17 @@ function checkModEntry (modName) { // Remove mod entries that do not match naming convention from exposed mods list. function checkAllMods() { - for (const mod of verifiedModsList) { + for (let i=0; i Date: Thu, 25 Aug 2022 22:58:37 +0200 Subject: [PATCH 7/9] fix: remove duplicated entries --- client/verified_mods.js | 42 ++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/client/verified_mods.js b/client/verified_mods.js index edbf20a..4517c74 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -3,24 +3,39 @@ const fs = require( "fs" ) // Checks if a mod entry respects the mod naming convention (AuthorName-ModName-Version). // https://northstar.thunderstore.io/package/create/docs/ (check dependencies format) -function checkModEntry (modName) { - return /^[a-zA-Z0-9\_]+-[a-zA-Z0-9\_]+-[0-9]+\.[0-9]+\.[0-9]+$/.test(modName); +function checkModEntry ( modName ) +{ + return /^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+-[0-9]+\.[0-9]+\.[0-9]+$/.test( modName ) } // Remove mod entries that do not match naming convention from exposed mods list. -function checkAllMods() { - for (let i=0; i entry === mod ).length + while ( entryCount !== 1 ) + { + verifiedModsList.splice( verifiedModsList.indexOf( mod, i+1 ), 1 ) + entryCount = verifiedModsList.filter( entry => entry === mod ).length + console.warn( `"${mod}" entry was found several times, deleting duplicate.` ) } } } @@ -44,7 +59,8 @@ fs.watch( verifiedModsPath, () => } ) let verifiedModsList = [] -if ( fs.existsSync( verifiedModsPath ) ) { +if ( fs.existsSync( verifiedModsPath ) ) +{ verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) checkAllMods() } From 6e86da43211534cb70233abf65ca7ee7643e6115 Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Thu, 25 Aug 2022 23:00:56 +0200 Subject: [PATCH 8/9] test: add some mods to list --- client/resource/verified_mods.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/resource/verified_mods.json b/client/resource/verified_mods.json index bb7b82e..621140f 100644 --- a/client/resource/verified_mods.json +++ b/client/resource/verified_mods.json @@ -1,3 +1,9 @@ [ - "hello there" + "northstar-Northstar-1.9.4", + "EladNLG-ModSettings-1.1.2", + 12, + 42, + "EladNLG-ModSettings-1.1.2", + "Wrong mod name", + "EladNLG-ModSettings-1.1.2" ] \ No newline at end of file From 62524f26b0eeb46922516653e0729f473053732a Mon Sep 17 00:00:00 2001 From: Remy Raes Date: Fri, 26 Aug 2022 22:41:32 +0200 Subject: [PATCH 9/9] feat: implement new mod format --- client/resource/verified_mods.json | 21 ++++++---- client/verified_mods.js | 66 +++++++++++++++--------------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/client/resource/verified_mods.json b/client/resource/verified_mods.json index 621140f..ceeca2c 100644 --- a/client/resource/verified_mods.json +++ b/client/resource/verified_mods.json @@ -1,9 +1,12 @@ -[ - "northstar-Northstar-1.9.4", - "EladNLG-ModSettings-1.1.2", - 12, - 42, - "EladNLG-ModSettings-1.1.2", - "Wrong mod name", - "EladNLG-ModSettings-1.1.2" -] \ No newline at end of file +{ + "Mod Settings": + { + "DependencyPrefix": "EladNLG-ModSettings", + "Versions": [ "1.0.0", "1.1.0" ] + }, + "Moblin.Archon": + { + "DependencyPrefix": "GalacticMoblin-MoblinArchon", + "Versions": [ "1.3.0", "1.3.1" ] + } +} \ No newline at end of file diff --git a/client/verified_mods.js b/client/verified_mods.js index 4517c74..e300d8f 100644 --- a/client/verified_mods.js +++ b/client/verified_mods.js @@ -1,41 +1,43 @@ const path = require( "path" ) const fs = require( "fs" ) -// Checks if a mod entry respects the mod naming convention (AuthorName-ModName-Version). -// https://northstar.thunderstore.io/package/create/docs/ (check dependencies format) -function checkModEntry ( modName ) +// Checks if a mod entry is an object, has "DependencyPrefix" and "Versions" properties, +// and also checks if both fields have correct format. +function checkModEntry ( modContent ) { - return /^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+-[0-9]+\.[0-9]+\.[0-9]+$/.test( modName ) + if ( typeof modContent !== "object" || Array.isArray( modContent ) || modContent === null ) + return false + if ( !Object.prototype.hasOwnProperty.call( modContent, "DependencyPrefix" ) || !Object.prototype.hasOwnProperty.call( modContent, "Versions" ) ) + return false + + // Checking TeamName-ModName format. + const dependencyPrefix = modContent["DependencyPrefix"] + if ( !/^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+$/.test( dependencyPrefix ) ) + return false + + // Checking x.y.z versions format. + const versions = modContent["Versions"] + for ( const version of versions ) + { + if ( Object.prototype.toString.call( version ) !== "[object String]" || !/[0-9]+\.[0-9]+\.[0-9]$/.test( version ) ) + return false + } + + return true } -// Remove mod entries that do not match naming convention from exposed mods list. +// Remove mod entries that do not match formatting convention from exposed mods list. function checkAllMods() { - for ( let i=0; i entry === mod ).length - while ( entryCount !== 1 ) + for ( let i=0; i entry === mod ).length - console.warn( `"${mod}" entry was found several times, deleting duplicate.` ) + console.warn( `Since "${mod}" does not have correct format, it was removed from verified mods list.` ) + delete verifiedMods[mod] } } } @@ -48,7 +50,7 @@ fs.watch( verifiedModsPath, () => { try { - verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) + verifiedMods = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) checkAllMods() console.log( "Updated verified mods list successfully!" ) } @@ -58,10 +60,10 @@ fs.watch( verifiedModsPath, () => } } ) -let verifiedModsList = [] +let verifiedMods = {} if ( fs.existsSync( verifiedModsPath ) ) { - verifiedModsList = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) + verifiedMods = JSON.parse( fs.readFileSync( verifiedModsPath ).toString() ) checkAllMods() } @@ -77,7 +79,7 @@ module.exports = ( fastify, opts, done ) => }, async ( ) => { - return verifiedModsList + return verifiedMods } ) done()