mirror of
https://github.com/wassname/talk.git
synced 2026-06-29 13:50:35 +08:00
Adds ban/unban to cli. Fix ban user in the admin.
This commit is contained in:
@@ -286,6 +286,40 @@ function removeRole(userID, role) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ban a user
|
||||
* @param {String} userID id of the user to ban
|
||||
*/
|
||||
function ban(userID) {
|
||||
User
|
||||
.setStatus(userID, 'banned', '')
|
||||
.then(() => {
|
||||
console.log(`Banned the User ${userID}.`);
|
||||
util.shutdown();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
util.shutdown(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unban a user
|
||||
* @param {String} userUD id of the user to remove the role from
|
||||
*/
|
||||
function unban(userID) {
|
||||
User
|
||||
.setStatus(userID, 'active', '')
|
||||
.then(() => {
|
||||
console.log(`Unban the User ${userID}.`);
|
||||
util.shutdown();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
util.shutdown(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a given user.
|
||||
* @param {String} userID the ID of a user to disable
|
||||
@@ -373,6 +407,16 @@ program
|
||||
.description('removes a role from a given user')
|
||||
.action(removeRole);
|
||||
|
||||
program
|
||||
.command('ban <userID>')
|
||||
.description('ban a given user')
|
||||
.action(ban);
|
||||
|
||||
program
|
||||
.command('uban <userID>')
|
||||
.description('unban a given user')
|
||||
.action(unban);
|
||||
|
||||
program
|
||||
.command('disable <userID>')
|
||||
.description('disable a given user from logging in')
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import actions from '../constants/users';
|
||||
|
||||
/**
|
||||
* Action disptacher related to comments
|
||||
*/
|
||||
@@ -19,9 +17,21 @@ export const createComment = (name, body) => dispatch => {
|
||||
};
|
||||
|
||||
// Dialog Actions
|
||||
export const showBanUserDialog = () => (dispatch) => {
|
||||
dispatch({type: actions.SHOW_BANUSER_DIALOG});
|
||||
export const showBanUserDialog = (userId, userName, commentId) => {
|
||||
return dispatch => {
|
||||
dispatch({type: 'SHOW_BANUSER_DIALOG', userId, userName, commentId});
|
||||
};
|
||||
};
|
||||
export const hideBanUserDialog = () => (dispatch) => {
|
||||
dispatch({type: actions.HIDE_BANUSER_DIALOG});
|
||||
|
||||
export const hideBanUserDialog = (showDialog) => {
|
||||
return dispatch => {
|
||||
dispatch({type: 'HIDE_BANUSER_DIALOG', showDialog});
|
||||
};
|
||||
};
|
||||
|
||||
export const banUser = (status, userId, commentId) => {
|
||||
return dispatch => {
|
||||
dispatch({type: 'USER_BAN', status, userId, commentId});
|
||||
dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH'});
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,9 +9,14 @@ import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
const lang = new I18n(translations);
|
||||
|
||||
const BanUserDialog = ({open, handleClose, authorName}) => (
|
||||
<Dialog className={styles.dialog} open={open} title={lang.t('bandialog.ban_user')} onClose={handleClose} onCancel={handleClose}>
|
||||
<span className={styles.close} onClick={handleClose}>×</span>
|
||||
const BanUserDialog = ({open, handleClose, onClickBanUser, user}) => {
|
||||
const userName = (typeof user === 'undefined') ? '' : user['userName'];
|
||||
const userId = (typeof user === 'undefined') ? '' : user['userId'];
|
||||
const commentId = (typeof user === 'undefined') ? '' : user['commentId'];
|
||||
|
||||
return (
|
||||
<Dialog className={styles.dialog} open={open} onClose={() => handleClose()} onCancel={() => handleClose()} title={lang.t('bandialog.ban_user')}>
|
||||
<span className={styles.close} onClick={() => handleClose()}>×</span>
|
||||
<div>
|
||||
<div className={styles.header}>
|
||||
<h3>
|
||||
@@ -20,21 +25,23 @@ const BanUserDialog = ({open, handleClose, authorName}) => (
|
||||
</div>
|
||||
<div className={styles.separator}>
|
||||
<h4>
|
||||
{lang.t('bandialog.are_you_sure', authorName)}
|
||||
{lang.t('bandialog.are_you_sure', userName)}
|
||||
</h4>
|
||||
<i>
|
||||
{lang.t('bandialog.note')}
|
||||
</i>
|
||||
</div>
|
||||
<div className={styles.buttons}>
|
||||
<Button cStyle="cancel" full>
|
||||
<Button cStyle="cancel" onClick={() => handleClose()} full>
|
||||
{lang.t('bandialog.cancel')}
|
||||
</Button>
|
||||
<Button cStyle="black" full>
|
||||
<Button cStyle="black" onClick={() => onClickBanUser(userId, commentId)} full>
|
||||
{lang.t('bandialog.yes_ban_user')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default BanUserDialog;
|
||||
|
||||
@@ -9,9 +9,6 @@ import translations from '../translations.json';
|
||||
|
||||
import {Icon} from 'react-mdl';
|
||||
import {FabButton, Button} from 'coral-ui';
|
||||
import BanUserDialog from './BanUserDialog';
|
||||
|
||||
import {showBanUserDialog, hideBanUserDialog} from '../actions/comments';
|
||||
|
||||
const linkify = new Linkify();
|
||||
|
||||
@@ -53,35 +50,27 @@ export default props => {
|
||||
);
|
||||
};
|
||||
|
||||
//return props.author.get('status') === 'banned' ? 'disabled' : 'raised';
|
||||
|
||||
// Get the button of the action performed over a comment if any
|
||||
const getActionButton = (action, i, props) => {
|
||||
const status = props.comment.get('status');
|
||||
const flagged = props.comment.get('flagged');
|
||||
const banned = (props.author.get('status') === 'banned');
|
||||
|
||||
if (action === 'flag' && (status || flagged === true)) {
|
||||
return null;
|
||||
}
|
||||
if (action === 'ban') {
|
||||
return (
|
||||
// <Button
|
||||
// {...props.author.get('status') === 'banned' ? 'disabled' : 'raised'}
|
||||
// key={i}
|
||||
// onClick={() => props.onClickAction(props.actionsMap[action].status, props.comment.get('id'), props.author.get('id'))}>{lang.t('comment.ban_user')}</Button>
|
||||
<div key={i}>
|
||||
<Button {...props.author.get('status') === 'banned' ? 'disabled' : 'raised'}
|
||||
cStyle="black"
|
||||
onClick={showBanUserDialog()}
|
||||
key={i}
|
||||
{...props} >
|
||||
{lang.t('comment.ban_user')}
|
||||
</Button>
|
||||
<BanUserDialog
|
||||
open={props.showBanUserDialog}
|
||||
handleClose={hideBanUserDialog()}
|
||||
authorName={props.author.get('displayName')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
<Button
|
||||
disabled={banned ? 'disabled' : ''}
|
||||
cStyle='black'
|
||||
onClick={() => props.onClickShowBanDialog(props.author.get('id'), props.author.get('displayName'), props.comment.get('id'))}
|
||||
key={i} >
|
||||
{lang.t('comment.ban_user')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<FabButton icon={props.actionsMap[action].icon} className={styles.actionButton}
|
||||
|
||||
@@ -20,6 +20,7 @@ export default class CommentList extends React.Component {
|
||||
|
||||
this.state = {active: null};
|
||||
this.onClickAction = this.onClickAction.bind(this);
|
||||
this.onClickShowBanDialog = this.onClickShowBanDialog.bind(this);
|
||||
}
|
||||
|
||||
// remove key handlers before leaving
|
||||
@@ -113,6 +114,10 @@ export default class CommentList extends React.Component {
|
||||
this.props.onClickAction(action, id, author_id);
|
||||
}
|
||||
|
||||
onClickShowBanDialog(userId, userName, commentId) {
|
||||
this.props.onClickShowBanDialog(userId, userName, commentId);
|
||||
}
|
||||
|
||||
render () {
|
||||
const {singleView, commentIds, comments, users, hideActive, key} = this.props;
|
||||
const {active} = this.state;
|
||||
@@ -127,6 +132,7 @@ export default class CommentList extends React.Component {
|
||||
key={index}
|
||||
index={index}
|
||||
onClickAction={this.onClickAction}
|
||||
onClickShowBanDialog={this.onClickShowBanDialog}
|
||||
actions={this.props.actions}
|
||||
actionsMap={actions}
|
||||
isActive={commentId === active}
|
||||
|
||||
+1
@@ -1,2 +1,3 @@
|
||||
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
|
||||
export const HIDE_BANUSER_DIALOG = 'HIDE_BANUSER_DIALOG';
|
||||
export const USER_BAN_SUCESS = 'USER_BAN_SUCESS';
|
||||
@@ -4,9 +4,9 @@ import key from 'keymaster';
|
||||
|
||||
import ModerationKeysModal from 'components/ModerationKeysModal';
|
||||
import CommentList from 'components/CommentList';
|
||||
import BanUserDialog from 'components/BanUserDialog';
|
||||
|
||||
import {updateStatus} from 'actions/comments';
|
||||
import {banUser} from 'actions/users';
|
||||
import {updateStatus, showBanUserDialog, hideBanUserDialog, banUser} from 'actions/comments';
|
||||
import styles from './ModerationQueue.css';
|
||||
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
@@ -52,18 +52,23 @@ class ModerationQueue extends React.Component {
|
||||
}
|
||||
|
||||
// Dispatch the update status action
|
||||
onCommentAction (action, id, author_id) {
|
||||
// if we are banning a user by the action then dispatch banUser
|
||||
// action = 'banned' in the case of banning
|
||||
if (action === 'banned') {
|
||||
this.props.dispatch(banUser(action, id, author_id));
|
||||
this.props.dispatch(updateStatus('rejected', id));
|
||||
}
|
||||
|
||||
onCommentAction (action, id) {
|
||||
// If not banning then change the status to approved or flagged as action = status
|
||||
this.props.dispatch(updateStatus(action, id));
|
||||
}
|
||||
|
||||
showBanUserDialog (userId, userName, commentId) {
|
||||
this.props.dispatch(showBanUserDialog(userId, userName, commentId));
|
||||
}
|
||||
|
||||
hideBanUserDialog () {
|
||||
this.props.dispatch(hideBanUserDialog(false));
|
||||
}
|
||||
|
||||
banUser (userId, commentId) {
|
||||
this.props.dispatch(banUser('banned', userId, commentId));
|
||||
}
|
||||
|
||||
onTabClick (activeTab) {
|
||||
this.setState({activeTab});
|
||||
}
|
||||
@@ -96,10 +101,16 @@ class ModerationQueue extends React.Component {
|
||||
}
|
||||
comments={comments.get('byId')}
|
||||
users={users.get('byId')}
|
||||
onClickAction={(action, id, author_id) => this.onCommentAction(action, id, author_id)}
|
||||
onClickAction={(action, commentId) => this.onCommentAction(action, commentId)}
|
||||
onClickShowBanDialog={(userId, userName, commentId) => this.showBanUserDialog(userId, userName, commentId)}
|
||||
actions={['reject', 'approve', 'ban']}
|
||||
loading={comments.loading} />
|
||||
</div>
|
||||
<BanUserDialog
|
||||
open={comments.get('showBanUserDialog')}
|
||||
handleClose={() => this.hideBanUserDialog()}
|
||||
onClickBanUser={(userId, commentId) => this.banUser(userId, commentId)}
|
||||
user={comments.get('banUser')}/>
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel ${styles.listContainer}`} id='rejected'>
|
||||
<CommentList
|
||||
isActive={activeTab === 'rejected'}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
import * as actions from '../constants/users';
|
||||
import * as actions from '../constants/comments';
|
||||
import {Map, List, fromJS} from 'immutable';
|
||||
|
||||
/**
|
||||
@@ -13,7 +12,12 @@ const initialState = Map({
|
||||
byId: Map(),
|
||||
ids: List(),
|
||||
loading: false,
|
||||
showBanUserDialog: false
|
||||
showBanUserDialog: false,
|
||||
banUser: {
|
||||
'userName': '',
|
||||
'userId': '',
|
||||
'commentId': ''
|
||||
}
|
||||
});
|
||||
|
||||
// Handle the comment actions
|
||||
@@ -26,16 +30,21 @@ export default (state = initialState, action) => {
|
||||
case 'COMMENT_FLAG': return flag(state, action);
|
||||
case 'COMMENT_CREATE_SUCCESS': return addComment(state, action);
|
||||
case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state);
|
||||
case actions.SHOW_BANUSER_DIALOG:
|
||||
return state
|
||||
.set('showBanUserDialog', true);
|
||||
case actions.HIDE_BANUSER_DIALOG:
|
||||
return state
|
||||
.set('showBanUserDialog', false);
|
||||
case actions.SHOW_BANUSER_DIALOG: return setBanUser(state, true, action);
|
||||
case actions.HIDE_BANUSER_DIALOG: return setBanUser(state, false, action);
|
||||
case actions.USER_BAN_SUCESS: return setBanUser(state, false, action);
|
||||
default: return state;
|
||||
}
|
||||
};
|
||||
|
||||
// hide or show the UI for the dialog confirming the ban
|
||||
// set the user that is going to set and the comment that is the reason
|
||||
const setBanUser = (state, showBanUser, action) => {
|
||||
const banUser = {'userName': action.userName, 'userId': action.userId, 'commentId': action.commentId};
|
||||
return state.set('showBanUserDialog', showBanUser)
|
||||
.set('banUser', banUser);
|
||||
};
|
||||
|
||||
// Update a comment status
|
||||
const updateStatus = (state, action) => {
|
||||
const byId = state.get('byId');
|
||||
|
||||
@@ -3,7 +3,6 @@ import {Map, List, fromJS} from 'immutable';
|
||||
const initialState = Map({
|
||||
byId: Map(),
|
||||
ids: List(),
|
||||
showBanUserDialog: false
|
||||
});
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
|
||||
@@ -21,8 +21,8 @@ export default store => next => action => {
|
||||
case 'COMMENT_CREATE':
|
||||
createComment(store, action.name, action.body);
|
||||
break;
|
||||
case 'USER_STATUS_UPDATE':
|
||||
userStatusUpdate(store, action.author_id, action.status);
|
||||
case 'USER_BAN':
|
||||
userStatusUpdate(store, action.status, action.userId, action.commentId);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ const createComment = (store, name, comment) => {
|
||||
};
|
||||
|
||||
// Ban a user
|
||||
const userStatusUpdate = (store, author_id, status) => {
|
||||
coralApi(`/user/${author_id}/status`, {method: 'POST', body: {status: status, comment_id: ''}})
|
||||
.then(res => store.dispatch({type: 'USER_BAN_SUCESSS', res}))
|
||||
const userStatusUpdate = (store, status, userId, commentId) => {
|
||||
return coralApi(`/user/${userId}/status`, {method: 'POST', body: {status: status, comment_id: commentId}})
|
||||
.then(res => store.dispatch({type: 'USER_BAN_SUCESS', res}))
|
||||
.catch(error => store.dispatch({type: 'USER_BAN_FAILED', error}));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user