From 48a05cd43703c201cc913c9131d2bbace99662c9 Mon Sep 17 00:00:00 2001 From: Jemma Date: Sun, 4 Feb 2024 16:59:58 -0600 Subject: [PATCH] Added permissions for communities. Added additional checks for making new posts and new communities to support this change. Update regex to support more languages. --- src/models/community.ts | 24 ++++++++++++++++++-- src/models/post.ts | 2 +- src/services/api/routes/communities.ts | 26 +++++++++++++++++++++- src/services/api/routes/friend_messages.ts | 2 +- src/services/api/routes/posts.ts | 8 +++---- src/types/mongoose/community.ts | 8 +++++++ 6 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/models/community.ts b/src/models/community.ts index 7ff1a50..284c35a 100644 --- a/src/models/community.ts +++ b/src/models/community.ts @@ -1,6 +1,25 @@ import { Schema, model } from 'mongoose'; import { CommunityData } from '@/types/miiverse/community'; -import { ICommunity, ICommunityMethods, CommunityModel, HydratedCommunityDocument } from '@/types/mongoose/community'; +import { ICommunity, ICommunityMethods, CommunityModel, ICommunityPermissions, HydratedCommunityDocument } from '@/types/mongoose/community'; + +const PermissionsSchema = new Schema({ + open: { + type: Boolean, + default: true + }, + minimum_new_post_access_level: { + type: Number, + default: 0 + }, + minimum_new_comment_access_level: { + type: Number, + default: 0 + }, + minimum_new_community_access_level: { + type: Number, + default: 0 + }, +}); const CommunitySchema = new Schema({ platform_id: Number, @@ -68,7 +87,8 @@ const CommunitySchema = new Schema('addUserFavorite', async function addUserFavorite(pid: number): Promise { diff --git a/src/models/post.ts b/src/models/post.ts index 663918a..618769e 100644 --- a/src/models/post.ts +++ b/src/models/post.ts @@ -107,7 +107,7 @@ PostSchema.method('generatePostUID', async function genera }); PostSchema.method('cleanedBody', function cleanedBody(): string { - return this.body ? this.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}+=,.<>/?;:'"[\]]/g, '').replace(/[\n\r]+/gm, '') : ''; + return this.body ? this.body.replace(/[\p{L}\p{P}\d$^¨←→↑↓√¦⇒⇔¤¢€£¥™©®+×÷=±∞˘˙¸˛˜°¹²³♭♪¬¯¼½¾♡♥●◆■▲▼☆★♀♂<>]/g, '').replace(/[\n\r]+/gm, '') : ''; }); PostSchema.method('cleanedMiiData', function cleanedMiiData(): string { diff --git a/src/services/api/routes/communities.ts b/src/services/api/routes/communities.ts index 3dfc260..40376f2 100644 --- a/src/services/api/routes/communities.ts +++ b/src/services/api/routes/communities.ts @@ -8,10 +8,11 @@ import { getCommunityByTitleID, getUserContent, } from '@/database'; -import { getValueFromQueryString } from '@/util'; +import { getValueFromQueryString, getUserAccountData } from '@/util'; import { LOG_WARN } from '@/logger'; import { Community } from '@/models/community'; import { Post } from '@/models/post'; +import { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; import { HydratedCommunityDocument } from '@/types/mongoose/community'; import { SubCommunityQuery } from '@/types/mongoose/subcommunity-query'; import { CommunityPostsQuery } from '@/types/mongoose/community-posts-query'; @@ -268,6 +269,29 @@ router.post('/', multer().none(), async function (request: express.Request, resp return respondCommunityError(response, 400, 20); } + let pnid: GetUserDataResponse; + + try { + pnid = await getUserAccountData(request.pid); + } catch (error) { + // TODO - Log this error + response.sendStatus(403); + return; + } + + if (pnid.accessLevel < parentCommunity.permissions.minimum_new_community_access_level) { + response.send(xmlbuilder.create({ + result: { + has_error: '1', + version: '1', + code: '403', + error_code: '911', + message: 'NO_NEW_COMMUNITY' + } + }).end({ pretty: true, allowEmpty: true })); + return; + } + request.body.name = request.body.name.trim(); request.body.icon = request.body.icon.trim(); diff --git a/src/services/api/routes/friend_messages.ts b/src/services/api/routes/friend_messages.ts index a41a04c..3c86961 100644 --- a/src/services/api/routes/friend_messages.ts +++ b/src/services/api/routes/friend_messages.ts @@ -160,7 +160,7 @@ router.post('/', upload.none(), async function (request: express.Request, respon } if (messageBody) { - messageBody = messageBody.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}‛¨ƒºª«»“”„¿¡←→↑↓√§¶†‡¦–—⇒⇔¤¢€£¥™©®+×÷=±∞ˇ˘˙¸˛˜′″µ°¹²³♭♪•…¬¯‰¼½¾♡♥●◆■▲▼☆★♀♂,./?;:'"\\<>]/g, ''); + messageBody = messageBody.replace(/[\p{L}\p{P}\d$^¨←→↑↓√¦⇒⇔¤¢€£¥™©®+×÷=±∞˘˙¸˛˜°¹²³♭♪¬¯¼½¾♡♥●◆■▲▼☆★♀♂<>]/g, ''); } if (messageBody.length > 280) { diff --git a/src/services/api/routes/posts.ts b/src/services/api/routes/posts.ts index ede2dfd..b5a4587 100644 --- a/src/services/api/routes/posts.ts +++ b/src/services/api/routes/posts.ts @@ -288,10 +288,10 @@ async function newPost(request: express.Request, response: express.Response): Pr } // TODO - Clean this up - // * Nesting this because of how manu checks there are, extremely unreadable otherwise + // * Nesting this because of how many checks there are, extremely unreadable otherwise if (!(community.admins && community.admins.indexOf(request.pid) !== -1 && userSettings.account_status === 0)) { - if (community.type >= 2) { - if (!(parentPost && community.allows_comments && community.open)) { + if (community.type >= 2 || user.accessLevel < community.permissions.minimum_new_post_access_level) { + if (!(parentPost && user.accessLevel >= community.permissions.minimum_new_comment_access_level && community.permissions.open)) { response.sendStatus(403); return; } @@ -318,7 +318,7 @@ async function newPost(request: express.Request, response: express.Response): Pr } if (messageBody) { - messageBody = messageBody.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}‛¨ƒºª«»“”„¿¡←→↑↓√§¶†‡¦–—⇒⇔¤¢€£¥™©®+×÷=±∞ˇ˘˙¸˛˜′″µ°¹²³♭♪•…¬¯‰¼½¾♡♥●◆■▲▼☆★♀♂,./?;:'"\\<>]/g, ''); + messageBody = messageBody.replace(/[\p{L}\p{P}\d$^¨←→↑↓√¦⇒⇔¤¢€£¥™©®+×÷=±∞˘˙¸˛˜°¹²³♭♪¬¯¼½¾♡♥●◆■▲▼☆★♀♂<>]/g, ''); } if (messageBody && messageBody.length > 280) { diff --git a/src/types/mongoose/community.ts b/src/types/mongoose/community.ts index 03f066c..bd4b446 100644 --- a/src/types/mongoose/community.ts +++ b/src/types/mongoose/community.ts @@ -8,6 +8,13 @@ enum COMMUNITY_TYPE { Private = 3 } +export interface ICommunityPermissions { + open: boolean; + minimum_new_post_access_level: number; + minimum_new_comment_access_level: number; + minimum_new_community_access_level: number; +} + export interface ICommunity { platform_id: number; name: string; @@ -30,6 +37,7 @@ export interface ICommunity { is_recommended: number; app_data: string; user_favorites: Types.Array; + permissions: ICommunityPermissions } export interface ICommunityMethods {