Skip to content

Commit

Permalink
Merge branch 'f24' into task3/db-anonymous-name-change
Browse files Browse the repository at this point in the history
  • Loading branch information
jdufitum authored Sep 26, 2024
2 parents 4c0e182 + 10b9daf commit f255236
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 82 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
yarn.lock
npm-debug.log


sftp-config.json
config.json
jsconfig.json
Expand Down
Binary file added dump.rdb
Binary file not shown.
6 changes: 5 additions & 1 deletion public/language/en-GB/topic.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@
"composer.replying-to": "Replying to %1",
"composer.new-topic": "New Topic",
"composer.editing-in": "Editing post in %1",

"composer-anonymous-none": "None",
"composer-anonymous-student": "Student",
"composer-anonymous-all": "Everyone",
"composer.select-anonymous-type": "Annonymous type",

"composer.uploading": "uploading...",
"composer.thumb-url-label": "Paste a topic thumbnail URL",
"composer.thumb-title": "Add a thumbnail to this topic",
Expand Down
25 changes: 15 additions & 10 deletions src/flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,49 +273,54 @@ Flags.sort = async function (flagIds, sort) {
return flagIds;
};

// Chatgpt Assisted Code
Flags.validate = async function (payload) {
console.log('Salman Al-Saigh');
const [target, reporter] = await Promise.all([
Flags.getTarget(payload.type, payload.id, payload.uid),
user.getUserData(payload.uid),
]);

if (!target) {
throw new Error('[[error:invalid-data]]');
} else if (target.deleted) {
}
if (target.deleted) {
throw new Error('[[error:post-deleted]]');
} else if (!reporter || !reporter.userslug) {
}
if (!reporter || !reporter.userslug) {
throw new Error('[[error:no-user]]');
} else if (reporter.banned) {
}
if (reporter.banned) {
throw new Error('[[error:user-banned]]');
}

// Disallow flagging of profiles/content of privileged users
const [targetPrivileged, reporterPrivileged] = await Promise.all([
user.isPrivileged(target.uid),
user.isPrivileged(reporter.uid),
]);
if (targetPrivileged && !reporterPrivileged) {
throw new Error('[[error:cant-flag-privileged]]');
}

if (payload.type === 'post') {
const editable = await privileges.posts.canEdit(payload.id, payload.uid);
if (!editable.flag && !meta.config['reputation:disabled'] && reporter.reputation < meta.config['min:rep:flag']) {
throw new Error(`[[error:not-enough-reputation-to-flag, ${meta.config['min:rep:flag']}]]`);
}
} else if (payload.type === 'user') {
return;
}
if (payload.type === 'user') {
if (parseInt(payload.id, 10) === parseInt(payload.uid, 10)) {
throw new Error('[[error:cant-flag-self]]');
}
const editable = await privileges.users.canEdit(payload.uid, payload.id);
if (!editable && !meta.config['reputation:disabled'] && reporter.reputation < meta.config['min:rep:flag']) {
throw new Error(`[[error:not-enough-reputation-to-flag, ${meta.config['min:rep:flag']}]]`);
}
} else {
throw new Error('[[error:invalid-data]]');
return;
}
throw new Error('[[error:invalid-data]]');
};



