Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CT-3569] Sanitize HTML from examples code and fix errors #477

Merged
merged 4 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 45 additions & 35 deletions api/models/Topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

var _ = require('lodash');
var Promise = require('bluebird');
var sanitizeHtml = require('sanitize-html');

module.exports = {

Expand All @@ -22,39 +23,39 @@ module.exports = {
},

description: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

usage: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

details: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

value: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

references: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

note: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

author: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

seealso: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

examples: {
type: Sequelize.TEXT,
type: Sequelize.TEXT
},

sourceJSON: {
Expand All @@ -65,7 +66,6 @@ module.exports = {

},
associations: function() {

Topic.belongsTo(PackageVersion,
{
as: 'package_version',
Expand Down Expand Up @@ -115,7 +115,7 @@ module.exports = {
.replace(':version', encodeURIComponent(this.package_version.version))
.replace(':topic', encodeURIComponent(this.name))
.replace('/api/', '/');
} else return sails.getUrlFor({ target: 'Topic.findById' })
} return sails.getUrlFor({ target: 'Topic.findById' })
.replace(':id', encodeURIComponent(this.id))
.replace('/api/', '/');
},
Expand All @@ -125,9 +125,9 @@ module.exports = {
.replace(':name', encodeURIComponent(this.package_version.package_name))
.replace(':version', encodeURIComponent(this.package_version.version))
.replace(':topic', encodeURIComponent(this.name));
} else return sails.getUrlFor({ target: 'Topic.findById' })
} return sails.getUrlFor({ target: 'Topic.findById' })
.replace(':id', encodeURIComponent(this.id));
},
}
},

