@@ -49,6 +57,10 @@
@{{ user | acct }}
+ admin
+ moderator
+
+
{{ $t('users.updatedAt') }}:
@@ -84,6 +96,7 @@ export default Vue.extend({
suspending: false,
unsuspending: false,
sort: '+createdAt',
+ state: 'all',
origin: 'combined',
limit: 10,
offset: 0,
@@ -100,6 +113,12 @@ export default Vue.extend({
this.fetchUsers();
},
+ state() {
+ this.users = [];
+ this.offset = 0;
+ this.fetchUsers();
+ },
+
origin() {
this.users = [];
this.offset = 0;
@@ -236,7 +255,8 @@ export default Vue.extend({
},
fetchUsers() {
- this.$root.api('users', {
+ this.$root.api('admin/show-users', {
+ state: this.state,
origin: this.origin,
sort: this.sort,
offset: this.offset,
@@ -284,4 +304,19 @@ export default Vue.extend({
margin-left 8px
opacity 0.7
+ > .is-admin
+ > .is-moderator
+ flex-shrink 0
+ align-self center
+ margin 0 0 0 .5em
+ padding 1px 6px
+ font-size 80%
+ border-radius 3px
+ background var(--noteHeaderAdminBg)
+ color var(--noteHeaderAdminFg)
+
+ > .is-verified
+ > .is-suspended
+ margin 0 0 0 .5em
+ color #4dabf7
diff --git a/src/server/api/endpoints/admin/show-users.ts b/src/server/api/endpoints/admin/show-users.ts
new file mode 100644
index 0000000000..20ccfbd7f3
--- /dev/null
+++ b/src/server/api/endpoints/admin/show-users.ts
@@ -0,0 +1,123 @@
+import $ from 'cafy';
+import User, { pack } from '../../../../models/user';
+import define from '../../define';
+
+export const meta = {
+ requireCredential: true,
+ requireModerator: true,
+
+ params: {
+ limit: {
+ validator: $.num.optional.range(1, 100),
+ default: 10
+ },
+
+ offset: {
+ validator: $.num.optional.min(0),
+ default: 0
+ },
+
+ sort: {
+ validator: $.str.optional.or([
+ '+follower',
+ '-follower',
+ '+createdAt',
+ '-createdAt',
+ '+updatedAt',
+ '-updatedAt',
+ ]),
+ },
+
+ state: {
+ validator: $.str.optional.or([
+ 'all',
+ 'admin',
+ 'moderator',
+ 'adminOrModerator',
+ 'verified',
+ 'suspended',
+ ]),
+ default: 'all'
+ },
+
+ origin: {
+ validator: $.str.optional.or([
+ 'combined',
+ 'local',
+ 'remote',
+ ]),
+ default: 'local'
+ }
+ }
+};
+
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
+ let _sort;
+ if (ps.sort) {
+ if (ps.sort == '+follower') {
+ _sort = {
+ followersCount: -1
+ };
+ } else if (ps.sort == '-follower') {
+ _sort = {
+ followersCount: 1
+ };
+ } else if (ps.sort == '+createdAt') {
+ _sort = {
+ createdAt: -1
+ };
+ } else if (ps.sort == '+updatedAt') {
+ _sort = {
+ updatedAt: -1
+ };
+ } else if (ps.sort == '-createdAt') {
+ _sort = {
+ createdAt: 1
+ };
+ } else if (ps.sort == '-updatedAt') {
+ _sort = {
+ updatedAt: 1
+ };
+ }
+ } else {
+ _sort = {
+ _id: -1
+ };
+ }
+
+ const q = {
+ $and: []
+ } as any;
+
+ // state
+ q.$and.push(
+ ps.state == 'admin' ? { isAdmin: true } :
+ ps.state == 'moderator' ? { isModerator: true } :
+ ps.state == 'adminOrModerator' ? {
+ $or: [{
+ isAdmin: true
+ }, {
+ isModerator: true
+ }]
+ } :
+ ps.state == 'verified' ? { isVerified: true } :
+ ps.state == 'suspended' ? { isSuspended: true } :
+ {}
+ );
+
+ // origin
+ q.$and.push(
+ ps.origin == 'local' ? { host: null } :
+ ps.origin == 'remote' ? { host: { $ne: null } } :
+ {}
+ );
+
+ const users = await User
+ .find(q, {
+ limit: ps.limit,
+ sort: _sort,
+ skip: ps.offset
+ });
+
+ res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
+}));