Flags.getNotes = async function (flagId) {
let notes = await db.getSortedSetRevRangeWithScores(`flag:${flagId}:notes`, 0, -1);
notes = await modifyNotes(notes);
Expand Down
123 changes: 56 additions & 67 deletions src/meta/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,11 @@ const url = nconf.get('url');
const relative_path = nconf.get('relative_path');
const upload_url = nconf.get('upload_url');

console.log('Deema');
Tags.parse = async (req, data, meta, link) => {
const isAPI = req.res && req.res.locals && req.res.locals.isAPI;

// Meta tags
const defaultTags = isAPI ? [] : [{
name: 'viewport',
content: 'width=device-width, initial-scale=1.0',
}, {
name: 'content-type',
content: 'text/html; charset=UTF-8',
noEscape: true,
}, {
name: 'apple-mobile-web-app-capable',
content: 'yes',
}, {
name: 'mobile-web-app-capable',
content: 'yes',
}, {
property: 'og:site_name',
content: Meta.config.title || 'NodeBB',
}, {
name: 'msapplication-badge',
content: `frequency=30; polling-uri=${url}/sitemap.xml`,
noEscape: true,
}, {
name: 'theme-color',
content: Meta.config.themeColor || '#ffffff',
}];
const defaultTags = getDefaultTags(isAPI);
const defaultLinks = getDefaultLinks(isAPI);

if (Meta.config.keywords && !isAPI) {
defaultTags.push({
Expand All @@ -57,19 +34,9 @@ Tags.parse = async (req, data, meta, link) => {
});
}

const faviconPath = `${relative_path}/assets/uploads/system/favicon.ico`;
const cacheBuster = `${Meta.config['cache-buster'] ? `?${Meta.config['cache-buster']}` : ''}`;

// Link Tags
const defaultLinks = isAPI ? [] : [{
rel: 'icon',
type: 'image/x-icon',
href: `${faviconPath}${cacheBuster}`,
}, {
rel: 'manifest',
href: `${relative_path}/manifest.webmanifest`,
crossorigin: `use-credentials`,
}];
if (!isAPI) {
addTouchIcons(defaultLinks);
}

if (plugins.hooks.hasListeners('filter:search.query') && !isAPI) {
defaultLinks.push({
Expand All @@ -80,57 +47,79 @@ Tags.parse = async (req, data, meta, link) => {
});
}

if (!isAPI) {
addTouchIcons(defaultLinks);
}
const results = await getMetaAndLinks(req, data, defaultTags, defaultLinks);
meta = processMetaTags(results.tags.tags.concat(meta || []));
link = processLinkTags(results.links.links.concat(link || []), isAPI);

await addSiteOGImage(meta);

addIfNotExists(meta, 'property', 'og:title', Meta.config.title || 'NodeBB');
addIfNotExists(meta, 'property', 'og:url', url + (req.originalUrl !== '/' ? stripRelativePath(req.originalUrl) : ''));
addIfNotExists(meta, 'name', 'description', Meta.config.description);
addIfNotExists(meta, 'property', 'og:description', Meta.config.description);

return { meta, link };
};

function getDefaultTags(isAPI) {
if (isAPI) return [];
return [
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
{ name: 'content-type', content: 'text/html; charset=UTF-8', noEscape: true },
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
{ name: 'mobile-web-app-capable', content: 'yes' },
{ property: 'og:site_name', content: Meta.config.title || 'NodeBB' },
{ name: 'msapplication-badge', content: `frequency=30; polling-uri=${url}/sitemap.xml`, noEscape: true },
{ name: 'theme-color', content: Meta.config.themeColor || '#ffffff' },
];
}

const results = await utils.promiseParallel({
tags: plugins.hooks.fire('filter:meta.getMetaTags', { req: req, data: data, tags: defaultTags }),
links: plugins.hooks.fire('filter:meta.getLinkTags', { req: req, data: data, links: defaultLinks }),
function getDefaultLinks(isAPI) {
const faviconPath = `${relative_path}/assets/uploads/system/favicon.ico`;
const cacheBuster = Meta.config['cache-buster'] ? `?${Meta.config['cache-buster']}` : '';
if (isAPI) return [];
return [
{ rel: 'icon', type: 'image/x-icon', href: `${faviconPath}${cacheBuster}` },
{ rel: 'manifest', href: `${relative_path}/manifest.webmanifest`, crossorigin: 'use-credentials' },
];
}

async function getMetaAndLinks(req, data, defaultTags, defaultLinks) {
return utils.promiseParallel({
tags: plugins.hooks.fire('filter:meta.getMetaTags', { req, data, tags: defaultTags }),
links: plugins.hooks.fire('filter:meta.getLinkTags', { req, data, links: defaultLinks }),
});
}

meta = results.tags.tags.concat(meta || []).map((tag) => {
function processMetaTags(tags) {
return tags.map((tag) => {
if (!tag || typeof tag.content !== 'string') {
winston.warn('Invalid meta tag. ', tag);
return tag;
}

if (!tag.noEscape) {
const attributes = Object.keys(tag);
attributes.forEach((attr) => {
Object.keys(tag).forEach((attr) => {
tag[attr] = utils.escapeHTML(String(tag[attr]));
});
}

return tag;
});
}

await addSiteOGImage(meta);

addIfNotExists(meta, 'property', 'og:title', Meta.config.title || 'NodeBB');
const ogUrl = url + (req.originalUrl !== '/' ? stripRelativePath(req.originalUrl) : '');
addIfNotExists(meta, 'property', 'og:url', ogUrl);
addIfNotExists(meta, 'name', 'description', Meta.config.description);
addIfNotExists(meta, 'property', 'og:description', Meta.config.description);

link = results.links.links.concat(link || []);
function processLinkTags(links, isAPI) {
if (isAPI) {
const whitelist = ['canonical', 'alternate', 'up'];
link = link.filter(link => whitelist.some(val => val === link.rel));
links = links.filter(link => whitelist.includes(link.rel));
}
link = link.map((tag) => {
return links.map((tag) => {
if (!tag.noEscape) {
const attributes = Object.keys(tag);
attributes.forEach((attr) => {
Object.keys(tag).forEach((attr) => {
tag[attr] = utils.escapeHTML(String(tag[attr]));
});
}

return tag;
});

return { meta, link };
};
}

function addTouchIcons(defaultLinks) {
if (Meta.config['brand:touchIcon']) {
Expand Down
2 changes: 2 additions & 0 deletions src/posts/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = function (Posts) {
const content = data.content.toString();
const timestamp = data.timestamp || Date.now();
const isMain = data.isMain || false;
const { annonymousType } = data;

if (!uid && parseInt(uid, 10) !== 0) {
throw new Error('[[error:invalid-uid]]');
Expand All @@ -35,6 +36,7 @@ module.exports = function (Posts) {
tid: tid,
content: content,
timestamp: timestamp,
annonymousType: annonymousType,
};

if (data.toPid) {
Expand Down
26 changes: 22 additions & 4 deletions src/topics/unread.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,29 @@ module.exports = function (Topics) {
const filterCids = params.cid && params.cid.map(cid => parseInt(cid, 10));
const filterTags = params.tag && params.tag.map(tag => String(tag));

function areTagsAllowed(topic, filterTags) {
if (!filterTags) {
return true;
}
for (const tag of filterTags) {
if (!topic.tags.find(topicTag => topicTag.value === tag)) {
return false;
}
}
return true;
}

function shouldIncludeTopic(topic, filterCids, filterTags, blockedUids) {
if (!topic || !topic.cid || blockedUids.includes(topic.uid)) {
return false;
}
if (filterCids && !filterCids.includes(topic.cid)) {
return false;
}
return areTagsAllowed(topic, filterTags);
}
topicData.forEach((topic) => {
if (topic && topic.cid &&
(!filterCids || filterCids.includes(topic.cid)) &&
(!filterTags || filterTags.every(tag => topic.tags.find(topicTag => topicTag.value === tag))) &&
!blockedUids.includes(topic.uid)) {
if (shouldIncludeTopic(topic, filterCids, filterTags, blockedUids)) {
if (isTopicsFollowed[topic.tid] ||
[categories.watchStates.watching, categories.watchStates.tracking].includes(userCidState[topic.cid])) {
tidsByFilter[''].push(topic.tid);
Expand Down

0 comments on commit f255236

Please sign in to comment.