Merge branch 'next' into user-status-refactor

This commit is contained in:
Wyatt Johnson
2017-11-28 09:47:34 -07:00
committed by GitHub
19 changed files with 213 additions and 71 deletions
+3 -2
View File
@@ -1,5 +1,6 @@
{
"exceptions": [
"https://nodesecurity.io/advisories/531"
"https://nodesecurity.io/advisories/531",
"https://nodesecurity.io/advisories/532"
]
}
}
+39 -14
View File
@@ -8,10 +8,13 @@ const program = require('./commander');
const inquirer = require('inquirer');
const UsersService = require('../services/users');
const UserModel = require('../models/user');
const CommentModel = require('../models/comment');
const ActionModel = require('../models/action');
const USER_ROLES = require('../models/enum/user_roles');
const mongoose = require('../services/mongoose');
const util = require('./util');
const Table = require('cli-table');
const databaseVerifications = require('./verifications/database');
const validateRequired = (msg = 'Field is required', len = 1) => (input) => {
if (input && input.length >= len) {
@@ -113,26 +116,48 @@ async function createUser(options) {
util.shutdown();
} catch (err) {
console.error(err);
util.shutdown();
util.shutdown(1);
}
}
/**
* Deletes a user.
*/
function deleteUser(userID) {
UserModel
.findOneAndRemove({
id: userID
})
.then(() => {
console.log('Deleted user');
util.shutdown();
})
.catch((err) => {
console.error(err);
util.shutdown();
});
async function deleteUser(userID) {
try {
// Find the user we're removing.
const user = await UserModel.findOne({id: userID});
if (!user) {
throw new Error(`user with id ${userID} not found`);
}
// Remove all the user's actions.
await ActionModel
.where({user_id: user.id})
.setOptions({multi: true})
.remove();
// Remove all the user's comments.
await CommentModel
.where({author_id: user.id})
.setOptions({multi: true})
.remove();
// Update the counts that might have changed.
for (const verification of databaseVerifications) {
await verification({fix: true, limit: Infinity, batch: 1000});
}
// Remove the user.
await user.remove();
util.shutdown();
} catch (err) {
console.error(err);
util.shutdown(1);
}
}
/**
@@ -87,7 +87,7 @@ const CoralHeader = ({
</a>
</MenuItem>
<MenuItem>
<a href="https://coralproject.net/contribute.html#other-ideas-and-bug-reports" target="_blank" rel="noopener noreferrer">
<a href="https://support.coralproject.net" target="_blank" rel="noopener noreferrer">
Report a bug or give feedback
</a>
</MenuItem>
@@ -53,3 +53,6 @@
.autoCloseWrapper {
display: flex;
}
@@ -180,22 +180,24 @@ class StreamSettings extends React.Component {
onCheckbox={this.updateAutoClose}
title={t('configure.close_after')}
>
<Textfield
type='number'
pattern='[0-9]+'
style={{width: 50}}
onChange={this.updateClosedTimeout}
value={getTimeoutAmount(settings.closedTimeout)}
label={t('configure.closed_comments_label')} />
<div className={styles.configTimeoutSelect}>
<SelectField
label="comments closed time window"
value={getTimeoutMeasure(settings.closedTimeout)}
onChange={this.updateClosedTimeoutMeasure}>
<Option value={'hours'}>{t('configure.hours')}</Option>
<Option value={'days'}>{t('configure.days')}</Option>
<Option value={'weeks'}>{t('configure.weeks')}</Option>
</SelectField>
<div className={styles.autoCloseWrapper}>
<Textfield
type='number'
pattern='[0-9]+'
style={{width: 50}}
onChange={this.updateClosedTimeout}
value={getTimeoutAmount(settings.closedTimeout)}
label={t('configure.closed_comments_label')} />
<div className={styles.configTimeoutSelect}>
<SelectField
label="comments closed time window"
value={getTimeoutMeasure(settings.closedTimeout)}
onChange={this.updateClosedTimeoutMeasure}>
<Option value={'hours'}>{t('configure.hours')}</Option>
<Option value={'days'}>{t('configure.days')}</Option>
<Option value={'weeks'}>{t('configure.weeks')}</Option>
</SelectField>
</div>
</div>
</ConfigureCard>
{/* the above card should be the last one if at all possible because of z-index issues with the selects */}
@@ -48,7 +48,7 @@ class Stories extends Component {
<div className={styles.optionHeader}>{t('streams.filter_streams')}</div>
<div className={styles.optionDetail}>{t('streams.stream_status')}</div>
<RadioGroup
name='status filter'
name='statusFilter'
value={filter}
childContainer='div'
onChange={onSettingChange('filter')}
@@ -60,7 +60,7 @@ class Stories extends Component {
</RadioGroup>
<div className={styles.optionHeader}>{t('streams.sort_by')}</div>
<RadioGroup
name='sort by'
name='sortBy'
value={asc}
childContainer='div'
onChange={onSettingChange('asc')}
@@ -2,9 +2,22 @@
margin-top: 6px;
}
.viewAllButton {
.viewAllButtonContainer {
position: absolute;
right: 0px;
width: 100%;
display: flex;
justify-content: center;
margin-top: -11px;
z-index: 10;
}
.viewAllButton {
composes: buttonReset from "coral-framework/styles/reset.css";
background-color: #4D8FCC;
color: white;
padding: 4px 8px;
border-radius: 2px;
}
.tabPanel {
@@ -26,4 +39,4 @@
margin-top: 28px;
padding-bottom: 50px;
min-height: 600px;
}
}
@@ -14,7 +14,7 @@ import t, {timeago} from 'coral-framework/services/i18n';
import CommentBox from 'talk-plugin-commentbox/CommentBox';
import QuestionBox from 'talk-plugin-questionbox/QuestionBox';
import {isCommentActive} from 'coral-framework/utils';
import {Button, Tab, TabCount, TabPane} from 'coral-ui';
import {Tab, TabCount, TabPane} from 'coral-ui';
import cn from 'classnames';
import get from 'lodash/get';
@@ -60,6 +60,7 @@ class Stream extends React.Component {
loadNewReplies,
auth: {user},
emit,
viewAllComments,
} = this.props;
// even though the permalinked comment is the highlighted one, we're displaying its parent + replies
@@ -78,6 +79,14 @@ class Stream extends React.Component {
return (
<div className={cn('talk-stream-highlighted-container', styles.highlightedContainer)}>
<div className={cn('talk-stream-show-all-comments-button-container', styles.viewAllButtonContainer)}>
<button
className={cn('talk-stream-show-all-comments-button', styles.viewAllButton)}
onClick={viewAllComments}
>
{t('framework.show_all_comments')}
</button>
</div>
<Comment
data={data}
root={root}
@@ -207,7 +216,6 @@ class Stream extends React.Component {
postComment,
notify,
updateItem,
viewAllComments,
auth: {loggedIn, user},
} = this.props;
const {keepCommentBox} = this.state;
@@ -234,15 +242,6 @@ class Stream extends React.Component {
return (
<div id="stream" className={styles.root}>
<AutomaticAssetClosure assetId={asset.id} closedAt={asset.closedAt}/>
{highlightedComment &&
<Button
cStyle="darkGrey"
className={cn('talk-stream-show-all-comments-button', styles.viewAllButton)}
onClick={viewAllComments}
>
{t('framework.show_all_comments')}
</Button>}
{open
? <div id="commentBox">
<InfoBox
@@ -324,7 +323,7 @@ Stream.propTypes = {
loading: PropTypes.bool,
editName: PropTypes.func,
appendItemArray: PropTypes.func,
updateItem: PropTypes.func,
updateItem: PropTypes.func,
viewAllComments: PropTypes.func,
notify: PropTypes.func.isRequired,
postComment: PropTypes.func.isRequired,
@@ -13,6 +13,8 @@
min-height: 50px;
display: flex;
border-radius: 3px;
padding-right: 40px;
box-sizing: border-box;
}
.icon {
@@ -67,4 +69,4 @@
.hidden {
visibility: hidden;
display: none;
}
}
+83
View File
@@ -0,0 +1,83 @@
// Errors.
const errors = require('../errors');
// Models.
const Action = require('../models/action');
const Asset = require('../models/asset');
const Comment = require('../models/comment');
const Setting = require('../models/setting');
const User = require('../models/user');
// Services.
const Actions = require('../services/actions');
const Assets = require('../services/assets');
const Cache = require('../services/cache');
const Comments = require('../services/comments');
const DomainList = require('../services/domainlist');
const I18n = require('../services/i18n');
const Jwt = require('../services/jwt');
const Karma = require('../services/karma');
const Kue = require('../services/kue');
const Limit = require('../services/limit');
const Locals = require('../services/locals');
const Mailer = require('../services/mailer');
const Metadata = require('../services/metadata');
const Migration = require('../services/migration');
const Mongoose = require('../services/mongoose');
const Passport = require('../services/passport');
const Plugins = require('../services/plugins');
const Pubsub = require('../services/pubsub');
const Redis = require('../services/redis');
const Regex = require('../services/regex');
const Scraper = require('../services/scraper');
const Settings = require('../services/settings');
const Setup = require('../services/setup');
const Subscriptions = require('../services/subscriptions');
const Tags = require('../services/tags');
const Tokens = require('../services/tokens');
const Users = require('../services/users');
const Wordlist = require('../services/wordlist');
// Connector.
const connectors = {
errors,
models: {
Action,
Asset,
Comment,
Setting,
User,
},
services: {
Actions,
Assets,
Cache,
Comments,
DomainList,
I18n,
Jwt,
Karma,
Kue,
Limit,
Locals,
Mailer,
Metadata,
Migration,
Mongoose,
Passport,
Plugins,
Pubsub,
Redis,
Regex,
Scraper,
Settings,
Setup,
Subscriptions,
Tags,
Tokens,
Users,
Wordlist,
},
};
module.exports = connectors;
+4
View File
@@ -2,6 +2,7 @@ const loaders = require('./loaders');
const mutators = require('./mutators');
const uuid = require('uuid');
const merge = require('lodash/merge');
const connectors = require('./connectors');
const plugins = require('../services/plugins');
const pubsub = require('../services/pubsub');
@@ -51,6 +52,9 @@ class Context {
this.user = user;
}
// Attach the connectors.
this.connectors = connectors;
// Create the loaders.
this.loaders = loaders(this);
+3 -3
View File
@@ -347,15 +347,15 @@ da:
email_message_suspend: "Kære {0},\n\nI overensstemmelse med {1}'s retningslinjer for fællesskabet er din konto midlertidigt suspenderet. Under suspensionen vil du ikke kunne kommentere, flagge eller engagere dig med andre kommentarer. Venligst tilslut dig til samtalen{2}.'"
title_notify: "Underret bruygeren om deres midlertidige suspension"
notify_suspend_until: "Bruger {0} er midlertidigt suspenderet. Denne suspension ophører automatisk om {1}."
description_notify: "Suspendering af denne bruger vil midlertidigt deaktivere deres konto og skjule alle deres kommentarer på webstedet."
description_notify: "Suspendering af denne bruger vil midlertidigt deaktivere deres konto."
write_message: "Skriv en besked"
send: "Send"
reject_username:
username: "brugernavn"
no_cancel: "Nej Afbryd"
description_reject: "Vil du midlertidigt forbyde denne bruger på grund af deres {0}? Hvis du gør det, vil det midlertidigt skjule deres kommentarer, indtil de omskriver deres {0}."
description_reject: "Vil du midlertidigt forbyde denne bruger på grund af deres {0}? Hvis du gør det vil blive suspenderet indtil de omskriver deres {0}."
title_notify: "Underret brugeren om deres midlertidige suspension"
description_notify: "Suspendering af denne bruger vil midlertidigt deaktivere deres konto, og skjule alle deres kommentarer på webstedet."
description_notify: "Suspendering af denne bruger vil midlertidigt deaktivere deres konto."
title_reject: "Vi har bemærket at du afviste et brugernavn."
suspend_user: "Suspender bruger"
yes_suspend: "Ja suspender"
+3 -3
View File
@@ -381,15 +381,15 @@ en:
email_message_suspend: "Dear {0},\n\nIn accordance with {1}s community guidelines, your account has been temporarily suspended. During the suspension, you will be unable to comment, flag or engage with fellow commenters. Please rejoin the conversation {2}."
title_notify: "Notify the user of their temporary suspension"
notify_suspend_until: "User {0} has been temporarily suspended. This suspension will automatically end {1}."
description_notify: "Suspending this user will temporarily disable their account and hide all of their comments on the site."
description_notify: "Suspending this user will temporarily disable their account."
write_message: "Write a message"
send: Send
reject_username:
username: username
no_cancel: "No cancel"
description_reject: "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}."
description_reject: "Would you like to temporarily ban this user because of their {0}? Doing so will temporarily suspend this user until they rewrite their {0}."
title_notify: "Notify the user of their temporary suspension"
description_notify: "Suspending this user will temporarily disable their account and hide all of their comments on the site."
description_notify: "Suspending this user will temporarily disable their account."
title_reject: "We noticed you rejected a username"
suspend_user: "Suspend User"
yes_suspend: "Yes suspend"
+3 -3
View File
@@ -393,15 +393,15 @@ es:
email_message_suspend: "Querido/a {0}, De acuerdo a la guía comunitaria de {1}, su cuenta ha sido temporalmente suspendida. Durante este tiempo, no podrá comentar, marcar o involucrarse con otros comentaristas. Por favor unirse a la conversación {2}."
title_notify: "Notificar al usuario de su suspensión temporal"
notify_suspend_until: "Usuario {0} ha sido temporalmente suspendido. Esta suspension va a terminar automáticamente en {1}."
description_notify: "Suspender a este usuario va a deshabilitar temporalmente su cuenta y ocultar todos sus comentarios en el sitio."
description_notify: "Suspender a este usuario va a deshabilitar temporalmente su cuenta."
write_message: "Escribir un mensaje"
send: "Enviar"
reject_username:
username: nombre de usuario
no_cancel: "No cancelar"
description_reject: "¿Quiere suspender temporalmente a este usuario por su {0}? Hacerlo va a ocultar temporalmente sus comentarios hasta que edite su {0}."
description_reject: "¿Quiere suspender temporalmente a este usuario por su {0}? El usuario estará temporalmente suspendido hasta que edite su {0}."
title_notify: "Notificar al usuario de su suspensión temporal"
description_notify: "Suspender a este usuario va a deshabilitar temporalmente su cuenta y ocultar todos sus comentarios en el sitio."
description_notify: "Suspender a este usuario va a deshabilitar temporalmente su cuenta."
title_reject: "Vimos que ha rechazado un nombre de usuario"
suspend_user: "Suspender Usuario"
yes_suspend: "Si, suspender"
+4 -4
View File
@@ -291,10 +291,10 @@ fr:
bio: Bio
cancel: "Annuler"
days: "{0} jours"
description_0: "Voulez-vous interdire temporairement cet utilisateur en raison de leur {0} ? Cela dissimulera temporairement leurs commentaires jusqu'à ce qu'ils réécrivent leurs {0}."
description_1: "Suspendre cet utilisateur désactivera temporairement son compte et cachera tous ses commentaires sur le site."
description_notify: "Suspendre cet utilisateur désactivera temporairement son compte et cachera tous ses commentaires sur le site."
description_reject: "Voulez-vous interdire temporairement cet utilisateur en raison de leur {0}? Cela dissimulera temporairement leurs commentaires jusqu'à ce qu'ils réécrivent leurs {0}."
description_0: "Voulez-vous interdire temporairement cet utilisateur en raison de leur {0} ? Cela va temporairement suspendre l'utilisateur jusqu'à ce qu'ils réécrivent leurs {0}."
description_1: "Suspendre cet utilisateur désactivera temporairement son compte."
description_notify: "Suspendre cet utilisateur désactivera temporairement son compte."
description_reject: "Voulez-vous interdire temporairement cet utilisateur en raison de leur {0}? Cela va temporairement suspendre l'utilisateur jusqu'à ce qu'ils réécrivent leurs {0}."
description_suspend: "Vous suspendez {0}. Ce commentaire sera rejeté, et {0} ne sera pas autorisé à aimer, à signaler, à répondre ou à publier jusqu'à ce que la suspension soit levée."
email: "Un autre membre de la communauté a récemment signalé votre nom d'utilisateur pour examen. En raison de son contenu, votre utilisateur a été rejeté. Cela signifie que vous ne pouvez plus commenter ou signaler du contenu jusqu'à ce que vous changiez votre nom d'utilisateur. Veuillez nous envoyer un e-mail si vous avez des questions ou des préoccupations."
email_subject: "Votre compte a été suspendu"
+3 -3
View File
@@ -349,15 +349,15 @@ pt_BR:
email_message_suspend: "Querido/a {0},\n\nDe acordo com as diretrizes da comunidade de {1}, sua conta foi temporariamente suspensa. Durante a suspensão, você não poderá comentar, denunciar ou se responder outros usuários(as). Por favor, volte para a conversa {2}."
title_notify: "Notificar o usuário da suspensão temporária"
notify_suspend_until: "O usuário {0} foi temporariamente suspenso. Esta suspensão terminará automaticamente {1}."
description_notify: "Suspender este usuário temporariamente desativará sua conta e esconderá todos os seus comentários no site"
description_notify: "Suspender este usuário temporariamente desativará sua conta."
write_message: "Escrever uma mensagem"
send: Enviar
reject_username:
username: nome de usuário
no_cancel: "Não cancelar"
description_reject: "Gostaria de proibir temporariamente este usuário por causa de seu {0}? Isso ocultará temporariamente seus comentários até que eles reescrevam seu {0}."
description_reject: "Gostaria de proibir temporariamente este usuário por causa de seu {0}? O usuário será suspenso temporariamente até que eles reescrevam seu {0}."
title_notify: "Notificar o usuário da suspensão temporária"
description_notify: "Suspender este usuário temporariamente desativará sua conta e esconderá todos os seus comentários no site."
description_notify: "Suspender este usuário temporariamente desativará sua conta."
title_reject: "Percebemos que você rejeitou um nome de usuário"
suspend_user: "Suspender usuário"
yes_suspend: "Sim suspender"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "talk",
"version": "3.8.0",
"version": "3.8.1",
"description": "A better commenting experience from Mozilla, The New York Times, and the Washington Post. https://coralproject.net",
"main": "app.js",
"private": true,
+3 -2
View File
@@ -38,7 +38,7 @@ router.get('/', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, nex
const {
value = '',
field = 'created_at',
field = 'publication_date',
page = 1,
asc = 'false',
filter = 'all',
@@ -46,9 +46,10 @@ router.get('/', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, nex
} = req.query;
try {
const order = (asc === 'true') ? 1 : -1;
const queryOpts = {
sort: {[field]: (asc === 'true') ? 1 : -1},
sort: {[field]: order, 'created_at': order},
skip: (page - 1) * limit,
limit
};
+10 -1
View File
@@ -7384,7 +7384,7 @@ react-mdl-selectfield@^0.2.0:
react-dom "^15.3.1"
react-mdl "^1.7.1"
react-mdl@^1.7.1, react-mdl@^1.7.2:
react-mdl@^1.7.1:
version "1.10.3"
resolved "https://registry.yarnpkg.com/react-mdl/-/react-mdl-1.10.3.tgz#f783e26a5eea4154a32129ab2562c09d5eeacf0d"
dependencies:
@@ -7393,6 +7393,15 @@ react-mdl@^1.7.1, react-mdl@^1.7.2:
lodash.isequal "^4.4.0"
prop-types "^15.5.0"
react-mdl@^1.7.2:
version "1.11.0"
resolved "https://registry.yarnpkg.com/react-mdl/-/react-mdl-1.11.0.tgz#7e07ee1009dd9b358b616dc400ff2ae1845a2e67"
dependencies:
clamp "^1.0.1"
classnames "^2.2.3"
lodash.isequal "^4.4.0"
prop-types "^15.5.0"
react-paginate@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/react-paginate/-/react-paginate-5.0.0.tgz#b5c12191ea81adc6d4d1b339b805e81841eaa8ea"