Skip to content

Commit 36592cc

Browse files
authored
Merge pull request #477 from datacamp/fix/queue-parsing
[CT-3569] Sanitize HTML from examples code and fix errors
2 parents aa71a42 + 0fffa7f commit 36592cc

File tree

4 files changed

+17945
-2176
lines changed

4 files changed

+17945
-2176
lines changed

api/models/Topic.js

+45-35
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
var _ = require('lodash');
99
var Promise = require('bluebird');
10+
var sanitizeHtml = require('sanitize-html');
1011

1112
module.exports = {
1213

@@ -22,39 +23,39 @@ module.exports = {
2223
},
2324

2425
description: {
25-
type: Sequelize.TEXT,
26+
type: Sequelize.TEXT
2627
},
2728

2829
usage: {
29-
type: Sequelize.TEXT,
30+
type: Sequelize.TEXT
3031
},
3132

3233
details: {
33-
type: Sequelize.TEXT,
34+
type: Sequelize.TEXT
3435
},
3536

3637
value: {
37-
type: Sequelize.TEXT,
38+
type: Sequelize.TEXT
3839
},
3940

4041
references: {
41-
type: Sequelize.TEXT,
42+
type: Sequelize.TEXT
4243
},
4344

4445
note: {
45-
type: Sequelize.TEXT,
46+
type: Sequelize.TEXT
4647
},
4748

4849
author: {
49-
type: Sequelize.TEXT,
50+
type: Sequelize.TEXT
5051
},
5152

5253
seealso: {
53-
type: Sequelize.TEXT,
54+
type: Sequelize.TEXT
5455
},
5556

5657
examples: {
57-
type: Sequelize.TEXT,
58+
type: Sequelize.TEXT
5859
},
5960

6061
sourceJSON: {
@@ -65,7 +66,6 @@ module.exports = {
6566

6667
},
6768
associations: function() {
68-
6969
Topic.belongsTo(PackageVersion,
7070
{
7171
as: 'package_version',
@@ -115,7 +115,7 @@ module.exports = {
115115
.replace(':version', encodeURIComponent(this.package_version.version))
116116
.replace(':topic', encodeURIComponent(this.name))
117117
.replace('/api/', '/');
118-
} else return sails.getUrlFor({ target: 'Topic.findById' })
118+
} return sails.getUrlFor({ target: 'Topic.findById' })
119119
.replace(':id', encodeURIComponent(this.id))
120120
.replace('/api/', '/');
121121
},
@@ -125,9 +125,9 @@ module.exports = {
125125
.replace(':name', encodeURIComponent(this.package_version.package_name))
126126
.replace(':version', encodeURIComponent(this.package_version.version))
127127
.replace(':topic', encodeURIComponent(this.name));
128-
} else return sails.getUrlFor({ target: 'Topic.findById' })
128+
} return sails.getUrlFor({ target: 'Topic.findById' })
129129
.replace(':id', encodeURIComponent(this.id));
130-
},
130+
}
131131
},
132132

