mirror of
https://github.com/wassname/talk.git
synced 2026-08-12 12:30:39 +08:00
user queries
This commit is contained in:
+49
-16
@@ -10,6 +10,47 @@ const {
|
||||
const UsersService = require('../../services/users');
|
||||
const UserModel = require('../../models/user');
|
||||
|
||||
const mergeState = (query, state) => {
|
||||
const {status} = state;
|
||||
|
||||
if (status) {
|
||||
const {username, banned, suspended} = status;
|
||||
|
||||
if (typeof username !== 'undefined' && username && username.length > 0) {
|
||||
query.merge({
|
||||
'status.username.status': {
|
||||
$in: username
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof banned !== 'undefined' && banned !== null) {
|
||||
query.merge({
|
||||
'status.banned.status': banned
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof suspended !== 'undefined' && suspended !== null) {
|
||||
if (suspended) {
|
||||
query.merge({
|
||||
'status.suspension.until': {
|
||||
$gte: Date.now()
|
||||
}
|
||||
});
|
||||
} else {
|
||||
query.merge({
|
||||
$or: [
|
||||
{'status.suspension.until': null},
|
||||
{'status.suspension.until': {
|
||||
$lt: Date.now()
|
||||
}}
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const genUserByIDs = async (context, ids) => {
|
||||
if (!ids || ids.length === 0) {
|
||||
return [];
|
||||
@@ -31,20 +72,16 @@ const genUserByIDs = async (context, ids) => {
|
||||
* @param {Object} context graph context
|
||||
* @param {Object} query query terms to apply to the users query
|
||||
*/
|
||||
const getUsersByQuery = async ({user, loaders: {Actions}}, {ids, limit, cursor, statuses, action_type, sortOrder}) => {
|
||||
const getUsersByQuery = async ({user, loaders: {Actions}}, {ids, limit, cursor, state, action_type, sortOrder}) => {
|
||||
let query = UserModel.find();
|
||||
|
||||
if (action_type || statuses) {
|
||||
if (action_type || state) {
|
||||
if (!user || !user.can(SEARCH_OTHER_USERS)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (statuses) {
|
||||
query = query.where({
|
||||
status: {
|
||||
$in: statuses
|
||||
}
|
||||
});
|
||||
if (state) {
|
||||
mergeState(query, state);
|
||||
} else {
|
||||
const userIds = await Actions.getByTypes({action_type, item_type: 'USERS'});
|
||||
ids = ids ? union(ids, userIds) : userIds;
|
||||
@@ -115,25 +152,21 @@ const getUsersByQuery = async ({user, loaders: {Actions}}, {ids, limit, cursor,
|
||||
* @return {Promise} resolves to the counts of the users from the
|
||||
* query
|
||||
*/
|
||||
const getCountByQuery = async ({loaders: {Actions}}, {action_type, statuses}) => {
|
||||
const getCountByQuery = async ({loaders: {Actions}}, {action_type, state}) => {
|
||||
let query = UserModel.find();
|
||||
|
||||
if (action_type) {
|
||||
const userIds = await Actions.getByTypes({action_type, item_type: 'USERS'});
|
||||
|
||||
query = query.find({
|
||||
query.merge({
|
||||
id: {
|
||||
$in: userIds
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (statuses) {
|
||||
query = query.where({
|
||||
status: {
|
||||
$in: statuses
|
||||
}
|
||||
});
|
||||
if (state) {
|
||||
mergeState(query, state);
|
||||
}
|
||||
|
||||
return UserModel
|
||||
|
||||
@@ -13,6 +13,8 @@ const setUserUsernameStatus = async (ctx, id, status) => {
|
||||
const user = await UsersService.setUsernameStatus(id, status, ctx.user.id);
|
||||
if (status === 'REJECTED') {
|
||||
ctx.pubsub.publish('usernameRejected', user);
|
||||
} else if (status === 'APPROVED') {
|
||||
ctx.pubsub.publish('usernameApproved', user);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+106
-114
@@ -7,131 +7,123 @@ const {
|
||||
SUBSCRIBE_ALL_USER_SUSPENDED,
|
||||
SUBSCRIBE_ALL_USER_BANNED,
|
||||
SUBSCRIBE_ALL_USERNAME_REJECTED,
|
||||
SUBSCRIBE_ALL_USERNAME_APPROVED,
|
||||
} = require('../perms/constants');
|
||||
|
||||
const merge = require('lodash/merge');
|
||||
const debug = require('debug')('talk:graph:setupFunctions');
|
||||
const plugins = require('../services/plugins');
|
||||
|
||||
const setupFunctions = {
|
||||
commentAdded: (options, args, comment, context) => {
|
||||
|
||||
// Only privileged users can subscribe to all assets.
|
||||
if (!args.asset_id && (!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_ADDED))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If user subscribes for statuses other than NONE and/or ACCEPTED statuses, it needs
|
||||
// special privileges.
|
||||
if (
|
||||
(!args.statuses || args.statuses.some((status) => !['NONE', 'ACCEPTED'].includes(status))) &&
|
||||
(!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_ADDED))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.asset_id && comment.asset_id !== args.asset_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.statuses && !args.statuses.includes(comment.status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
commentEdited: (options, args, comment, context) => {
|
||||
if (!args.asset_id && (!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_EDITED))) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
},
|
||||
commentFlagged: (options, args, comment, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_FLAGGED)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
},
|
||||
commentAccepted: (options, args, comment, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_ACCEPTED)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
},
|
||||
commentRejected: (options, args) => (comment, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_REJECTED)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
},
|
||||
userSuspended: (options, args, user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USER_SUSPENDED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
},
|
||||
userBanned: (options, args, user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USER_BANNED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
},
|
||||
usernameRejected: (options, args, user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USERNAME_REJECTED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
},
|
||||
usernameApproved: (options, args, user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USERNAME_APPROVED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Plugin support requires that we merge in existing setupFunctions with our new
|
||||
* plugin based ones. This allows plugins to extend existing setupFunctions as well
|
||||
* as provide new ones.
|
||||
* plugin based ones. This allows plugins to extend existing setupFunctions as
|
||||
* well as provide new ones. We'll remap our internal representation of the
|
||||
* setupFunctions into the format needed by Apollo.
|
||||
*/
|
||||
const setupFunctions = plugins.get('server', 'setupFunctions').reduce((acc, {plugin, setupFunctions}) => {
|
||||
module.exports = plugins.get('server', 'setupFunctions').reduce((acc, {plugin, setupFunctions}) => {
|
||||
debug(`added plugin '${plugin.name}'`);
|
||||
|
||||
return merge(acc, setupFunctions);
|
||||
}, {
|
||||
commentAdded: (options, args) => ({
|
||||
commentAdded: {
|
||||
filter: (comment, context) => {
|
||||
}, Object.keys(setupFunctions).map((key) => {
|
||||
const filter = setupFunctions[key];
|
||||
|
||||
// Only privileged users can subscribe to all assets.
|
||||
if (!args.asset_id && (!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_ADDED))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If user subscribes for statuses other than NONE and/or ACCEPTED statuses, it needs
|
||||
// special privileges.
|
||||
if (
|
||||
(!args.statuses || args.statuses.some((status) => !['NONE', 'ACCEPTED'].includes(status))) &&
|
||||
(!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_ADDED))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.asset_id && comment.asset_id !== args.asset_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.statuses && !args.statuses.includes(comment.status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return {
|
||||
[key]: (options, args) => ({
|
||||
[key]: {
|
||||
filter: (user, ctx) => filter(options, args, user, ctx)
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentEdited: (options, args) => ({
|
||||
commentEdited: {
|
||||
filter: (comment, context) => {
|
||||
if (!args.asset_id && (!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_EDITED))) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentFlagged: (options, args) => ({
|
||||
commentFlagged: {
|
||||
filter: (comment, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_FLAGGED)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentAccepted: (options, args) => ({
|
||||
commentAccepted: {
|
||||
filter: (comment, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_ACCEPTED)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentRejected: (options, args) => ({
|
||||
commentRejected: {
|
||||
filter: (comment, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_REJECTED)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
userSuspended: (options, args) => ({
|
||||
userSuspended: {
|
||||
filter: (user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USER_SUSPENDED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
userBanned: (options, args) => ({
|
||||
userBanned: {
|
||||
filter: (user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USER_BANNED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
usernameRejected: (options, args) => ({
|
||||
usernameRejected: {
|
||||
filter: (user, context) => {
|
||||
if (
|
||||
!context.user
|
||||
|| args.user_id !== user.id && !context.user.can(SUBSCRIBE_ALL_USERNAME_REJECTED)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !args.user_id || user.id === args.user_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
module.exports = setupFunctions;
|
||||
})
|
||||
};
|
||||
})
|
||||
.reduce((setupFunction, setupFunctions) => {
|
||||
return merge(setupFunctions, setupFunction);
|
||||
}, {}));
|
||||
|
||||
@@ -1492,6 +1492,10 @@ type Subscription {
|
||||
# `user_id` must match id of current user except for
|
||||
# users with the `ADMIN` or `MODERATOR` role.
|
||||
usernameRejected(user_id: ID): User
|
||||
|
||||
# Gen an update whenever a username has been approved. `user_id` must match id
|
||||
# of current user except for users with the `ADMIN` or `MODERATOR` role.
|
||||
usernameApproved(user_id: ID): User
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -7,4 +7,5 @@ module.exports = {
|
||||
SUBSCRIBE_ALL_USER_SUSPENDED: 'SUBSCRIBE_ALL_USER_SUSPENDED',
|
||||
SUBSCRIBE_ALL_USER_BANNED: 'SUBSCRIBE_ALL_USER_BANNED',
|
||||
SUBSCRIBE_ALL_USERNAME_REJECTED: 'SUBSCRIBE_ALL_USERNAME_REJECTED',
|
||||
SUBSCRIBE_ALL_USERNAME_APPROVED: 'SUBSCRIBE_ALL_USERNAME_APPROVED'
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ module.exports = (user, perm) => {
|
||||
case types.SUBSCRIBE_ALL_USER_SUSPENDED:
|
||||
case types.SUBSCRIBE_ALL_USER_BANNED:
|
||||
case types.SUBSCRIBE_ALL_USERNAME_REJECTED:
|
||||
case types.SUBSCRIBE_ALL_USERNAME_APPROVED:
|
||||
return check(user, ['ADMIN', 'MODERATOR']);
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user