diff --git a/src/controllers/postPackages.js b/src/controllers/postPackages.js index 77837361..5d8658a7 100644 --- a/src/controllers/postPackages.js +++ b/src/controllers/postPackages.js @@ -1,6 +1,7 @@ /** * @module postPackages */ +const parseGithubURL = require("parse-github-url"); module.exports = { docs: { @@ -92,7 +93,7 @@ module.exports = { } // Check repository format validity. - if (params.repository === "" || typeof params.repository !== "string") { + if (params.repository === false) { // repository format is invalid const sso = new context.sso(); @@ -105,7 +106,8 @@ module.exports = { // Currently though the repository is in `owner/repo` format, // meanwhile needed functions expects just `repo` - const repo = params.repository.split("/")[1]?.toLowerCase(); + const repo = parseGithubURL(params.repository)?.name.toLowerCase(); + const ownerRepo = parseGithubURL(params.repository)?.repo; if (repo === undefined) { const sso = new context.sso(); @@ -133,7 +135,7 @@ module.exports = { // has permissions to this package const gitowner = await context.vcs.ownership( user.content, - params.repository + ownerRepo ); callStack.addCall("vcs.ownership", gitowner); @@ -148,7 +150,7 @@ module.exports = { // TODO: Stop hardcoding `git` as service const newPack = await context.vcs.newPackageData( user.content, - params.repository, + ownerRepo, "git" ); @@ -190,16 +192,15 @@ module.exports = { // Now to check if this package is a bundled package (since they don't exist on the db) const isBundled = context.bundled.isNameBundled(newPack.content.name); + callStack.addCall("bundled.isNameBundled", isBundled); + if (isBundled.ok && isBundled.content) { const sso = new context.sso(); return sso .notOk() .addShort("package_exists") - .addCalls("auth.verifyAuth", user) - .addCalls("vcs.ownership", gitowner) - .addCalls("vcs.newPackageData", newPack) - .addCalls("bundled.isNameBundled", isBundled); + .assignCalls(callStack); } // Now with valid package data, we can insert them into the DB @@ -247,7 +248,7 @@ module.exports = { sso.featureDetection = { user: user.content, service: "git", // TODO stop hardcoding git - ownerRepo: params.repository, + ownerRepo: ownerRepo, }; return sso.isOk().addContent(packageObjectFull); diff --git a/src/query_parameters/repository.js b/src/query_parameters/repository.js index 91f4b323..a54e6b20 100644 --- a/src/query_parameters/repository.js +++ b/src/query_parameters/repository.js @@ -2,8 +2,9 @@ * @function repo * @desc Parses the 'repository' query parameter, returning it if valid, otherwise returning ''. * @param {object} req - The `Request` object inherited from the Express endpoint. - * @returns {string} Returning the valid 'repository' query parameter, or '' if invalid. + * @returns {string} Returning the valid 'repository' query parameter, or false if invalid. */ +const parseGithubURL = require("parse-github-url"); module.exports = { schema: { @@ -21,17 +22,25 @@ module.exports = { const prov = req.query.repository; if (prov === undefined) { - return ""; + return false; } - const re = /^[-a-zA-Z\d][-\w.]{0,213}\/[-a-zA-Z\d][-\w.]{0,213}$/; + const parsed = parseGithubURL(prov); - // Ensure req is in the format "owner/repo" and - // owner and repo observe the following rules: - // - less than or equal to 214 characters - // - only URL safe characters (letters, digits, dashes, underscores and/or dots) - // - cannot begin with a dot or an underscore - // - cannot contain a space. - return prov.match(re) !== null ? prov : ""; + if (typeof parsed.owner !== "string" || typeof parsed.name !== "string") { + return false; + } + + const re = /^[^._ ][^ ]{0,213}$/; + // Ensure both the name and owner: + // - less than or equal to 214 characters + // - cannot begin with a dot or an underscore + // - cannot contain a space + + if (parsed.owner.match(re) === null || parsed.name.match(re) === null) { + return false; + } + + return prov; }, }; diff --git a/tests/http/postPackages.test.js b/tests/http/postPackages.test.js index e8e91d0e..82df8101 100644 --- a/tests/http/postPackages.test.js +++ b/tests/http/postPackages.test.js @@ -36,7 +36,7 @@ describe("POST /api/packages Behaves as expected", () => { const sso = await endpoint.logic( { - repository: "", + repository: false, auth: "valid-token", }, localContext @@ -63,7 +63,7 @@ describe("POST /api/packages Behaves as expected", () => { const sso = await endpoint.logic( { - repository: "bad-format", + repository: false, auth: "valid-token", }, localContext diff --git a/tests/unit/query.test.js b/tests/unit/query.test.js index 726b624f..bd92d923 100644 --- a/tests/unit/query.test.js +++ b/tests/unit/query.test.js @@ -104,8 +104,9 @@ describe("Verify Auth Query Returns", () => { const repositoryCases = [ [{ query: { repository: "owner/repo" } }, "owner/repo"], - [{ query: {} }, ""], - [{ query: { repository: "InvalidRepo" } }, ""], + [{ query: {} }, false], + [{ query: { repository: "InvalidRepo" } }, false], + [{ query: { repository: "git@github.com:ndr-brt/pulsar-p5js" } }, "git@github.com:ndr-brt/pulsar-p5js"], ]; describe("Verify Repo Query Returns", () => {