diff --git a/.gitignore b/.gitignore
index c45bd74c..ee711ed1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,7 +20,7 @@
/static/img-local
/static/docs-local
-sus.txt
+moderation/*
# Created by .ignore support plugin (hsz.mobi)
### Node template
diff --git a/Makefile b/Makefile
index dfd8a97a..06217af9 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ KEYS_DIR=./keys
install:
-cp -n .env.dist .env
if [ ! -d "${KEYS_DIR}" ]; then mkdir -p ${KEYS_DIR}; openssl genrsa -out ${KEYS_DIR}/private.pem 2048; openssl rsa -in ${KEYS_DIR}/private.pem -outform PEM -pubout -out ${KEYS_DIR}/public.pem; fi
- touch sus.txt
+ touch moderation/sus.txt moderation/rules-users.md moderation/rules-terminology.md moderation/rules-sources.md
yarn
node server/migrate.js
diff --git a/components/AbuseReports.vue b/components/AbuseReports.vue
new file mode 100644
index 00000000..da96737e
--- /dev/null
+++ b/components/AbuseReports.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
diff --git a/components/Ban.vue b/components/Ban.vue
index 6a24def7..96d4e4d9 100644
--- a/components/Ban.vue
+++ b/components/Ban.vue
@@ -47,6 +47,8 @@
ban.action
+
+
@@ -71,8 +73,14 @@
saving: false,
forbidden,
+
+ abuseReports: [],
}
},
+ async mounted() {
+ if (!this.$isGranted('users')) { return; }
+ this.abuseReports = await this.$axios.$get(`/admin/reports/${this.user.id}`);
+ },
methods: {
async ban() {
await this.$confirm(this.$t('ban.confirm', {username: this.user.username}), 'danger');
diff --git a/components/MarkSus.vue b/components/MarkSus.vue
new file mode 100644
index 00000000..cbe67070
--- /dev/null
+++ b/components/MarkSus.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/components/ModerationRules.vue b/components/ModerationRules.vue
new file mode 100644
index 00000000..64d41339
--- /dev/null
+++ b/components/ModerationRules.vue
@@ -0,0 +1,32 @@
+
+
+
+ {{label}}
+
+
+
+
+
+
diff --git a/nuxt.config.js b/nuxt.config.js
index 45a5ee58..e3acf0d1 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -274,6 +274,7 @@ export default {
}
routes.push({ path: '/license', component: resolve(__dirname, 'routes/license.vue') });
routes.push({ path: '/admin', component: resolve(__dirname, 'routes/admin.vue') });
+ routes.push({ path: '/admin/moderation', component: resolve(__dirname, 'routes/adminModeration.vue') });
if (config.profile.enabled) {
routes.push({path: '/u/*', component: resolve(__dirname, 'routes/profile.vue')});
diff --git a/routes/admin.vue b/routes/admin.vue
index c53e1e31..c29e0644 100644
--- a/routes/admin.vue
+++ b/routes/admin.vue
@@ -8,6 +8,8 @@
Stats counted: {{$datetime(stats.calculatedAt)}}
+ Moderation rules
+
@@ -119,48 +121,11 @@
Abuse reports
+ ({{abuseReportsActiveCount}})
-
+
+
+
@@ -246,14 +211,6 @@
};
},
methods: {
- async handleReport(id) {
- await this.$confirm('Are you sure you want to mark this report as handled?', 'success');
- await this.$post(`/admin/reports/handle/${id}`);
- this.abuseReports = this.abuseReports.map(r => {
- if (r.id === id) { r.isHandled = true; }
- return r;
- });
- },
async impersonate(email) {
const { token } = await this.$axios.$get(`/admin/impersonate/${encodeURIComponent(email)}`);
this.$cookies.set('impersonator', this.$cookies.get('token'));
@@ -261,12 +218,6 @@
await this.$router.push('/' + this.config.user.route);
setTimeout(() => window.location.reload(), 500);
},
- formatComment(comment) {
- return comment
- .split(', ')
- .map(x => x.replace(/^(.*) \((.*)\)$/, '$1'))
- .join(', ');
- },
},
computed: {
profilesByLocale() {
@@ -276,6 +227,9 @@
}
return r;
},
+ abuseReportsActiveCount() {
+ return this.abuseReports.filter(r => !r.isHandled).length;
+ },
},
watch: {
userFilter() {
diff --git a/routes/adminModeration.vue b/routes/adminModeration.vue
new file mode 100644
index 00000000..93428e10
--- /dev/null
+++ b/routes/adminModeration.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+ Moderation rules
+
+
+
+
+
+
+
+
diff --git a/routes/profile.vue b/routes/profile.vue
index a0ca1020..44aa514d 100644
--- a/routes/profile.vue
+++ b/routes/profile.vue
@@ -10,7 +10,9 @@
-
+
+
+