Merge branch 'master' into akismet-bug

This commit is contained in:
Kim Gardner
2018-05-22 12:21:53 -04:00
committed by GitHub
38 changed files with 561 additions and 219 deletions
+2 -1
View File
@@ -7,6 +7,7 @@
"https://nodesecurity.io/advisories/594",
"https://nodesecurity.io/advisories/603",
"https://nodesecurity.io/advisories/611",
"https://nodesecurity.io/advisories/612"
"https://nodesecurity.io/advisories/612",
"https://nodesecurity.io/advisories/654"
]
}
@@ -0,0 +1,16 @@
.external {
margin-bottom: 20px;
}
.separator h5 {
text-align: center;
font-size: 1.2em;
}
.slot > * {
margin-bottom: 8px;
&:last-child {
margin-bottom: 0px;
}
}
@@ -0,0 +1,24 @@
import React from 'react';
import PropTypes from 'prop-types';
import styles from './External.css';
import Slot from 'coral-framework/components/Slot';
import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty';
const External = ({ slot }) => (
<IfSlotIsNotEmpty slot={slot}>
<div>
<div className={styles.external}>
<Slot fill={slot} className={styles.slot} />
</div>
<div className={styles.separator}>
<h5>Or</h5>
</div>
</div>
</IfSlotIsNotEmpty>
);
External.propTypes = {
slot: PropTypes.string.isRequired,
};
export default External;
+49 -41
View File
@@ -4,6 +4,7 @@ import styles from './SignIn.css';
import { Button, TextField, Alert } from 'coral-ui';
import cn from 'classnames';
import Recaptcha from 'coral-framework/components/Recaptcha';
import External from './External';
class SignIn extends React.Component {
recaptcha = null;
@@ -33,48 +34,55 @@ class SignIn extends React.Component {
render() {
const { email, password, errorMessage, requireRecaptcha } = this.props;
return (
<form className="talk-admin-login-sign-in" onSubmit={this.handleSubmit}>
{errorMessage && <Alert>{errorMessage}</Alert>}
<TextField
id="email"
label="Email Address"
value={email}
onChange={this.handleEmailChange}
/>
<TextField
id="password"
label="Password"
value={password}
onChange={this.handlePasswordChange}
type="password"
/>
{requireRecaptcha && (
<div className={styles.recaptcha}>
<Recaptcha
ref={this.handleRecaptchaRef}
onVerify={this.props.onRecaptchaVerify}
/>
</div>
)}
<Button
className={cn(styles.signInButton, 'talk-admin-login-sign-in-button')}
type="submit"
cStyle="black"
full
>
Sign In
</Button>
<p className={styles.forgotPasswordCTA}>
Forgot your password?{' '}
<a
href="#"
className={styles.forgotPasswordLink}
onClick={this.handleForgotPasswordLink}
<div className="talk-admin-login-sign-in">
<External slot="authExternalAdminSignIn" />
<form onSubmit={this.handleSubmit}>
{errorMessage && <Alert>{errorMessage}</Alert>}
<TextField
id="email"
label="Email Address"
value={email}
onChange={this.handleEmailChange}
/>
<TextField
id="password"
label="Password"
value={password}
onChange={this.handlePasswordChange}
type="password"
/>
{requireRecaptcha && (
<div className={styles.recaptcha}>
<Recaptcha
ref={this.handleRecaptchaRef}
onVerify={this.props.onRecaptchaVerify}
/>
</div>
)}
<Button
className={cn(
styles.signInButton,
'talk-admin-login-sign-in-button'
)}
type="submit"
cStyle="black"
full
>
Request a new one.
</a>
</p>
</form>
Sign In
</Button>
<p className={styles.forgotPasswordCTA}>
{/* TODO: translate */}
Forgot your password?{' '}
<a
href="#"
className={styles.forgotPasswordLink}
onClick={this.handleForgotPasswordLink}
>
Request a new one.
</a>
</p>
</form>
</div>
);
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withSignIn } from 'coral-framework/hocs';
import { withSignIn, withPopupAuthHandler } from 'coral-framework/hocs';
import { compose } from 'recompose';
import SignIn from '../components/SignIn';
@@ -55,4 +55,4 @@ SignInContainer.propTypes = {
requireRecaptcha: PropTypes.bool.isRequired,
};
export default compose(withSignIn)(SignInContainer);
export default compose(withSignIn, withPopupAuthHandler)(SignInContainer);
+27 -23
View File
@@ -3,32 +3,36 @@ import { getStaticConfiguration } from 'coral-framework/services/staticConfigura
import { createPostMessage } from 'coral-framework/services/postMessage';
document.addEventListener('DOMContentLoaded', () => {
try {
const staticConfig = getStaticConfiguration();
const { STATIC_ORIGIN: origin } = staticConfig;
const postMessage = createPostMessage(origin);
const staticConfig = getStaticConfiguration();
const { STATIC_ORIGIN: origin } = staticConfig;
const postMessage = createPostMessage(origin);
// Get the auth element and parse it as JSON by decoding it.
const auth = document.getElementById('auth');
const doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = auth.innerText;
// Get the auth element and parse it as JSON by decoding it.
const auth = document.getElementById('auth');
const doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = auth.innerText;
// Auth state is contained within the node.
const { err, data } = JSON.parse(doc.body.textContent);
if (err) {
// TODO: send back the error message.
console.error(err);
// Auth state is contained within the node.
const { err, data } = JSON.parse(doc.body.textContent);
if (err) {
const errDiv = document.createElement('div');
if (err.message) {
errDiv.innerText = `${err.name}: ${err.message}`;
} else {
// The data will contain a user and a token.
const { user, token } = data;
// Send the state back.
postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token });
errDiv.innerText = JSON.stringify(err);
}
} finally {
// Always close the window.
setTimeout(() => {
window.close();
}, 50);
document.body.appendChild(errDiv);
throw err;
}
// The data will contain a user and a token.
const { user, token } = data;
// Send the state back.
postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token });
// Close the window when all went well.
setTimeout(() => {
window.close();
}, 50);
});
+1 -1
View File
@@ -116,7 +116,7 @@ export const withRemoveTag = withMutation(
asset_id: assetId,
item_type: itemType,
},
o3timisticResponse: {
optimisticResponse: {
removeTag: {
__typename: 'ModifyTagResponse',
errors: null,
@@ -56,10 +56,10 @@ export function createPostMessage(origin, scope = 'client') {
// Send the message.
target.postMessage(msg, origin);
},
subscribe: (handler, target = window) => {
subscribe(handler, target = window) {
// If this handler is already attached to the target, detach it.
if (has(listeners, [target, handler])) {
this.unsubscribeFromMessages(handler, target);
this.unsubscribe(handler, target);
}
// Wrap the listener with a origin check.
@@ -71,7 +71,7 @@ export function createPostMessage(origin, scope = 'client') {
// Attach the listener to the target.
target.addEventListener('message', listener);
},
unsubscribe: (handler, target = window) => {
unsubscribe(handler, target = window) {
if (!has(listeners, [target, handler])) {
return;
}
+20
View File
@@ -273,3 +273,23 @@ export function translateError(error) {
}
return error.toString();
}
/**
* handlePopupAuth will optionally open a popup with the requested uri if the
* window is not already a popup.
*
* @param {String} uri the url to open the window? to
* @param {String} title the title of the new window? to open
* @param {String} features the features to use when opening a window?
*/
export function handlePopupAuth(
uri,
title = 'Login', // TODO: translate
features = 'menubar=0,resizable=0,width=500,height=550,top=200,left=500'
) {
if (window.opener) {
window.location = uri;
} else {
window.open(uri, title, features);
}
}
+48 -12
View File
@@ -20,10 +20,13 @@ de:
bio_offensive: "Diese Biographie ist unangemessen"
cancel: "Abbrechen"
confirm_email:
email_confirmation: "E-Mail-Bestätigung"
click_to_confirm: "Unten klicken, um E-Mail-Adresse zu bestätigen"
confirm: "Bestätigen"
password_reset:
mail_sent: 'Falls Sie eine registriertes Konto haben, wurde Ihnen ein Zurücksetzen-Link an diese E-Mail-Adresse geschickt'
set_new_password: "Passwort ändern"
change_password_help: "Bitte geben Sie ein neues Passwort ein. Benutzen Sie ein sicheres!"
new_password: "Neues Passwort"
new_password_help: "Das Passwort benötigt mindestens 8 Zeichen"
confirm_new_password: "Neues Passwort bestätigen"
@@ -120,11 +123,12 @@ de:
custom_css_url: "Benutzerdefinierte CSS-URL"
custom_css_url_desc: "URL eines CSS-Stylesheets zum Überschreiben des Standard-Designs"
days: Tage
description: "Als Administrator können Sie die Einstellungen für den Kommentarbereich dieses Artikels anpassen:"
description: "Ändern Sie die Einstellungen für den Kommentarbereich dieses Artikels."
disable_commenting_title: "Kommentieren global deaktivieren"
disable_commenting_desc: "Verfassen Sie eine Nachricht, die angezeigt wird, solange das Kommentieren deaktiviert ist."
domain_list_text: "Geben Sie Domains an, für die diese Talk-Instanz freigegeben werden soll, z.B. für lokale Test- oder Produktionsumgebungen (Bsp.: localhost:3000 staging.domain.com domain.com)."
domain_list_title: "Zugelassene Domains"
edit_info: "Information bearbeiten"
edit_comment_timeframe_heading: "Zeitlimit zur Bearbeitung von Kommentaren"
edit_comment_timeframe_text_pre: "Kommentatoren haben"
edit_comment_timeframe_text_post: "Sekunden Zeit, um ihre Kommentare zu bearbeiten."
@@ -150,17 +154,31 @@ de:
open_stream_configuration: "Dieser Kommentarbereich ist momentan geöffnet. Nach dem Schließen dieses Kommentarbereich wird es nicht mehr möglich sein, zu kommentieren. Bestehende Kommentare bleiben sichtbar."
require_email_verification: "E-Mail-Bestätigung erforderlich"
require_email_verification_text: "Neue Nutzer müssen ihre E-Mail-Adresse bestätigen."
save: "Speichern"
save_changes: "Änderungen speichern"
shortcuts: Tastaturkürzel
sign_out: "Abmelden"
stories: Artikel
stream_settings: "Einstellungen Kommentarbereich"
access_message: "Sie müssen Administrator sein, um auf die Einstellungen zuzugreifen. Fragen Sie ggf. einen Administrator, der Ihnen mehr Recht zuweisen kann!"
suspect_word_title: "Liste verdächtiger Wörter"
suspect_word_text: "Kommentare, die diese Wörter oder Phrasen enthalten (unabhängig von Groß-/Kleinschreibung), werden im Kommentarbereich markiert. Geben Sie ein Wort ein und bestätigen Sie mit Eingabetaste oder Tab. Es ist auch möglich, einen komma-separierten Text einzufügen."
tech_settings: "Technische Einstellungen"
organization_information: "Über die Organisation"
organization_info_copy: "Wir verwenden diese Informationen in automatisierten E-Mail-Benachrichtigungen, die Talk versendet. Damit können Nutzer Ihre Organisation identifizieren und sie haben die Möglichkeit bei Problemen in Kontakt mit Ihnen zu treten."
organization_info_copy_2: "Wir empfehlen, einee generische E-Mail-Adresse (z.B. community@yournewsroom.com) für diesen Zweck einzurichten. Die kann über die Zeit gleich bleiben, und gibt nach außen keine Namen preis, die von Nutzern im Fall von Konflikten für persönliche Angriffe missbraucht werden könnten."
organization_details: "Details zur Organisation"
organization_name: "Name der Organisation"
organization_contact_email: "E-Mail-Adresse der Organisation"
title: "Kommentarbereich konfigurieren"
weeks: Wochen
wordlist: "Gesperrte Wörter"
save_changes_dialog:
unsaved_changes: "Ungespeicherte Änderungen"
copy: "Sie haben einen oder mehrere Änderungen vorgenommen, ohne zu speichern. Möchten Sie jetzt speichern oder die Änderungen verwerfen?"
save_settings: "Einstellungen speichern"
discard: "Verwerfen"
cancel: "Abbrechen"
continue: "Fortfahren"
createdisplay:
check_the_form: "Ungültige Eingabe. Bitte prüfen Sie die Felder."
@@ -202,11 +220,17 @@ de:
we_received_a_request: "Wir haben eine Anfrage erhalten, Ihr Passwort zurückzusetzen. Sollten Sie dies nicht angefordert haben, können Sie diese Nachricht ignorieren."
if_you_did: "Falls doch,"
please_click: "klicken Sie bitte hier zum Zurücksetzen"
subject: "Passwort zurücksetzen"
password_change:
subject: "{0} Passwort-Änderung"
body: "Das Passwort Ihres Benutzerkontos wurde geändert.\n\nFalls Sie diese Änderung nicht angefordert haben, kontaktieren Sie uns bitte unter {0}."
embedlink:
copy: "In die Zwischenablage kopieren"
error:
PASSWORD_INCORRECT: "Ihr bestehendes Passwort wurde falsch eingegeben"
COMMENT_PARENT_NOT_VISIBLE: "Der Kommentar, auf den Sie antworten möchten, wurde entfernt oder existiert nicht."
EMAIL_VERIFICATION_TOKEN_INVALID: "Code zur E-Mail-Bestätigung ist ungültig."
EMAIL_ALREADY_VERIFIED: "E-Mail-Adresse ist bereits bestätigt."
PASSWORD_RESET_TOKEN_INVALID: "Ihr Link zum Passwort zurücksetzen ist ungültig."
COMMENT_TOO_SHORT: "Kommentare sollten mehr als ein Zeichen enthalten, bitte überprüfen Sie Ihren Kommentar und probieren Sie es erneut."
NOT_AUTHORIZED: "Sie sind nicht berechtigt, diese Aktion auszuführen."
@@ -230,15 +254,20 @@ de:
ALREADY_EXISTS: "Ressource existiert bereits"
INVALID_ASSET_URL: "Asset-URL ist ungültig"
CANNOT_IGNORE_STAFF: "Mitarbeiter können nicht ignoriert werden."
email: "E-Mail-Adresse ungültig"
INCORRECT_PASSWORD: "Falsches Passwort"
email: "Bitte geben Sie eine gültige E-Mail-Adresse ein."
DELETION_NOT_SCHEDULED: "Löschvorgang wurde nicht geplant"
confirm_password: "Passwörter nicht identisch. Bitte erneut überprüfen"
network_error: "Server-Verbindung fehlgeschlagen. Bitte überprüfen Sie ihre Internetverbindung und versuchen Sie es erneut."
email_not_verified: "E-Mail-Adresse {0} nicht bestätigt."
email_password: "E-Mail und/oder Passwort inkorrekt."
organization_name: "Namen von Organisationen dürfen nur Buchstaben und Zahlen enthalten."
organization_contact_email: "E-Mail-Adresse der Organisation ist ungültig."
password: "Passwort muss mindestens 8 Zeichen enthalten"
username: "Nutzernamen dürfen nur Buchstaben, Zahlen und _ enthalten"
unexpected: "Unerwarteter Fehler aufgetreten. Es tut uns leid!"
required_field: "Dieses Feld ist erforderlich"
temporarily_suspended: "Ihr Konto ist vorübergehend gesperrt. Es wird wieder aktiviert am {0}. Bei Fragen setzen Sie sich mit uns in Kontakt."
flag_comment: "Kommentar melden"
flag_reason: "Grund der Meldung (optional)"
flag_username: "Nutzername melden"
@@ -248,6 +277,7 @@ de:
comment: Kommentar
comment_is_ignored: "Dieser Kommentar ist nicht sichtbar, da Sie den Nutzer ignorieren."
comment_is_rejected: "Sie haben diesen Kommentar abgelehnt."
comment_is_deleted: "Der Kommentar wurde vom Nutzer gelöscht."
comment_is_hidden: "Dieser Kommentar ist nicht verfügbar."
comments: Kommentare
configure_stream: "Konfigurieren"
@@ -336,6 +366,7 @@ de:
sort: "Sortieren"
show_shortcuts: "Tastaturkürzel anzeigen"
singleview: "Zen-Modus"
system_withheld: "System Withheld"
thismenu: "Dieses Menü öffnen"
jump_to_queue: "Zu bestimmter Liste springen"
thousand: T
@@ -358,6 +389,9 @@ de:
report_notif: "Vielen Dank für Ihre Meldung. Unsere Moderatoren wurden informiert und werden sich in Kürze darum kümmern."
report_notif_remove: "Ihre Meldung wurde entfernt."
reported: Gemeldet
comment_history_blank:
title: Sie haben noch keine Kommentare verfasst
info: Hier wird ein Verlauf Ihrer verfassten Kommentare erscheinen
settings:
from_settings_page: "Sie können auf Ihrer Profilseite Ihren Kommentarverlauf einsehen."
my_comment_history: "Mein Kommentarverlauf"
@@ -369,7 +403,7 @@ de:
stream:
all_comments: "Alle Kommentare"
temporarily_suspended: "Entsprechend der Community-Regeln von {0} wurde Ihr Konto vorübergehend gesperrt. Nehmen Sie {1} wieder an der Diskussion teil."
comment_not_found: "Kommentar nicht gefunden"
comment_not_found: "Dieser Kommentar wurde entfernt oder existiert nicht."
no_comments: "Es gibt noch keine Kommentare. Schreiben Sie doch einen..."
no_comments_and_closed: "Es gab zu diesem Artikel keine Kommentare."
step_1_header: "Ein Problem melden"
@@ -396,6 +430,8 @@ de:
one_hour: "1 Stunde"
hours: "{0} Stunden"
days: "{0} Tage"
hour: "{0} hours"
day: "{0} days"
cancel: "Abbrechen"
suspend_user: "Nutzer vorübergehend sperren"
email_message_suspend: "Sehr geehrte/r {0}, entsprechend der Community-Richtlinien von {1} wurde Ihr Konto vorübergehend gesperrt. Während der Sperrung können Sie weder kommentieren noch andere Aktionen ausführen. Nehmen Sie {2} wieder an der Diskussion teil."
@@ -435,15 +471,15 @@ de:
rejected: "Abgelehnte"
user_history: "Konto-Verlauf"
user_history:
user_banned: "User banned"
ban_removed: "Ban removed"
username_status: "Username {0}"
suspended: "Suspended, {0}"
suspension_removed: "Suspension removed"
user_banned: "Nutzer gesperrt"
ban_removed: "Sperrung aufgehoben"
username_status: "Nutzername {0}"
suspended: "Vorübergehend gesperrt, {0}"
suspension_removed: "Vorübergehende Sperrung aufgehoben"
system: "System"
date: "Date"
action: "Action"
taken_by: "Taken By"
date: "Datum"
action: "Aktion"
taken_by: "Durch"
user_impersonating: "Gibt sich für jemand anderen aus"
user_no_comment: "Sie haben noch keinen Kommentar abgegeben. Teilen Sie Ihre Meinung mit uns!"
username_offensive: "Dieser Nutzername ist unangemessen"
@@ -461,7 +497,7 @@ de:
username: "Nutzername"
password: "Passwort"
confirm_password: "Passwort bestätigen"
organization_contact_email: "Organization Contact Email"
organization_contact_email: "Kontakt-Adresse der Organisation"
save: "Speichern"
permitted_domains:
title: "Zugelassene Domains"
+10
View File
@@ -339,6 +339,11 @@ User.virtual('banned')
})
.set(function(status) {
this.status.banned.status = status;
if (!this.status.banned.history) {
this.status.banned.history = [];
}
this.status.banned.history.push({
status,
created_at: new Date(),
@@ -357,6 +362,11 @@ User.virtual('suspended')
})
.set(function(until) {
this.status.suspension.until = until;
if (!this.status.suspension.history) {
this.status.suspension.history = [];
}
this.status.suspension.history.push({
until,
created_at: new Date(),
+2 -2
View File
@@ -149,7 +149,7 @@
"metascraper-title": "^3.9.2",
"minimist": "^1.2.0",
"moment": "^2.18.1",
"mongoose": "^4.12.3",
"mongoose": "^5.1.1",
"ms": "^2.0.0",
"murmurhash-js": "^1.0.0",
"name-all-modules-plugin": "^1.0.1",
@@ -231,7 +231,7 @@
"husky": "^0.14.3",
"identity-obj-proxy": "^3.0.0",
"jest-junit": "^3.6.0",
"lint-staged": "^7.0.0",
"lint-staged": "^7.1.0",
"mocha": "^3.1.2",
"mocha-junit-reporter": "^1.12.1",
"nightwatch": "^0.9.16",
+1
View File
@@ -9,4 +9,5 @@ export {
getDefinitionName,
getShallowChanges,
createDefaultResponseFragments,
handlePopupAuth,
} from 'coral-framework/utils';
@@ -1,3 +1,5 @@
import { handlePopupAuth } from 'plugin-api/beta/client/utils';
export const loginWithFacebook = () => (dispatch, _, { rest }) => {
window.location = `${rest.uri}/auth/facebook`;
handlePopupAuth(`${rest.uri}/auth/facebook`);
};
@@ -5,6 +5,7 @@ import translations from './translations.yml';
export default {
translations,
slots: {
authExternalAdminSignIn: [SignIn],
authExternalSignIn: [SignIn],
authExternalSignUp: [SignUp],
},
@@ -1,3 +1,5 @@
import { handlePopupAuth } from 'plugin-api/beta/client/utils';
export const loginWithGoogle = () => (dispatch, _, { rest }) => {
window.location = `${rest.uri}/auth/google`;
handlePopupAuth(`${rest.uri}/auth/google`);
};
@@ -5,6 +5,7 @@ import translations from './translations.yml';
export default {
translations,
slots: {
authExternalAdminSignIn: [SignIn],
authExternalSignIn: [SignIn],
authExternalSignUp: [SignUp],
},
@@ -69,6 +69,76 @@ en:
description_2: "You can change your account settings by visiting"
path: "My Profile > Settings"
alert: "Email Added!"
de:
email:
email_change_original:
subject: Änderung Ihrer E-Mail-Adresse
body: Ihre E-Mail-Adresse wurde von {0} zu {1} geändert. Falls Sie diese Änderung nicht selbst vorgenommen haben, kontaktieren Sie bitte zur Sicherheit {2}.
error:
NO_LOCAL_PROFILE: Mit diesem Benutzerkonto ist keine E-Mail-Adresse verbunden.
LOCAL_PROFILE: Es ist bereits eine bestätigte E-Mail-Adresse mit diesem Benutzerkonto verbunden.
INCORRECT_PASSWORD: Das Passwort war nicht korrekt.
talk-plugin-local-auth:
change_password:
change_password: "Passwort ändern"
passwords_dont_match: "Die Passwörter stimmen nicht überein"
required_field: "Diese Angabe ist erforderlich"
forgot_password: "Passwort vergessen?"
save: "Speichern"
cancel: "Abbrechen"
edit: "Ändern"
changed_password_msg: "Passwort geändert - Ihr Passwort wurde erfolgreich geändert"
forgot_password_sent: "Passwort vergessen - Wir haben Ihnen eine E-Mail zum Zurücksetzen des Passwortes geschickt"
change_username:
change_username_note: "Nutzernamen können nur alle 14 Tage geändert werden. Ihr Nutzername ist zur Zeit nicht editierbar."
save: "Speichern"
edit_profile: "Profil ändern"
cancel: "Abbrechen"
confirm_username_change: "Änderung des Nutzernamens bestätigen"
description: "Sie möchten Ihren Nutzernamen ändern: der neue Nutzername wird an allen alten und neuen Kommentaren erscheinen."
old_username: "Alter Nutzername"
new_username: "Neuer Nutzername"
bottom_note: "Achtung: die nächste Änderung des Nutzernamens ist erst nach 14 Tagen möglich"
confirm_changes: "Änderung bestätigen"
username_does_not_match: "Die Nutzernamen stimmen nicht überein"
cant_be_equal: "Der neue Nutzername {0} muss sich vom alten unterscheiden."
changed_username_success_msg: "Nutzername geändert - Ihr Nutzername wurde erfolgreich aktualisiert. Die nächste Änderung des Nutzernamens ist erst nach 14 Tagen möglich."
change_username_attempt: "Der Nutzername kann zur Zeit nicht aktualisiert werden. Änderungen sind nur nach jeweils 14 Tagen möglich."
change_email:
confirm_email_change: "Änderung der E-Mail-Adresse bestätigen"
description: "Sie versuchen, Ihre E-Mail-Adresse ändern: die neue E-Mail-Adresse wird zum Login sowie für Benachrichtigungen bzgl. Ihres Benutzerkontos verwendet."
old_email: "Alte E-Mail-Adresse"
new_email: "Neue E-Mail-Adresse"
enter_password: "Passwort"
incorrect_password: "Passwort nicht korrekt"
confirm_change: "Änderung bestätigen"
cancel: "Abbrechen"
change_email_msg: "E-Mail-Adresse erfolgreich aktualisiert - die neue E-Mail-Adresse ab sofort zum Anmelden und für Benachrichtigungen verwendet."
add_email:
add_email_address: "E-Mail-Adresse hinzufügen"
enter_email_address: "E-Mail-Adresse:"
invalid_email_address: "Ungültige E-Mail-Adresse"
confirm_email_address: "Bestätigung der E-Mail-Adresse:"
email_does_not_match: "Die E-Mail-Adressen stimmen nicht überein"
insert_password: "Passwort auswählen:"
required_field: "Dieses Feld ist erforderlich"
done: "Fertig"
content:
title: "E-Mail-Adresse hinzufügen"
description: "Aus Sicherheitsgründen benötigen wir eine E-Mail-Adresse zu jedem Benutzerkonto. Ihre E-Mail-Adresse wird für folgendes verwendet:"
item_1: "Benachrichtigungen über Änderungen am Benutzerkonto (Nutzername, E-Mail-Adresse, Passwort)"
item_2: "Ermöglicht den Download des eigenen Kommentar-Archivs"
item_3: "Kommentar-Benachrichtigungen erhalten, die Sie explizit angefordert haben"
verify:
title: "E-Mail-Adresse bestätigen"
description: "Wir haben einen E-Mail an {0} geschickt. Bitte bestätigen Sie Ihre E-Mail-Adresse, um damit Benachrichtigungen über Änderungen am Benutzerkonto zu erhalten."
added:
title: "E-Mail-Adresse hinzugefügt"
description: "Ihre E-Mail-Adresse wurde dem Benutzerkonto hinzugefügt."
subtitle: "Sie möchten Ihre E-Mail-Adresse ändern?"
description_2: "Sie können Ihre Konto-Einstellugen ändern unter"
path: "Mein Profil > Profil-Einstellungen"
alert: "E-Mail-Adresse hinzugefügt!"
es:
talk-plugin-local-auth:
change_password:
@@ -1,3 +1,6 @@
en:
talk-plugin-notifications-category-featured:
toggle_description: My comment is featured
de:
talk-plugin-notifications-category-featured:
toggle_description: Mein Kommentar wird empfohlen
@@ -3,4 +3,10 @@ en:
categories:
featured:
subject: "One of your comments was featured on {0}"
body: "{0}\nA member of our team has selected this comment to be featured for other readers: {1}"
body: "{0}\nA member of our team has selected this comment to be featured for other readers: {1}"
de:
talk-plugin-notifications:
categories:
featured:
subject: "Einer Ihrer Kommentare wurde auf {0} hervorgehoben"
body: "{0}\nEin Mitglied unseres Teams hat diesen Kommentar ausgewählt, er wird jetzt für andere Leser besonders hervorgehoben: {1}"
@@ -1,3 +1,6 @@
en:
talk-plugin-notifications-category-reply:
toggle_description: My comment receives a reply
de:
talk-plugin-notifications-category-reply:
toggle_description: Jemand antwortet auf meinen Kommentar
@@ -3,4 +3,10 @@ en:
categories:
reply:
subject: "Someone has replied to your comment on {0}"
body: "{0}\n{1} replied to your comment: {2}"
body: "{0}\n{1} replied to your comment: {2}"
de:
talk-plugin-notifications:
categories:
reply:
subject: "Jemand hat bei {0} auf Ihren Kommentar geantwortet"
body: "{0}\n{1} antwortete auf Ihren Kommentar: {2}"
@@ -1,3 +1,6 @@
en:
talk-plugin-notifications-category-staff:
toggle_description: A staff member replies to my comment
de:
talk-plugin-notifications-category-staff:
toggle_description: Ein Redaktionsmitglied antwortet auf meinen Kommentar
@@ -3,4 +3,10 @@ en:
categories:
staff:
subject: "Someone at {0} has replied to your comment"
body: "{0}\n{1} works for {2} and has replied to your comment: {3}"
body: "{0}\n{1} works for {2} and has replied to your comment: {3}"
de:
talk-plugin-notifications:
categories:
staff:
subject: "Jemand hat bei {0} auf Ihren Kommentar geantwortet"
body: "{0}\n{1} arbeitet für {2} und hat auf Ihren Kommentar geantwortet: {3}"
@@ -2,3 +2,7 @@ en:
talk-plugin-notifications:
digest_enum:
DAILY: In a daily digest
de:
talk-plugin-notifications:
digest_enum:
DAILY: Einmal täglich
@@ -2,3 +2,7 @@ en:
talk-plugin-notifications:
digest_enum:
HOURLY: In an hourly digest
de:
talk-plugin-notifications:
digest_enum:
HOURLY: Stündlich
@@ -16,3 +16,21 @@ en:
digest_option: Send notifications
digest_enum:
NONE: Immediately
de:
talk-plugin-notifications:
settings_title: Benachrichtigungen
settings_subtitle: Benachrichtige mich wenn
turn_off_all: Ich möchte keine Benachrichtigungen erhalten
banner_info:
title: Bestätigte E-Mail-Adresse benötigt
text: Um E-Mail-Benachrichtigungen zu erhalten, müssen Sie eine bestätigte E-Mail-Adresse haben.
verify_now: E-Mail-Adresse jetzt bestätigen
banner_success:
title: E-Mail-Bestätigungsanfrage verschickt
text: Eine E-Mail mit einem Bestätigungslink wurde an {0} geschickt.
banner_error:
title: Fehler
text: Beim Versand der Bestätigungsmail gab es einen Fehler. Bitte versuchen Sie es später erneut.
digest_option: Benachrichtigungen senden
digest_enum:
NONE: Sofort
@@ -11,4 +11,18 @@ en:
click_to_confirm: "Click below to confirm that you would like to unsubscribe from all notifications"
confirm: "Confirm"
are_unsubscribed: "You are now unsubscribed from all notifications."
token_invalid: "Unsubscribe link is invalid, click the link from a more recent email or visit a comment stream and login to change your notification preferences"
token_invalid: "Unsubscribe link is invalid, click the link from a more recent email or visit a comment stream and login to change your notification preferences"
de:
talk-plugin-notifications:
templates:
digest:
subject: "Ihre Kommentaraktivität bei {0}"
footer: "Sie erhalten diese Benachrichtigung, weil Sie Community-Mitglied bei {0} sind und diese E-Mails abonniert haben."
links:
unsubscribe: "E-Mail-Benachrichtigungen abbestellen"
unsubscribe_page:
unsubscribe: "Kommentar-Benachrichtigungen abbestellen"
click_to_confirm: "Klicken Sie folgenden Link, um zu bestätigen, dass Sie alle Benachrichtigungen abbestellen möchten"
confirm: "Bestätigen"
are_unsubscribed: "Sie haben haben alle Benachrichtigungen erfolgreich abbestellt."
token_invalid: "Der Abbestell-Link ist ungültig. Klicken Sie den Link einer neueren E-Mail oder gehen Sie zu einem Kommentarbereich, melden Sie sich an und ändern Sie dort Ihre Benachrichtigungseinstellungen"
@@ -63,17 +63,18 @@ class DeleteMyAccount extends React.Component {
<p className="talk-plugin-auth--delete-my-account-description">
{t('delete_request.delete_my_account_description')}
</p>
<p className="talk-plugin-auth--delete-my-account-description">
{scheduledDeletionDate &&
t(
'delete_request.already_submitted_request_description',
moment(scheduledDeletionDate).format('MMM Do YYYY, h:mm:ss a')
)}
</p>
{scheduledDeletionDate ? (
<Button onClick={this.cancelAccountDeletion}>
{t('delete_request.cancel_account_deletion_request')}
</Button>
<div>
<p className="talk-plugin-auth--delete-my-account-description">
{t(
'delete_request.already_submitted_request_description',
moment(scheduledDeletionDate).format('MMM Do YYYY, h:mm:ss a')
)}
</p>
<Button onClick={this.cancelAccountDeletion}>
{t('delete_request.cancel_account_deletion_request')}
</Button>
</div>
) : (
<Button icon="delete" onClick={this.showDialog}>
{t('delete_request.delete_my_account')}
@@ -1,6 +1,9 @@
.button {
margin: 0;
&:disabled {
/* TODO: better optimize for mobile so this styling is not necessary */
height: auto;
}
i {
font-size: inherit;
vertical-align: sub;
@@ -49,3 +49,54 @@ en:
subtitle: "Are you sure you want to delete your account?"
description: "To confirm you would like to delete your account please type in the following phrase into the text box below:"
type_to_confirm: "Type phrase below to confirm"
de:
download_request:
section_title: "Mein Kommentar-Archiv herunterladen"
you_will_get_a_copy: "Sie werden eine E-Mail mit einem Download-Link erhalten. Sie können"
download_rate: "eine Download-Anfrage alle {0} Tage stellen"
most_recent_request: "Ihre letzte Anfrage"
request: "Kommentar-Archiv anfordern"
rate_limit: "Sie können die nächste Anfrage stellen in {0}"
hours: "{0} Stunden"
days: "{0} Tagen"
hour: "{0} Stunde"
day: "{0} Tag"
download_preparing: "Bereite Konto-Download vor - Überprüfen Sie Ihr E-Mail-Postfach, sie sollten den Download-Link demnächst erhalten"
delete_request:
account_deletion_cancelled: 'Konto-Löschung abgebrochen - Ihre Anfrage, Ihr Konto zu löschen wurde abgebrochen.'
account_deletion_requested: 'Konto-Löschung angefordert'
received_on: "Die Anfrage, Ihr Konto zu löschen haben wir erhalten am "
cancel_request_description: "Fall Sie ihr Konto wieder aktivieren möchten, können Sie die Lösch-Anfrage hier abbrechen"
before: "vorher"
cancel_account_deletion_request: "Konto-Lösch-Anfrage abbrechen"
delete_my_account: "Mein Benutzerkonto löschen"
delete_my_account_description: "Mit dem Löschen Ihres Kontos werden Ihr Profil sowie alle Ihre Kommentare dauerhaft von dieser Website entfernt."
already_submitted_request_description: "Sie haben bereits eine Lösch-Anfrage gestellt. Ihr Konto wird nach dem {0} gelöscht. Bis zu diesem Zeitpunkt können Sie die Anfrage noch abbrechen"
your_request_submitted_description: "Ihre Lösch-Anfrage wurde übermittelt und eine Bestätigungsanfrage an die dem Konto zugehörige E-Mail-Adresse geschickt."
your_account_deletion_scheduled: "Ihr Benutzerkonto wird gelöscht nach dem:"
changed_your_mind: "Haben Sie Ihre Meinung geändert?"
simply_go_to: "Gehen Sie einfach vor dem Zeitpunkt zu Ihrem Konto und klicken Sie"
tell_us_why: "Sagen Sie uns warum"
feedback_copy: "Wir würden gern erfahren, warum Sie sich entschieden haben, Ihr Konto zu löschen. Schicken Sie uns eine E-Mail mit Feedback an"
done: "Fertig"
cancel: "Abbrechen"
proceed: "Fortfahren"
input_is_not_correct: "Die Eingabe ist nicht korrekt"
step_0:
you_are_attempting: "Sie versuchen Ihr Konto zu löschen. Das bedeutet:"
item_1: "Alle Ihre Kommentare werden von der Website entfernt"
item_2: "Alle Ihre Kommentare werden aus unserer Datenbank gelöscht"
item_3: "Ihr Nutzername und Ihre E-Mail-Adresse werden aus unserem System gelöscht"
step_1:
subtitle: "Wann wird mein Benutzerkonto entfernt?"
description: "Ihr Konto wird {0} Stunden nachdem Sie die Anfrage gestellt haben gelöscht."
subtitle_2: "Kann ich weiterhin Kommentare schreiben, bis mein Konto gelöscht wird?"
description_2: "Ja, Sie können kommentieren, antworten usw. bis die {0} Stunden abgelaufen sind."
step_2:
description: "Bevor Ihr Konto gelöscht wird, empfehlen wir Ihnen, Ihr Kommentar-Archiv herunterzuladen. Nach der Konto-Löschung ist dies nicht mehr möglich."
to_download: "Um Ihr Konto-Archiv herunterzuladen gehen sie zu:"
path: "Profil > Mein Kommentar-Archiv herunterladen"
step_3:
subtitle: "Sind Sie sicher, dass Sie Ihr Benutzerkonto löschen möchten?"
description: "Um zu bestätigen, dass Sie Ihr Konto löschen möchten, geben Sie bitte folgende Zeichen in das Textfeld ein:"
type_to_confirm: "Zur Bestätigung Zeichenfolge eingeben"
@@ -35,3 +35,40 @@ en:
body: "You have cancelled your account deletion request for {0}. Your account is now reactivated."
error:
DOWNLOAD_TOKEN_INVALID: "Your download link is not valid."
de:
download_landing:
download_your_account: "Mein Kommentar-Archiv herunterladen"
download_details: "Ihr Kommentar-Archiv wird als ZIP-Datei bereitgestellt. Nach dem Entpacken erhalten Sie eine CSV-Datei, die einfach in ein Tabellenkalkulationsprogramm importiert werden kann."
all_information_included: "Für jeden Ihrer Kommentare sind folgende Informationen enthalten:"
information_included:
date: "Wann Sie den Kommentar geschrieben haben"
url: "Die dauerhafte URL (Internetadresse) des Kommentars"
body: "Der Kommentar-Text"
asset_url: "Die URL (Internetadresse) des Artikels an dem der Kommentar erscheint"
confirm: "Kommentar-Archiv herunterladen"
email:
download:
subject: "Ihre Kommentare sind zum Download bereit: {0}"
download_link_ready: "Hier klicken, um Ihre Kommentare von {0} bis {1} herunterzuladen:"
download_archive: "Archiv herunterladen"
delete:
subject: "Ihr Benutzerkonto bei {0} ist zur Löschung vorgesehen"
body: |
Wir haben eine Anfrage erhalten, Ihr Benutzerkonto zu löschen. Die Löschung ist geplant für den {1}.
Nach diesem Zeitpunkt werden alle Ihre Kommentare von der Website und aus unserer Datenbank gelöscht. Außerdem werden Ihr Nutzername und Ihre E-Mail-Adresse aus unserem System enfernt.
Falls Sie es sich noch anders überlegen, können Sie sich bis spätestens zum angegebenen Lösch-Zeitpunkt einloggen und die Lösch-Anfrage abbrechen.
deleted:
subject: "Ihre Benutzerkonto bei {0} wurde gelöscht"
body: |
Ihr Kommentar-Konto bei {0} ist nun gelöscht. Schade, auf Wiedersehen!
Falls Sie sich in Zukunft erneut an der Diskussion beteiligen möchten, können Sie jederzeit ein neues Benutzerkonto einrichten.
Wenn Sie Lust haben, schreiben Sie uns doch eine Rückmeldung, Feedback, oder Kritik an {1}, damit wir unsere Community verbessern können. Vielen Dank!
cancelDelete:
subject: "Die Lösch-Anfrage für Ihr Benutzerkonto bei {0} wurde abgebrochen"
body: "Sie haben die Lösch-Anfrage für Ihr Benutzerkonto bei {0} abgebrochen. Das Konto ist nun wieder aktiv."
error:
DOWNLOAD_TOKEN_INVALID: "Der Download-Link ist ungültig."
@@ -7,21 +7,17 @@ class Button extends React.Component {
render() {
const {
className,
title,
onClick,
children,
active,
activeClassName,
disabled,
...rest
} = this.props;
return (
<button
className={cn(className, styles.button, {
[cn(styles.active, activeClassName)]: active,
})}
title={title}
onClick={onClick}
disabled={disabled}
{...rest}
>
{children}
</button>
@@ -32,11 +28,8 @@ class Button extends React.Component {
Button.propTypes = {
className: PropTypes.string,
activeClassName: PropTypes.string,
title: PropTypes.string,
onClick: PropTypes.func,
children: PropTypes.node,
active: PropTypes.bool,
disabled: PropTypes.bool,
};
export default Button;
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import Button from '../components/Button';
import bowser from 'bowser';
/**
* createToggle creates a button that can be active, inactive or disabled
@@ -32,7 +33,17 @@ const createToggle = (
this.execCommand();
};
// Detect whether there was focus on the RTE before the click.
hadFocusBeforeClick = false;
handleMouseDown = () => (this.hadFocusBeforeClick = this.props.api.focused);
handleClick = () => {
// Skip IOS when the focus was not there before.
// IOS fails to focus to the RTE correctly and scrolls to nirvana.
// See https://www.pivotaltracker.com/story/show/157607216
if (!this.hadFocusBeforeClick && bowser.ios) {
return;
}
this.props.api.focus();
this.formatToggle();
this.props.api.focus();
@@ -62,6 +73,7 @@ const createToggle = (
<Button
className={className}
title={title}
onMouseDown={this.handleMouseDown}
onClick={this.handleClick}
active={this.state.active}
disabled={disabled || this.state.disabled}
@@ -381,9 +381,13 @@ export function isBogusBR(node) {
}
/**
* Returns an array of all nodes after `node`.
* Returns an array of all nodes after `node` in a _line_.
*/
export function getRightOfNode(node) {
if (node.tagName === 'BR') {
return [];
}
let result = [];
let cur = node;
while (
@@ -515,10 +519,10 @@ export function outdentBlock(node, changeSelection) {
// A new lines to substitute the missing block element.
const needLineAfter =
node.nextSibling &&
!isBlockElement(node.nextSibling) &&
node.lastChild &&
!isBlockElement(node.lastChild);
!node.lastChild ||
(node.nextSibling &&
!isBlockElement(node.nextSibling) &&
!isBlockElement(node.lastChild));
const needLineBefore =
node.previousSibling &&
!isBlockElement(node.previousSibling) &&
+22 -27
View File
@@ -2,7 +2,7 @@ const ActionModel = require('../models/action');
const CommentModel = require('../models/comment');
const UserModel = require('../models/user');
const _ = require('lodash');
const errors = require('../errors');
const { ErrAlreadyExists } = require('../errors');
const incrActionCounts = async (action, value) => {
const ACTION_TYPE = action.action_type.toLowerCase();
@@ -41,35 +41,30 @@ const incrActionCounts = async (action, value) => {
* @param {object} update the update operation for the mongo findOneAndUpdate op
* @param {object} options the options operation for the mongo findOneAndUpdate op
*/
const findOnlyOneAndUpdate = async (query, update, options = {}) =>
new Promise((resolve, reject) => {
ActionModel.findOneAndUpdate(
query,
update,
Object.assign({}, options, {
// Use raw result to get `updatedExisting`.
passRawResult: true,
const findOnlyOneAndUpdate = async (query, update, options = {}) => {
const raw = await ActionModel.findOneAndUpdate(
query,
update,
Object.assign({}, options, {
// Use raw result to get `updatedExisting`.
rawResult: true,
// Ensure that if it's new, we return the new object created.
new: true,
// Ensure that if it's new, we return the new object created.
new: true,
// Perform an upsert in the event that this doesn't exist.
upsert: true,
// Perform an upsert in the event that this doesn't exist.
upsert: true,
// Set the default values if not provided based on the mongoose models.
setDefaultsOnInsert: true,
}),
(err, doc, raw) => {
if (err) {
return reject(err);
}
if (raw.lastErrorObject.updatedExisting) {
return reject(new errors.ErrAlreadyExists(raw.value));
}
return resolve(raw.value);
}
);
});
// Set the default values if not provided based on the mongoose models.
setDefaultsOnInsert: true,
})
);
if (raw.lastErrorObject.updatedExisting) {
throw new ErrAlreadyExists(raw.value);
}
return raw.value;
};
module.exports = class ActionsService {
/**
-1
View File
@@ -45,7 +45,6 @@ if (WEBPACK) {
// Connect to the Mongo instance.
mongoose
.connect(MONGO_URL, {
useMongoClient: true,
config: {
autoIndex: CREATE_MONGO_INDEXES,
},
+59 -75
View File
@@ -1644,6 +1644,10 @@ bson@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.4.tgz#93c10d39eaa5b58415cbc4052f3e53e562b0b72c"
bson@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.6.tgz#444db59ddd4c24f0cb063aabdc5c8c7b0ceca912"
buffer-crc32@^0.2.1, buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -1652,10 +1656,6 @@ buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
buffer-shims@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
@@ -3353,10 +3353,6 @@ es6-map@^0.1.3:
es6-symbol "~3.1.1"
event-emitter "~0.3.5"
es6-promise@3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
es6-promise@^4.0.5:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
@@ -4890,10 +4886,6 @@ home-or-tmp@^2.0.0:
os-homedir "^1.0.0"
os-tmpdir "^1.0.1"
hooks-fixed@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hooks-fixed/-/hooks-fixed-2.0.2.tgz#20076daa07e77d8a6106883ce3f1722e051140b0"
hosted-git-info@^2.1.4:
version "2.5.0"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
@@ -6399,9 +6391,9 @@ jxLoader@*:
promised-io "*"
walker "1.x"
kareem@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.5.0.tgz#e3e4101d9dcfde299769daf4b4db64d895d17448"
kareem@2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.0.7.tgz#8d260366a4df4236ceccec318fcf10c17c5beb22"
keymaster@^1.6.2:
version "1.6.2"
@@ -6528,9 +6520,9 @@ linkifyjs@^2.1.5:
react ">=0.14.0"
react-dom ">=0.14.0"
lint-staged@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.0.tgz#57926c63201e7bd38ca0576d74391efa699b4a9d"
lint-staged@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.1.0.tgz#1514a5b71b8d9492ca0c3d2a44769cbcbc8bcc79"
dependencies:
app-root-path "^2.0.1"
chalk "^2.3.1"
@@ -6541,6 +6533,7 @@ lint-staged@^7.0.0:
execa "^0.9.0"
find-parent-dir "^0.3.0"
is-glob "^4.0.0"
is-windows "^1.0.2"
jest-validate "^22.4.0"
listr "^0.13.0"
lodash "^4.17.5"
@@ -6550,8 +6543,9 @@ lint-staged@^7.0.0:
p-map "^1.1.1"
path-is-inside "^1.0.2"
pify "^3.0.0"
please-upgrade-node "^3.0.1"
staged-git-files "1.1.0"
please-upgrade-node "^3.0.2"
staged-git-files "1.1.1"
string-argv "^0.0.2"
stringify-object "^3.2.2"
listr-silent-renderer@^1.1.1:
@@ -7451,36 +7445,36 @@ moment@^2.15.2:
version "2.22.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad"
mongodb-core@2.1.17:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.17.tgz#a418b337a14a14990fb510b923dee6a813173df8"
mongodb-core@3.0.8:
version "3.0.8"
resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-3.0.8.tgz#8d401f4eab6056c0d874a3d5844a4844f761d4d7"
dependencies:
bson "~1.0.4"
require_optional "~1.0.0"
require_optional "^1.0.1"
mongodb@2.2.33:
version "2.2.33"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.33.tgz#b537c471d34a6651b48f36fdbf29750340e08b50"
mongodb@3.0.8:
version "3.0.8"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.0.8.tgz#2c1daecac9a0ec2de2f2aea4dc97d76ae70f8951"
dependencies:
es6-promise "3.2.1"
mongodb-core "2.1.17"
readable-stream "2.2.7"
mongodb-core "3.0.8"
mongoose@^4.12.3:
version "4.13.7"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.13.7.tgz#f760c770e6c8cdf34a6fe8b7443882b5fced1032"
mongoose-legacy-pluralize@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4"
mongoose@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.1.1.tgz#a7e925607e76032e5ef20b3035a357bc8581b45e"
dependencies:
async "2.1.4"
bson "~1.0.4"
hooks-fixed "2.0.2"
kareem "1.5.0"
bson "~1.0.5"
kareem "2.0.7"
lodash.get "4.4.2"
mongodb "2.2.33"
mpath "0.3.0"
mpromise "0.5.5"
mquery "2.3.3"
mongodb "3.0.8"
mongoose-legacy-pluralize "1.0.2"
mpath "0.4.1"
mquery "3.0.0"
ms "2.0.0"
muri "1.3.0"
regexp-clone "0.0.1"
sliced "1.0.1"
@@ -7509,17 +7503,13 @@ move-concurrently@^1.0.1:
rimraf "^2.5.4"
run-queue "^1.0.3"
mpath@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.3.0.tgz#7a58f789e9b5fd3c94520634157960f26bd5ef44"
mpath@0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.4.1.tgz#ed10388430380bf7bbb5be1391e5d6969cb08e89"
mpromise@0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mpromise/-/mpromise-0.5.5.tgz#f5b24259d763acc2257b0a0c8c6d866fd51732e6"
mquery@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/mquery/-/mquery-2.3.3.tgz#221412e5d4e7290ca5582dd16ea8f190a506b518"
mquery@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.0.0.tgz#e5f387dbabc0b9b69859e550e810faabe0ceabb0"
dependencies:
bluebird "3.5.0"
debug "2.6.9"
@@ -7538,10 +7528,6 @@ ms@^2.0.0, ms@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
muri@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/muri/-/muri-1.3.0.tgz#aeccf3db64c56aa7c5b34e00f95b7878527a4721"
murmurhash-js@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51"
@@ -8556,9 +8542,11 @@ platform@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd"
please-upgrade-node@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.1.tgz#0a681f2c18915e5433a5ca2cd94e0b8206a782db"
please-upgrade-node@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.2.tgz#7b9eaeca35aa4a43d6ebdfd10616c042f9a83acc"
dependencies:
semver-compare "^1.0.0"
pluralize@^1.2.1:
version "1.2.1"
@@ -9717,18 +9705,6 @@ readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stre
string_decoder "~1.0.3"
util-deprecate "~1.0.1"
readable-stream@2.2.7:
version "2.2.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1"
dependencies:
buffer-shims "~1.0.0"
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~1.0.0"
util-deprecate "~1.0.1"
readdirp@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
@@ -10034,7 +10010,7 @@ require-uncached@^1.0.3:
caller-path "^0.1.0"
resolve-from "^1.0.0"
require_optional@~1.0.0:
require_optional@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e"
dependencies:
@@ -10285,6 +10261,10 @@ selenium-standalone@^6.11.0:
which "^1.2.12"
yauzl "^2.5.0"
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
semver-diff@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@@ -10762,9 +10742,9 @@ stack-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620"
staged-git-files@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.0.tgz#1a9bb131c1885601023c7aaddd3d54c22142c526"
staged-git-files@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b"
static-extend@^0.1.1:
version "0.1.2"
@@ -10841,6 +10821,10 @@ strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
string-argv@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736"
string-hash@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
@@ -10875,7 +10859,7 @@ string.prototype.padend@^3.0.0:
es-abstract "^1.4.3"
function-bind "^1.0.2"
string_decoder@^1.0.0, string_decoder@~1.0.0, string_decoder@~1.0.3:
string_decoder@^1.0.0, string_decoder@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
dependencies: