Skip to content

Commit 7ad35f9

Browse files
committed
Add validation of CDN URL
1 parent 300029f commit 7ad35f9

File tree

5 files changed

+327
-24
lines changed

5 files changed

+327
-24
lines changed

gulpfile.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ const chalk = require('chalk');
66
const del = require('del');
77
const ejs = require('gulp-ejs');
88
const zip = require('gulp-zip');
9+
const path = require('path');
10+
const globby = require('globby');
911
const mergeStream = require('merge-stream');
1012
const {
1113
formatVersionFolder,
1214
compareStrings,
1315
formatPackageUpgrades,
1416
getLibraries,
1517
getUpgradeVersions,
18+
validatePackage,
1619
} = require('./utility');
1720

1821
const libraries = getLibraries();
@@ -66,9 +69,33 @@ function makePackageTask(library) {
6669
return packageFn;
6770
}
6871

72+
/**
73+
* A Gulp task which validates the packages
74+
*
75+
* @returns {Promise} A Promise which resolves when done
76+
*/
77+
async function validatePackages() {
78+
let invalidCount = 0;
79+
const zipFiles = await globby('./_InstallPackages/**/*.zip');
80+
for (const zipFile of zipFiles) {
81+
const fileName = path.basename(zipFile);
82+
const validationResult = await validatePackage(zipFile);
83+
if (validationResult.length > 0) {
84+
invalidCount++;
85+
log.error(`${fileName} was invalid:`);
86+
validationResult.forEach(msg => log.error(msg));
87+
}
88+
}
89+
90+
if (invalidCount > 0) {
91+
throw new Error(`${invalidCount} invalid package(s)`);
92+
}
93+
}
94+
6995
const defaultTask = gulp.series(
7096
clean,
71-
gulp.parallel(...libraries.map(makePackageTask))
97+
gulp.parallel(...libraries.map(makePackageTask)),
98+
validatePackages
7299
);
73100

74101
/**

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,22 @@
8181
"chalk": "^2.4.2",
8282
"cliui": "5.0.0",
8383
"cross-spawn": "6.0.5",
84+
"decompress": "4.2.0",
8485
"del": "5.1.0",
8586
"end-of-stream": "1.4.1",
8687
"fancy-log": "1.3.3",
8788
"glob": "^7.1.3",
88-
"globby": "^10.0.1",
89+
"globby": "10.0.1",
90+
"got": "9.6.0",
8991
"gulp": "^4.0.0",
9092
"gulp-ejs": "^4.1.1",
9193
"gulp-zip": "^5.0.0",
9294
"lodash": "4.17.14",
9395
"merge-stream": "^2.0.0",
9496
"package-json": "^6.0.0",
9597
"semver": "6.2.0",
98+
"xmldom": "0.1.27",
99+
"xpath.js": "1.1.0",
96100
"yeoman-generator": "^4.0.1",
97101
"yo": "^3.1.0"
98102
}

utility/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const { padStart } = require('lodash');
44
const { formatPackageUpgrades } = require('./ui');
55
const { getLibraries, getUpgradeVersions } = require('./packages');
6+
const { validatePackage } = require('./validate');
67

78
/**
89
* Format a version number in the format used by DNN JS library folders
@@ -46,4 +47,5 @@ module.exports = {
4647
formatPackageUpgrades,
4748
getLibraries,
4849
getUpgradeVersions,
50+
validatePackage,
4951
};

utility/validate.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const decompress = require('decompress');
5+
const select = require('xpath.js');
6+
const { DOMParser } = require('xmldom');
7+
const got = require('got');
8+
9+
/**
10+
* Validates a package
11+
*
12+
* @param {String} file - Path to a zip package file
13+
* @returns {Promise<String[]>} Resolves to a list of error messages
14+
*/
15+
async function validatePackage(file) {
16+
const validationMessages = [];
17+
try {
18+
const files = await decompress(file);
19+
const manifestFiles = files.filter(
20+
file => path.extname(file.path) === '.dnn'
21+
);
22+
if (manifestFiles.length > 1) {
23+
return ['Too many .dnn manifest files'];
24+
} else if (manifestFiles.length === 0) {
25+
return ['Missing .dnn manifest file'];
26+
}
27+
28+
const manifestFile = manifestFiles[0];
29+
const manifestContents = manifestFile.data.toString('utf-8');
30+
const parser = new DOMParser();
31+
32+
const doc = parser.parseFromString(manifestContents);
33+
const cdnPathNodes = select(
34+
doc,
35+
'/dotnetnuke/packages/package/components/component/javaScriptLibrary/CDNPath/text()'
36+
);
37+
const cdnResponses = cdnPathNodes
38+
.map(({ data }) => data)
39+
.filter(data => Boolean(data))
40+
.map(url => got.head(url));
41+
for (const response of cdnResponses) {
42+
try {
43+
await response;
44+
} catch (e) {
45+
validationMessages.push('Error checking CDN URL: ' + e);
46+
}
47+
}
48+
49+
return validationMessages;
50+
} catch (e) {
51+
validationMessages.push('Unexpected error: ' + e);
52+
return validationMessages;
53+
}
54+
}
55+
56+
module.exports = {
57+
validatePackage,
58+
};

0 commit comments

Comments
 (0)