From d9ea5977cd9cd596e81c4b9282512d04d8f22f1f Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 5 Jan 2017 18:24:05 -0300 Subject: [PATCH 001/142] Unique displayName for the User. --- models/user.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/models/user.js b/models/user.js index 7df713337..f4ddbd895 100644 --- a/models/user.js +++ b/models/user.js @@ -46,7 +46,11 @@ const UserSchema = new mongoose.Schema({ // This is sourced from the social provider or set manually during user setup // and simply provides a name to display for the given user. - displayName: String, + displayName: { + type: String, + unique: true, + required: true + }, // This is true when the user account is disabled, no action should be // acknowledged when they are disabled. Logins are also prevented. From 712e436f584f4a7ba861fae0e8b00dfe16caee80 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 6 Jan 2017 16:38:44 -0300 Subject: [PATCH 002/142] Cleans error on email address or name. We need to go through all the errors and manage them better with translations. --- client/coral-framework/actions/auth.js | 4 +++- client/coral-framework/translations.json | 6 ++++-- client/coral-sign-in/translations.js | 2 ++ models/user.js | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index 106224c25..f06ea7526 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -82,7 +82,9 @@ export const fetchSignUp = formData => (dispatch) => { dispatch(changeView('SIGNIN')); }, 3000); }) - .catch(() => dispatch(signUpFailure(lang.t('error.emailInUse')))); // We need to inprove error handling. TODO (bc) + .catch(() => { + dispatch(signUpFailure(lang.t('error.emailORusernameInUse'))); + }); // We need to improve error handling. TODO (bc) }; // Forgot Password Actions diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 06a39944a..99d3341b1 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -10,7 +10,8 @@ "displayName": "Display name is too short", "confirmPassword": "Passwords don`t match. Please, check again", "emailPasswordError": "Email and/or password combination incorrect.", - "emailInUse": "Email address already in use" + "emailInUse": "Email address already in use", + "emailORusernameInUse": "Email address or Username already in use" } }, "es": { @@ -24,7 +25,8 @@ "displayName": "El nombre es muy corto", "confirmPassword": "Las contraseñas no coinciden", "emailPasswordError": "Email y/o contraseña incorrecta.", - "emailInUse": "Email address already in use" + "emailInUse": "Correo electronico en uso.", + "emailORusernameInUse": "Correo o Nombre en uso." } } } diff --git a/client/coral-sign-in/translations.js b/client/coral-sign-in/translations.js index 200cb91f1..a50ad6f54 100644 --- a/client/coral-sign-in/translations.js +++ b/client/coral-sign-in/translations.js @@ -19,6 +19,7 @@ export default { alreadyHaveAnAccount: 'Already have an account?', recoverPassword: 'Recover password', emailInUse: 'Email address already in use', + emailORusernameInUse: 'Email address or Username already in use', requiredField: 'This field is required', passwordsDontMatch: 'Passwords don\'t match.', checkTheForm: 'Invalid Form. Please, check the fields' @@ -44,6 +45,7 @@ export default { alreadyHaveAnAccount: 'Ya tienes una cuenta?', recoverPassword: 'Recuperar contraseña', emailInUse: 'Este email se encuentra en uso', + emailORusernameInUse: 'Este email ó nombre se encuentran en uso', requiredField: 'Este campo es requerido', passwordsDontMatch: 'Las contraseñas no coinciden', checkTheForm: 'Formulario Inválido. Por favor, completa los campos' diff --git a/models/user.js b/models/user.js index d8a116ae5..bcc22d895 100644 --- a/models/user.js +++ b/models/user.js @@ -356,7 +356,7 @@ UserService.createLocalUser = (email, password, displayName) => { user.save((err) => { if (err) { if (err.code === 11000) { - return reject('Email address already in use'); + return reject(new Error('Email address or Name already in use')); } return reject(err); } From 4dbc73f9abf77af12e2f5080520405a98e548694 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 6 Jan 2017 16:57:25 -0300 Subject: [PATCH 003/142] Add a test on already used display name. --- tests/models/user.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/models/user.js b/tests/models/user.js index 7484880bf..46584a9dc 100644 --- a/tests/models/user.js +++ b/tests/models/user.js @@ -80,6 +80,22 @@ describe('models.User', () => { }); + describe('#createLocalUser', () => { + it('should not create a user with duplicate display name', () => { + return User.createLocalUsers([{ + email: 'otrostampi@gmail.com', + displayName: 'Stampi', + password: '1Coralito!' + }]) + .then((user) => { + expect(user).to.be.null; + }) + .catch((error) => { + expect(error).to.not.be.null; + }); + }); + }); + describe('#createEmailConfirmToken', () => { it('should create a token for a valid user', () => { From 1acc92a1f2e700ff06dc78561e1f96ec1f443d24 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 9 Jan 2017 12:45:41 -0300 Subject: [PATCH 004/142] Header Changes --- .../coral-admin/src/components/ui/Header.css | 31 +++++++++++++------ .../coral-admin/src/components/ui/Header.js | 2 +- client/coral-admin/src/components/ui/Logo.css | 23 +++++++------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/client/coral-admin/src/components/ui/Header.css b/client/coral-admin/src/components/ui/Header.css index a0d7dd30d..0de8f549a 100644 --- a/client/coral-admin/src/components/ui/Header.css +++ b/client/coral-admin/src/components/ui/Header.css @@ -1,22 +1,25 @@ .header { - background: #505050; + background-color: transparent; + box-shadow: none; } .header > div { - position: relative; - padding: 0; - width: 1170px; - margin: 0 auto; + background-color: #696969; + position: relative; + padding: 0; + width: 1170px; + margin: 0 auto; + box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12); } .active { - background: #232323; + background: #232323; } .rightPanel { - position: absolute; - right: 0; - width: 170px; + position: absolute; + right: 0; + width: 170px; } .rightPanel ul { @@ -45,3 +48,13 @@ background: rgba(158, 158, 158, 0.69); cursor: pointer; } + +.navLink { + padding: 0 20px; + font-size: 16px; + font-weight: 500; +} + +.nav .navLink { + padding: 0 20px; +} diff --git a/client/coral-admin/src/components/ui/Header.js b/client/coral-admin/src/components/ui/Header.js index 4c76424cc..4e2b391c8 100644 --- a/client/coral-admin/src/components/ui/Header.js +++ b/client/coral-admin/src/components/ui/Header.js @@ -9,7 +9,7 @@ import {Logo} from './Logo'; export default ({handleLogout}) => (
- + {lang.t('configure.moderate')} Date: Mon, 9 Jan 2017 12:54:28 -0300 Subject: [PATCH 005/142] Adding Roboto --- views/admin.ejs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/views/admin.ejs b/views/admin.ejs index efcf1dfc9..9b585b653 100644 --- a/views/admin.ejs +++ b/views/admin.ejs @@ -5,6 +5,7 @@ Talk - Coral Admin + + + +
+
+ Admin Login + + + + +
+
+
+ + + + diff --git a/views/password-reset.ejs b/views/admin/password-reset.ejs similarity index 97% rename from views/password-reset.ejs rename to views/admin/password-reset.ejs index ec905c041..06b9d2a86 100644 --- a/views/password-reset.ejs +++ b/views/admin/password-reset.ejs @@ -3,7 +3,6 @@ - Password Reset @@ -122,6 +121,9 @@ url: '/api/v1/account/password/reset', contentType: 'application/json', method: 'PUT', + headers: { + 'X-CSRF-Token': '<%= csrfToken %>' + }, data: JSON.stringify({password: password, token: location.hash.replace('#', '')}) }).then(function (success) { location.href = '<%= redirectUri %>'; From 6282c39f3ae9c1adc7c986e27975350d7e062df3 Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Mon, 23 Jan 2017 16:52:16 -0700 Subject: [PATCH 089/142] merge remote. can reply to a comment --- client/coral-embed-stream/src/Comment.js | 226 +++++++++++------- client/coral-embed-stream/src/Embed.js | 33 ++- client/coral-embed-stream/src/Stream.js | 6 +- .../src/graphql/mutations/index.js | 4 +- client/coral-plugin-commentbox/CommentBox.js | 71 +++--- client/coral-plugin-flags/FlagButton.js | 2 +- client/coral-plugin-replies/ReplyBox.js | 31 ++- client/coral-plugin-replies/ReplyButton.js | 32 ++- 8 files changed, 245 insertions(+), 160 deletions(-) diff --git a/client/coral-embed-stream/src/Comment.js b/client/coral-embed-stream/src/Comment.js index 6e3744aab..21e98ae64 100644 --- a/client/coral-embed-stream/src/Comment.js +++ b/client/coral-embed-stream/src/Comment.js @@ -11,103 +11,157 @@ import PermalinkButton from 'coral-plugin-permalinks/PermalinkButton'; // import AuthorName from '../../coral-plugin-author-name/AuthorName'; import Content from '../../coral-plugin-commentcontent/CommentContent'; import PubDate from '../../coral-plugin-pubdate/PubDate'; -// import {ReplyBox, ReplyButton} from '../../coral-plugin-replies'; +import {ReplyBox, ReplyButton} from 'coral-plugin-replies'; import FlagComment from '../../coral-plugin-flags/FlagComment'; import LikeButton from '../../coral-plugin-likes/LikeButton'; const getAction = (type, comment) => comment.actions.filter((a) => a.type === type)[0]; -const Comment = ({comment, currentUser, asset, depth, showSignInDialog, postAction, deleteAction}) => { - const like = getAction('LIKE', comment); - const flag = getAction('FLAG', comment); - return ( -
-
- {/* */} - - -
- {/* - - */} - -
-
- +
+ {/* - -
- { - comment.replies && - comment.replies.map(reply => { - return */} + + + + { + currentUser + ?
+ { + console.log('reply button click'); + this.setState({replyBoxVisible: !this.state.replyBoxVisible}); + }} + parentCommentId={comment.id} + currentUserId={currentUser.id} + banned={false} /> + +
+ : null + } +
+ { + currentUser + ? ; - }) - } + currentUser={currentUser} /> + : null + } -
- ); -}; + +
+ { + this.state.replyBoxVisible + ? + : null + } + { + comment.replies && + comment.replies.map(reply => { + return ; + }) + } -Comment.propTypes = { - depth: PropTypes.number.isRequired, - asset: PropTypes.shape({ - id: PropTypes.string, - title: PropTypes.string, - url: PropTypes.string - }).isRequired, - currentUser: PropTypes.object, - comment: PropTypes.shape({ - depth: PropTypes.number, - actions: PropTypes.array.isRequired, - body: PropTypes.string.isRequired, - id: PropTypes.string.isRequired, - replies: PropTypes.arrayOf( - PropTypes.shape({ - body: PropTypes.string.isRequired, - id: PropTypes.string.isRequired - }) - ), - user: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired - }).isRequired -}; + + ); + } +} export default Comment; diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index cd55c13cd..8ddc215cb 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -102,7 +102,7 @@ class Embed extends Component { // const banned = (this.props.userData.status === 'banned'); - const {loading, asset} = this.props.data; + const {loading, asset, refetch} = this.props.data; // const {status, moderation, closedMessage, charCount, charCountEnable} = asset.settings; @@ -129,24 +129,31 @@ class Embed extends Component { enable={asset.settings.infoBoxEnable} /> }> - + { + user + ? + : null + } :

{asset.settings.closedMessage}

} {!loggedIn && } { +const Stream = ({comments, currentUser, asset, postItem, addNotification, postAction, deleteAction, showSignInDialog}) => { return (
{ comments.map(comment => { return ({ - postItem: ({asset_id, body}) => { + postItem: ({asset_id, body, parent_id} /*, type */) => { return mutate({ variables: { asset_id, body, - parent_id: null + parent_id } }); }}), diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js index ff9bf7e39..90113180c 100644 --- a/client/coral-plugin-commentbox/CommentBox.js +++ b/client/coral-plugin-commentbox/CommentBox.js @@ -8,11 +8,13 @@ const name = 'coral-plugin-commentbox'; class CommentBox extends Component { static propTypes = { - postItem: PropTypes.func, - updateItem: PropTypes.func, - id: PropTypes.string, - comments: PropTypes.array, - reply: PropTypes.bool, + postItem: PropTypes.func.isRequired, + // updateItem: PropTypes.func, + assetId: PropTypes.string.isRequired, + parentId: PropTypes.string, + authorId: PropTypes.string.isRequired, + // comments: PropTypes.array, + isReply: PropTypes.bool.isRequired, canPost: PropTypes.bool, currentUser: PropTypes.object } @@ -25,33 +27,36 @@ class CommentBox extends Component { postComment = () => { const { postItem, - updateItem, - id, - parent_id, - child_id, + // updateItem, + assetId, + parentId, + // child_id, addNotification, - appendItemArray, - author + // appendItemArray, + authorId } = this.props; let comment = { body: this.state.body, - asset_id: id, - author_id: author.id + asset_id: assetId, + author_id: authorId, + parent_id: parentId }; - let related; - let parent_type; - if (parent_id) { - comment.parent_id = parent_id; - related = 'children'; - parent_type = 'comments'; - } else { - related = 'comments'; - parent_type = 'assets'; - } - if (child_id || parent_id) { - updateItem(child_id || parent_id, 'showReply', false, 'comments'); - } + + console.log('CommentBox.parentId', parentId); + // let related; + // let parent_type; + // if (parent_id) { + // comment.parent_id = parent_id; + // related = 'children'; + // parent_type = 'comments'; + // } else { + // related = 'comments'; + // parent_type = 'assets'; + // } + // if (child_id || parent_id) { + // updateItem(child_id || parent_id, 'showReply', false, 'comments'); + // } if (this.props.charCount && this.state.body.length > this.props.charCount) { return; @@ -59,13 +64,13 @@ class CommentBox extends Component { postItem(comment, 'comments') .then(({data}) => { const postedComment = data.createComment; - const commentId = postedComment.id; + // const commentId = postedComment.id; if (postedComment.status === 'rejected') { addNotification('error', lang.t('comment-post-banned-word')); } else if (postedComment.status === 'PREMOD') { addNotification('success', lang.t('comment-post-notif-premod')); } else { - appendItemArray(parent_id || id, related, commentId, !parent_id, parent_type); + // appendItemArray(parent_id || id, related, commentId, !parent_id, parent_type); addNotification('success', 'Your comment has been posted.'); } }) @@ -74,23 +79,23 @@ class CommentBox extends Component { } render () { - const {styles, reply, author, charCount} = this.props; + const {styles, isReply, authorId, charCount} = this.props; const length = this.state.body.length; return