classMethods: {
Expand All @@ -140,8 +140,8 @@ module.exports = {
var options = _.mergeWith({
where: criteria,
include: [
{model: Argument, as: 'arguments', attributes: ['name', 'description', 'topic_id'], separate:true },
{model: Section, as: 'sections', attributes: ['name', 'description', 'topic_id'], separate:true },
{model: Argument, as: 'arguments', attributes: ['name', 'description', 'topic_id'], separate: true },
{model: Section, as: 'sections', attributes: ['name', 'description', 'topic_id'], separate: true },
{model: Tag, as: 'keywords', attributes: ['name']},
{model: Alias, as: 'aliases', attributes: ['name', 'topic_id'], separate: true },
{model: Example, as: 'user_examples',
Expand All @@ -162,23 +162,24 @@ module.exports = {
package_name: packageName
};

if(version) { //if version is specified, find in this one
if (version) { // if version is specified, find in this one
packageCriteria.version = version;
}

var params = {
where: { name: name },
include: [
{ model: PackageVersion, as: 'package_version', attributes: ['package_name', 'version'], where: packageCriteria }
],
]
};

return Promise.join(
Topic.findAll(params),
Topic.findByAliasInPackage(packageName, name, version),
function(topics, aliasesTopics) {
return topics.concat(aliasesTopics).sort(PackageService.compareVersions('desc', function(topic) {
return topic.package_version.version })
return topic.package_version.version;
})
)[0];
});
},
Expand All @@ -188,7 +189,7 @@ module.exports = {
package_name: packageName
};

if(version) { //if version is specified, find in this one
if (version) { // if version is specified, find in this one
packageCriteria.version = version;
}

Expand All @@ -200,16 +201,19 @@ module.exports = {
};

return Topic.findAll(params).then(function(topicInstances) {
if(topicInstances) return topicInstances.sort(PackageService.compareVersions('desc', function(topic) {
return topic.package_version.version })
if (topicInstances) {
return topicInstances.sort(PackageService.compareVersions('desc', function(topic) {
return topic.package_version.version;
})
)[0];
else return topicInstances;
}
return topicInstances;
});
},

createWithRdFile: function(opts) {
var rdJSON = opts.input;
return sequelize.transaction(function (t) {
return sequelize.transaction(function(t) {
var attributes = [
'name',
'title',
Expand All @@ -225,11 +229,20 @@ module.exports = {

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

if (topic.usage !== null && typeof topic.usage === 'object') {
topic.usage = topic.usage.contents;
}

topic.examples = sanitizeHtml(topic.examples, {
allowedTags: ['a' ],
allowedAttributes: {}
});

var arrayToString = function(val) {
if (val instanceof Array) {
if(_.isEmpty(val)) return "";
else return val.join("\n\n");
} else return val;
if (_.isEmpty(val)) return '';
return val.join('\n\n');
} return val;
};

topic = _.mapValues(topic, arrayToString);
Expand All @@ -245,14 +258,13 @@ module.exports = {
var packageVersion = {
package_name: opts.packageName,
version: opts.packageVersion,
description: "",
license: ""
description: '',
license: ''
};

return PackageVersion.upsertPackageVersion(packageVersion, {
transaction: t
}).spread(function(version, created) {

topic.package_version_id = version.id;


Expand Down Expand Up @@ -281,12 +293,12 @@ module.exports = {
{model: Alias, as: 'aliases'}
]
}),
Tag.bulkCreate(keywordsRecords, {transaction:t, ignoreDuplicates: true})
Tag.bulkCreate(keywordsRecords, {transaction: t, ignoreDuplicates: true})
.then(function(instances) {
var names = _.map(instances, function (inst) {
var names = _.map(instances, function(inst) {
return inst.name;
});
return Tag.findAll({where: {name: {$in: names}}, transaction:t });
return Tag.findAll({where: {name: {$in: names}}, transaction: t });
}),
function(instanceCreatedArray, keywordsInstances) {
var topicInstance = instanceCreatedArray[0];
Expand Down Expand Up @@ -329,11 +341,9 @@ module.exports = {
topicInstance.setKeywords(keywordsInstances, {transaction: t }),
topicInstance.save({transaction: t})
]).then(_.partial(Topic.findOnePopulated, {id: topicInstance.id}, {transaction: t}));
});
});
});

});

}
}
}
Expand Down
13 changes: 8 additions & 5 deletions api/services/TopicService.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ module.exports = {
let basePath = '/link/';
if(!relative)
basePath = 'https:' + process.env.BASE_URL + basePath;

$('a').each(function(i, elem) {
var current = $(elem).attr('href');
var topicName = $(elem).text();
var rdOptions = $(elem).attr('rd-options');
if(!current) return;
var absolutePattern = /^https?:\/\//i;
if (absolutePattern.test(current)) return;
var rdrrPattern = /rdrr.io/i;
if (absolutePattern.test(current) && !rdrrPattern.test(current)) return;
if (rdOptions === '' || !rdOptions) {
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(current)) +
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(topicName)) +
'?package=' + encodeURIComponent(packageVersion.package_name) +
'\&version=' + encodeURIComponent(packageVersion.version));
$(elem).attr('data-mini-rdoc', `${packageVersion.package_name}::${current}`);
$(elem).attr('data-mini-rdoc', `${packageVersion.package_name}::${topicName}`);
} else {
if (rdOptions.split(':') > 1) {
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(rdOptions[1])) +
Expand All @@ -28,11 +31,11 @@ module.exports = {
'\&to=' + encodeURIComponent(rdOptions[0]));
$(elem).attr('data-mini-rdoc', `${rdOptions[0]}::${rdOptions[1]}`);
} else {
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(current)) +
$(elem).attr('href', url.resolve(basePath, encodeURIComponent(topicName)) +
'?package=' + encodeURIComponent(packageVersion.package_name) +
'\&version=' + encodeURIComponent(packageVersion.version) +
'\&to=' + encodeURIComponent(rdOptions));
$(elem).attr('data-mini-rdoc', `${rdOptions}::${current}`);
$(elem).attr('data-mini-rdoc', `${rdOptions}::${topicName}`);
}
}

Expand Down
Loading