Skip to content
Open
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
118 changes: 85 additions & 33 deletions src/controllers/composer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,59 +39,111 @@ exports.get = async function (req, res, callback) {
}
};

exports.post = async function (req, res) {
const { body } = req;
const data = {
// Helpers to reduce complexity
// Used ChatGPT to name all the helpers
//Split into 7 helpers

function invalidDataError() {
return new Error('[[error:invalid-data]]');
}

function buildBaseData(req, body) {
const base = {
uid: req.uid,
req: req,
timestamp: Date.now(),
content: body.content,
handle: body.handle,
fromQueue: false,
};

req.body.noscript = 'true';
return base;
}

function ensureContent(data) {
if (!data.content) {
return helpers.noScriptErrors(req, res, '[[error:invalid-data]]', 400);
throw invalidDataError();
}
async function queueOrPost(postFn, data) {
const shouldQueue = await posts.shouldQueue(req.uid, data);
if (shouldQueue) {
delete data.req;
return await posts.addToQueue(data);
}
return await postFn(data);
}

function decideAction(body) {
if (body.tid) {
return 'reply';
}
if (body.cid) {
return 'topic';
}
throw invalidDataError();
}

function enrichForAction(data, body, action) {
if (action === 'reply') {
data.tid = body.tid;
return;
}

data.cid = body.cid;
data.title = body.title;
data.tags = [];
data.thumb = '';
}

async function queueOrPost(uid, postFn, data) {
const shouldQueue = await posts.shouldQueue(uid, data);
if (shouldQueue) {
delete data.req;
return posts.addToQueue(data);
}
return postFn(data);
}

async function performPost(action, uid, data) {
const map = {
reply: topics.reply,
topic: topics.post,
};
const postFn = map[action];
return queueOrPost(uid, postFn, data);
}

//Used help of CoPilot/ChatGPT for body of conditionals
function computeRedirectPath(result) {
let path = nconf.get('relative_path');
if (result.pid) {
path += `/post/${result.pid}`;
} else if (result.topicData) {
path += `/topic/${result.topicData.slug}`;
}
return path;
}

exports.post = async function (req, res) {
try {
let result;
if (body.tid) {
data.tid = body.tid;
result = await queueOrPost(topics.reply, data);
} else if (body.cid) {
data.cid = body.cid;
data.title = body.title;
data.tags = [];
data.thumb = '';
result = await queueOrPost(topics.post, data);
} else {
throw new Error('[[error:invalid-data]]');
}
const { body } = req;

const data = buildBaseData(req, body);
ensureContent(data);

const action = decideAction(body);
enrichForAction(data, body, action);

console.log('JORDAN_BAIN');

const result = await performPost(action, req.uid, data);
if (!result) {
throw new Error('[[error:invalid-data]]');
throw invalidDataError();
}

if (result.queued) {
return res.redirect(`${nconf.get('relative_path') || '/'}?noScriptMessage=[[success:post-queued]]`);
}


user.updateOnlineUsers(req.uid);
let path = nconf.get('relative_path');
if (result.pid) {
path += `/post/${result.pid}`;
} else if (result.topicData) {
path += `/topic/${result.topicData.slug}`;
}
res.redirect(path);
const path = computeRedirectPath(result);
return res.redirect(path);
} catch (err) {
helpers.noScriptErrors(req, res, err.message, 400);
return helpers.noScriptErrors(req, res, err.message, 400);
}
};
78 changes: 49 additions & 29 deletions src/user/search.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

'use strict';

const _ = require('lodash');
Expand All @@ -25,7 +24,6 @@ module.exports = function (User) {
unverified: ['email:confirmed'],
};


User.search = async function (data) {
const query = data.query || '';
const searchBy = data.searchBy || 'username';
Expand Down Expand Up @@ -123,7 +121,6 @@ module.exports = function (User) {
hardCap = hardCap || resultsPerPage * 10;

const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, hardCap);
// const uids = data.map(data => data.split(':').pop());
const uids = data.map((data) => {
if (data.includes(':https:')) {
return data.substring(data.indexOf(':https:') + 1);
Expand All @@ -134,45 +131,68 @@ module.exports = function (User) {
return uids;
}

async function filterAndSortUids(uids, data) {
uids = uids.filter(uid => parseInt(uid, 10) || activitypub.helpers.isUri(uid));
let filters = data.filters || [];
filters = Array.isArray(filters) ? filters : [data.filters];
//helpers to reduce complexity
//Used ChatGPT to name all my help functions
function normalizeFilters(filters) {
const list = filters || [];
return Array.isArray(list) ? list : [list];
}

function collectFields(sortBy, filters) {
const fields = [];
if (sortBy) fields.push(sortBy);
filters.forEach((f) => {
if (filterFieldMap[f]) {
fields.push(...filterFieldMap[f]);
}
});
return fields;
}

if (data.sortBy) {
fields.push(data.sortBy);
}
async function applyGroupFilter(uids, groupName) {
if (!groupName) return uids;
const isMembers = await groups.isMembers(uids, groupName);
return uids.filter((uid, i) => isMembers[i]);
}

filters.forEach((filter) => {
if (filterFieldMap[filter]) {
fields.push(...filterFieldMap[filter]);
async function maybeApplyBannedFilter(uids, filters) {
const wantsBanned = filters.includes('banned') || filters.includes('notbanned');
if (!wantsBanned) return uids;

const isMembersOfBanned = await groups.isMembers(uids, groups.BANNED_USERS);
const checkBanned = filters.includes('banned');
return uids.filter((uid, i) => (checkBanned ? isMembersOfBanned[i] : !isMembersOfBanned[i]));
}

function applyFilterFns(userData, filters) {
let result = userData;
filters.forEach((f) => {
if (filterFnMap[f]) {
result = result.filter(filterFnMap[f]);
}
});
return result;
}

if (data.groupName) {
const isMembers = await groups.isMembers(uids, data.groupName);
uids = uids.filter((uid, index) => isMembers[index]);
}
// function with helper methods included
async function filterAndSortUids(uids, data) {
let filteredUids = uids.filter(uid => parseInt(uid, 10) || activitypub.helpers.isUri(uid));

const filters = normalizeFilters(data.filters);
const fields = collectFields(data.sortBy, filters);

filteredUids = await applyGroupFilter(filteredUids, data.groupName);

if (!fields.length) {
return uids;
return filteredUids;
}

if (filters.includes('banned') || filters.includes('notbanned')) {
const isMembersOfBanned = await groups.isMembers(uids, groups.BANNED_USERS);
const checkBanned = filters.includes('banned');
uids = uids.filter((uid, index) => (checkBanned ? isMembersOfBanned[index] : !isMembersOfBanned[index]));
}
filteredUids = await maybeApplyBannedFilter(filteredUids, filters);

fields.push('uid');
let userData = await User.getUsersFields(uids, fields);
let userData = await User.getUsersFields(filteredUids, fields);

filters.forEach((filter) => {
if (filterFnMap[filter]) {
userData = userData.filter(filterFnMap[filter]);
}
});
userData = applyFilterFns(userData, filters);

if (data.sortBy) {
sortUsers(userData, data.sortBy, data.sortDirection);
Expand Down