mirror of
https://github.com/wassname/talk.git
synced 2026-08-15 12:55:10 +08:00
added support for user assigned_by fields to get resolved
This commit is contained in:
@@ -40,11 +40,11 @@ const stopIgnoringUser = ({user}, userToStopIgnoring) => {
|
||||
};
|
||||
|
||||
const changeUsername = async (ctx, id, username) => {
|
||||
return UsersService.changeUsername(id, username);
|
||||
return UsersService.changeUsername(id, username, ctx.user.id);
|
||||
};
|
||||
|
||||
const setUsername = async (ctx, id, username) => {
|
||||
return UsersService.setUsername(id, username);
|
||||
return UsersService.setUsername(id, username, ctx.user.id);
|
||||
};
|
||||
|
||||
module.exports = (ctx) => {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
const {decorateUserField} = require('./util');
|
||||
|
||||
const BannedStatusHistory = {};
|
||||
|
||||
decorateUserField(BannedStatusHistory, 'assigned_by');
|
||||
|
||||
module.exports = BannedStatusHistory;
|
||||
@@ -1,13 +1,7 @@
|
||||
const {SEARCH_OTHER_USERS} = require('../../perms/constants');
|
||||
const {decorateUserField} = require('./util');
|
||||
|
||||
const CommentStatusHistory = {
|
||||
assigned_by({assigned_by}, _, {user, loaders: {Users}}) {
|
||||
if (!user || !user.can(SEARCH_OTHER_USERS) || assigned_by == null) {
|
||||
return null;
|
||||
}
|
||||
const CommentStatusHistory = {};
|
||||
|
||||
return Users.getByID.load(assigned_by);
|
||||
}
|
||||
};
|
||||
decorateUserField(CommentStatusHistory, 'assigned_by');
|
||||
|
||||
module.exports = CommentStatusHistory;
|
||||
|
||||
+18
-14
@@ -1,56 +1,60 @@
|
||||
const _ = require('lodash');
|
||||
const debug = require('debug')('talk:graph:resolvers');
|
||||
|
||||
const ActionSummary = require('./action_summary');
|
||||
const Action = require('./action');
|
||||
const AssetActionSummary = require('./asset_action_summary');
|
||||
const ActionSummary = require('./action_summary');
|
||||
const Asset = require('./asset');
|
||||
const CommentStatusHistory = require('./comment_status_history');
|
||||
const AssetActionSummary = require('./asset_action_summary');
|
||||
const BannedStatusHistory = require('./banned_status_history');
|
||||
const Comment = require('./comment');
|
||||
const CommentStatusHistory = require('./comment_status_history');
|
||||
const Cursor = require('./cursor');
|
||||
const Date = require('./date');
|
||||
const FlagActionSummary = require('./flag_action_summary');
|
||||
const FlagAction = require('./flag_action');
|
||||
const DontAgreeAction = require('./dont_agree_action');
|
||||
const DontAgreeActionSummary = require('./dont_agree_action_summary');
|
||||
const FlagAction = require('./flag_action');
|
||||
const FlagActionSummary = require('./flag_action_summary');
|
||||
const GenericUserError = require('./generic_user_error');
|
||||
const RootMutation = require('./root_mutation');
|
||||
const RootQuery = require('./root_query');
|
||||
const Settings = require('./settings');
|
||||
const Subscription = require('./subscription');
|
||||
const TagLink = require('./tag_link');
|
||||
const Tag = require('./tag');
|
||||
const UserError = require('./user_error');
|
||||
const TagLink = require('./tag_link');
|
||||
const User = require('./user');
|
||||
const UserError = require('./user_error');
|
||||
const UserState = require('./user_state');
|
||||
const UsernameStatusHistory = require('./username_status_history');
|
||||
const ValidationUserError = require('./validation_user_error');
|
||||
|
||||
const plugins = require('../../services/plugins');
|
||||
|
||||
// Provide the core resolvers.
|
||||
let resolvers = {
|
||||
ActionSummary,
|
||||
Action,
|
||||
AssetActionSummary,
|
||||
ActionSummary,
|
||||
Asset,
|
||||
CommentStatusHistory,
|
||||
AssetActionSummary,
|
||||
BannedStatusHistory,
|
||||
Comment,
|
||||
CommentStatusHistory,
|
||||
Cursor,
|
||||
Date,
|
||||
FlagActionSummary,
|
||||
FlagAction,
|
||||
DontAgreeAction,
|
||||
DontAgreeActionSummary,
|
||||
FlagAction,
|
||||
FlagActionSummary,
|
||||
GenericUserError,
|
||||
RootMutation,
|
||||
RootQuery,
|
||||
Settings,
|
||||
Subscription,
|
||||
TagLink,
|
||||
Tag,
|
||||
UserError,
|
||||
TagLink,
|
||||
User,
|
||||
UserError,
|
||||
UserState,
|
||||
UsernameStatusHistory,
|
||||
ValidationUserError,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
const {decorateUserField} = require('./util');
|
||||
|
||||
const SuspensionStatusHistory = {};
|
||||
|
||||
decorateUserField(SuspensionStatusHistory, 'assigned_by');
|
||||
|
||||
module.exports = SuspensionStatusHistory;
|
||||
@@ -0,0 +1,7 @@
|
||||
const {decorateUserField} = require('./util');
|
||||
|
||||
const UsernameStatusHistory = {};
|
||||
|
||||
decorateUserField(UsernameStatusHistory, 'assigned_by');
|
||||
|
||||
module.exports = UsernameStatusHistory;
|
||||
+39
-2
@@ -1,4 +1,8 @@
|
||||
const {ADD_COMMENT_TAG} = require('../../perms/constants');
|
||||
const {
|
||||
ADD_COMMENT_TAG,
|
||||
SEARCH_OTHER_USERS,
|
||||
} = require('../../perms/constants');
|
||||
const property = require('lodash/property');
|
||||
|
||||
/**
|
||||
* Decorates the typeResolver with the tags field.
|
||||
@@ -22,7 +26,7 @@ const decorateWithTags = (typeResolver) => {
|
||||
*/
|
||||
const decorateWithPermissionCheck = (typeResolver, protect) => {
|
||||
for (const [field, permissions] of Object.entries(protect)) {
|
||||
let fieldResolver = (obj) => obj[field];
|
||||
let fieldResolver = property(field);
|
||||
if (field in typeResolver) {
|
||||
fieldResolver = typeResolver[field];
|
||||
}
|
||||
@@ -37,7 +41,40 @@ const decorateWithPermissionCheck = (typeResolver, protect) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* decorateUserField will decorate the user field accesses with correct
|
||||
* permission checks.
|
||||
*
|
||||
* @param {Object} typeResolver the type resolver
|
||||
* @param {String} field the field to decorate
|
||||
*/
|
||||
const decorateUserField = (typeResolver, field) => {
|
||||
|
||||
// The default resolver for the user decorator is loading the user by id.
|
||||
let fieldResolver = (obj, args, ctx) =>
|
||||
ctx.loaders.Users.getByID.get(obj[field]);
|
||||
|
||||
// The resolver can be overridden however. This decorator will simply wrap the
|
||||
// field with a permission check.
|
||||
if (field in typeResolver) {
|
||||
fieldResolver = typeResolver[field];
|
||||
}
|
||||
|
||||
typeResolver[field] = (obj, args, ctx, info) => {
|
||||
if (
|
||||
!ctx.user ||
|
||||
obj[field] === null ||
|
||||
(ctx.user.id !== obj[field] && !ctx.user.can(SEARCH_OTHER_USERS))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fieldResolver(obj, args, ctx, info);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
decorateUserField,
|
||||
decorateWithTags,
|
||||
decorateWithPermissionCheck,
|
||||
};
|
||||
|
||||
+6
-6
@@ -209,7 +209,7 @@ class UsersService {
|
||||
return user;
|
||||
}
|
||||
|
||||
static async _setUsername(id, username, fromStatus, toStatus, resetAllowed = false) {
|
||||
static async _setUsername(id, username, fromStatus, toStatus, assignedBy, resetAllowed = false) {
|
||||
try {
|
||||
const query = {
|
||||
id,
|
||||
@@ -228,7 +228,7 @@ class UsersService {
|
||||
$push: {
|
||||
'status.username.history': {
|
||||
status: toStatus,
|
||||
assigned_by: id,
|
||||
assigned_by: assignedBy,
|
||||
created_at: Date.now()
|
||||
}
|
||||
}
|
||||
@@ -265,12 +265,12 @@ class UsersService {
|
||||
}
|
||||
}
|
||||
|
||||
static async setUsername(id, username) {
|
||||
return UsersService._setUsername(id, username, 'UNSET', 'SET', true);
|
||||
static async setUsername(id, username, assignedBy) {
|
||||
return UsersService._setUsername(id, username, 'UNSET', 'SET', assignedBy, true);
|
||||
}
|
||||
|
||||
static async changeUsername(id, username) {
|
||||
return UsersService._setUsername(id, username, 'REJECTED', 'CHANGED');
|
||||
static async changeUsername(id, username, assignedBy) {
|
||||
return UsersService._setUsername(id, username, 'REJECTED', 'CHANGED', assignedBy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,24 @@ describe('graph.mutations.changeUsername', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query User {
|
||||
me {
|
||||
state {
|
||||
status {
|
||||
username {
|
||||
history {
|
||||
status
|
||||
assigned_by {
|
||||
username
|
||||
}
|
||||
created_at
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
[
|
||||
@@ -44,7 +62,7 @@ describe('graph.mutations.changeUsername', () => {
|
||||
let res = await graphql(schema, changeUsernameMutation, {}, ctx, {
|
||||
user_id: user.id,
|
||||
username,
|
||||
});
|
||||
}, 'ChangeUsername');
|
||||
|
||||
if (res.errors && res.errors.length > 0) {
|
||||
console.error(res.errors);
|
||||
@@ -65,7 +83,7 @@ describe('graph.mutations.changeUsername', () => {
|
||||
res = await graphql(schema, changeUsernameMutation, {}, ctx, {
|
||||
user_id: user.id,
|
||||
username,
|
||||
});
|
||||
}, 'ChangeUsername');
|
||||
|
||||
if (res.errors && res.errors.length > 0) {
|
||||
console.error(res.errors);
|
||||
@@ -74,9 +92,15 @@ describe('graph.mutations.changeUsername', () => {
|
||||
expect(res.errors).to.be.undefined;
|
||||
expect(res.data.changeUsername).to.be.null;
|
||||
|
||||
user = await UsersService.findById(user.id);
|
||||
res = await graphql(schema, changeUsernameMutation, {}, ctx, {}, 'User');
|
||||
|
||||
expect(user.status.username.status, 'CHANGED');
|
||||
if (res.errors && res.errors.length > 0) {
|
||||
console.error(res.errors);
|
||||
}
|
||||
|
||||
expect(res.errors).to.be.undefined;
|
||||
|
||||
expect(res.data.me.state.status.username.status, 'CHANGED');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user