133133
classMethods: {
@@ -140,8 +140,8 @@ module.exports = {
140140
var options = _.mergeWith({
141141
where: criteria,
142142
include: [
143-
{model: Argument, as: 'arguments', attributes: ['name', 'description', 'topic_id'], separate:true },
144-
{model: Section, as: 'sections', attributes: ['name', 'description', 'topic_id'], separate:true },
143+
{model: Argument, as: 'arguments', attributes: ['name', 'description', 'topic_id'], separate: true },
144+
{model: Section, as: 'sections', attributes: ['name', 'description', 'topic_id'], separate: true },
145145
{model: Tag, as: 'keywords', attributes: ['name']},
146146
{model: Alias, as: 'aliases', attributes: ['name', 'topic_id'], separate: true },
147147
{model: Example, as: 'user_examples',
@@ -162,23 +162,24 @@ module.exports = {
162162
package_name: packageName
163163
};
164164

165-
if(version) { //if version is specified, find in this one
165+
if (version) { // if version is specified, find in this one
166166
packageCriteria.version = version;
167167
}
168168

169169
var params = {
170170
where: { name: name },
171171
include: [
172172
{ model: PackageVersion, as: 'package_version', attributes: ['package_name', 'version'], where: packageCriteria }
173-
],
173+
]
174174
};
175175

176176
return Promise.join(
177177
Topic.findAll(params),
178178
Topic.findByAliasInPackage(packageName, name, version),
179179
function(topics, aliasesTopics) {
180180
return topics.concat(aliasesTopics).sort(PackageService.compareVersions('desc', function(topic) {
181-
return topic.package_version.version })
181+
return topic.package_version.version;
182+
})
182183
)[0];
183184
});
184185
},
@@ -188,7 +189,7 @@ module.exports = {
188189
package_name: packageName
189190
};
190191

191-
if(version) { //if version is specified, find in this one
192+
if (version) { // if version is specified, find in this one
192193
packageCriteria.version = version;
193194
}
194195

@@ -200,16 +201,19 @@ module.exports = {
200201
};
201202

202203
return Topic.findAll(params).then(function(topicInstances) {
203-
if(topicInstances) return topicInstances.sort(PackageService.compareVersions('desc', function(topic) {
204-
return topic.package_version.version })
204+
if (topicInstances) {
205+
return topicInstances.sort(PackageService.compareVersions('desc', function(topic) {
206+
return topic.package_version.version;
207+
})
205208
)[0];
206-
else return topicInstances;
209+
}
210+
return topicInstances;
207211
});
208212
},
209213

210214
createWithRdFile: function(opts) {
211215
var rdJSON = opts.input;
212-
return sequelize.transaction(function (t) {
216+
return sequelize.transaction(function(t) {
213217
var attributes = [
214218
'name',
215219
'title',
@@ -225,11 +229,20 @@ module.exports = {
225229

226230
var topic = _.pick(rdJSON, attributes);
227231

232+
if (topic.usage !== null && typeof topic.usage === 'object') {
233+
topic.usage = topic.usage.contents;
234+
}
235+
236+
topic.examples = sanitizeHtml(topic.examples, {
237+
allowedTags: ['a' ],
238+
allowedAttributes: {}
239+
});
240+
228241
var arrayToString = function(val) {
229242
if (val instanceof Array) {
230-
if(_.isEmpty(val)) return "";
231-
else return val.join("\n\n");
232-
} else return val;
243+
if (_.isEmpty(val)) return '';
244+
return val.join('\n\n');
245+
} return val;
233246
};
234247

235248
topic = _.mapValues(topic, arrayToString);
@@ -245,14 +258,13 @@ module.exports = {
245258
var packageVersion = {
246259
package_name: opts.packageName,
247260
version: opts.packageVersion,
248-
description: "",
249-
license: ""
261+
description: '',
262+
license: ''
250263
};
251264

252265
return PackageVersion.upsertPackageVersion(packageVersion, {
253266
transaction: t
254267
}).spread(function(version, created) {
255-
256268
topic.package_version_id = version.id;
257269

258270

@@ -281,12 +293,12 @@ module.exports = {
281293
{model: Alias, as: 'aliases'}
282294
]
283295
}),
284-
Tag.bulkCreate(keywordsRecords, {transaction:t, ignoreDuplicates: true})
296+
Tag.bulkCreate(keywordsRecords, {transaction: t, ignoreDuplicates: true})
285297
.then(function(instances) {
286-
var names = _.map(instances, function (inst) {
298+
var names = _.map(instances, function(inst) {
287299
return inst.name;
288300
});
289-
return Tag.findAll({where: {name: {$in: names}}, transaction:t });
301+
return Tag.findAll({where: {name: {$in: names}}, transaction: t });
290302
}),
291303
function(instanceCreatedArray, keywordsInstances) {
292304
var topicInstance = instanceCreatedArray[0];
@@ -329,11 +341,9 @@ module.exports = {
329341
topicInstance.setKeywords(keywordsInstances, {transaction: t }),
330342
topicInstance.save({transaction: t})
331343
]).then(_.partial(Topic.findOnePopulated, {id: topicInstance.id}, {transaction: t}));
332-
});
344+
});
333345
});
334-
335346
});
336-
337347
}
338348
}
339349
}

api/services/TopicService.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ module.exports = {
99
let basePath = '/link/';
1010
if(!relative)
1111
basePath = 'https:' + process.env.BASE_URL + basePath;
12+
1213
$('a').each(function(i, elem) {
1314
var current = $(elem).attr('href');
15+
var topicName = $(elem).text();
1416
var rdOptions = $(elem).attr('rd-options');
1517
if(!current) return;
1618
var absolutePattern = /^https?:\/\//i;
17-
if (absolutePattern.test(current)) return;
19+
var rdrrPattern = /rdrr.io/i;
20+
if (absolutePattern.test(current) && !rdrrPattern.test(current)) return;
1821
if (rdOptions === '' || !rdOptions) {
19-
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(current)) +
22+
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(topicName)) +
2023
'?package=' + encodeURIComponent(packageVersion.package_name) +
2124
'\&version=' + encodeURIComponent(packageVersion.version));
22-
$(elem).attr('data-mini-rdoc', `${packageVersion.package_name}::${current}`);
25+
$(elem).attr('data-mini-rdoc', `${packageVersion.package_name}::${topicName}`);
2326
} else {
2427
if (rdOptions.split(':') > 1) {
2528
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(rdOptions[1])) +
@@ -28,11 +31,11 @@ module.exports = {
2831
'\&to=' + encodeURIComponent(rdOptions[0]));
2932
$(elem).attr('data-mini-rdoc', `${rdOptions[0]}::${rdOptions[1]}`);
3033
} else {
31-
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(current)) +
34+
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(topicName)) +
3235
'?package=' + encodeURIComponent(packageVersion.package_name) +
3336
'\&version=' + encodeURIComponent(packageVersion.version) +
3437
'\&to=' + encodeURIComponent(rdOptions));
35-
$(elem).attr('data-mini-rdoc', `${rdOptions}::${current}`);
38+
$(elem).attr('data-mini-rdoc', `${rdOptions}::${topicName}`);
3639
}
3740
}
3841

0 commit comments

Comments
 (0)