mirror of
https://github.com/wassname/talk.git
synced 2026-07-08 16:17:09 +08:00
Merge pull request #299 from coralproject/username-displayname
Inital rename of displayName -> username
This commit is contained in:
+1
-1
@@ -15,7 +15,7 @@
|
||||
There are some runtime requirements for running Talk from source:
|
||||
|
||||
- [Node](https://nodejs.org/) v7 or later
|
||||
- [MongoDB](https://www.mongodb.com/) v3.2 or later
|
||||
- [MongoDB](https://www.mongodb.com/) v3.4 or later
|
||||
- [Redis](https://redis.io/) v3.2 or later
|
||||
- [Yarn](https://yarnpkg.com/) v0.19.1 or later
|
||||
|
||||
|
||||
+5
-5
@@ -116,11 +116,11 @@ const performSetup = () => {
|
||||
return inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'displayName',
|
||||
message: 'Display Name',
|
||||
filter: (displayName) => {
|
||||
name: 'username',
|
||||
message: 'Username',
|
||||
filter: (username) => {
|
||||
return UsersService
|
||||
.isValidDisplayName(displayName, false)
|
||||
.isValidDisplayName(username, false)
|
||||
.catch((err) => {
|
||||
throw err.message;
|
||||
});
|
||||
@@ -174,7 +174,7 @@ const performSetup = () => {
|
||||
settings: settings.toObject(),
|
||||
user: {
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
username: user.username,
|
||||
password: user.password
|
||||
}
|
||||
});
|
||||
|
||||
+9
-9
@@ -32,7 +32,7 @@ function getUserCreateAnswers(options) {
|
||||
email: options.email,
|
||||
password: options.password,
|
||||
confirmPassword: options.password,
|
||||
displayName: options.name,
|
||||
username: options.name,
|
||||
roles: []
|
||||
};
|
||||
|
||||
@@ -75,11 +75,11 @@ function getUserCreateAnswers(options) {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'displayName',
|
||||
message: 'Display Name',
|
||||
filter: (displayName) => {
|
||||
name: 'username',
|
||||
message: 'Username',
|
||||
filter: (username) => {
|
||||
return UsersService
|
||||
.isValidDisplayName(displayName)
|
||||
.isValidDisplayName(username)
|
||||
.catch((err) => {
|
||||
throw err.message;
|
||||
});
|
||||
@@ -108,7 +108,7 @@ function createUser(options) {
|
||||
})
|
||||
.then((answers) => {
|
||||
return UsersService
|
||||
.createLocalUser(answers.email.trim(), answers.password.trim(), answers.displayName.trim())
|
||||
.createLocalUser(answers.email.trim(), answers.password.trim(), answers.username.trim())
|
||||
.then((user) => {
|
||||
console.log(`Created user ${user.id}.`);
|
||||
|
||||
@@ -209,7 +209,7 @@ function updateUser(userID, options) {
|
||||
'id': userID
|
||||
}, {
|
||||
$set: {
|
||||
displayName: options.name
|
||||
username: options.name
|
||||
}
|
||||
});
|
||||
|
||||
@@ -238,7 +238,7 @@ function listUsers() {
|
||||
let table = new Table({
|
||||
head: [
|
||||
'ID',
|
||||
'Display Name',
|
||||
'Username',
|
||||
'Profiles',
|
||||
'Roles',
|
||||
'Status',
|
||||
@@ -249,7 +249,7 @@ function listUsers() {
|
||||
users.forEach((user) => {
|
||||
table.push([
|
||||
user.id,
|
||||
user.displayName,
|
||||
user.username,
|
||||
user.profiles.map((p) => p.provider).join(', '),
|
||||
user.roles.join(', '),
|
||||
user.status,
|
||||
|
||||
+12
-2
@@ -10,11 +10,21 @@ machine:
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
# TODO: use the following to add in support for MongoDB 3.4.
|
||||
# # Upgrade the database version to 3.4.
|
||||
# - sudo apt-get purge mongodb-org*
|
||||
# - sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
|
||||
# - echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu precise/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
|
||||
# - sudo apt-get update
|
||||
# - sudo apt-get install -y mongodb-org
|
||||
# - sudo service mongod restart
|
||||
|
||||
# Install node dependencies.
|
||||
- yarn
|
||||
cache_directories:
|
||||
- ~/.cache/yarn
|
||||
post:
|
||||
# Build the static assets
|
||||
# Build the static assets.
|
||||
- yarn build
|
||||
# Lint the project here, before tests are ran.
|
||||
- yarn lint
|
||||
@@ -30,7 +40,7 @@ test:
|
||||
override:
|
||||
# Run the tests using the junit reporter.
|
||||
- MOCHA_FILE=$CIRCLE_TEST_REPORTS/junit/test-results.xml MOCHA_REPORTER=mocha-junit-reporter yarn test
|
||||
# Run the e2e test suite
|
||||
# Run the e2e test suite.
|
||||
- E2E_REPORT_PATH=$CIRCLE_TEST_REPORTS/e2e yarn e2e
|
||||
|
||||
deployment:
|
||||
|
||||
@@ -18,7 +18,7 @@ const ActionButton = ({option, type, comment = {}, user, menuOptionsMap, onClick
|
||||
className={`ban ${styles.banButton}`}
|
||||
cStyle='darkGrey'
|
||||
disabled={banned ? 'disabled' : ''}
|
||||
onClick={() => onClickShowBanDialog(user.id, user.displayName, comment.id)
|
||||
onClick={() => onClickShowBanDialog(user.id, user.username, comment.id)
|
||||
}
|
||||
raised
|
||||
>
|
||||
|
||||
@@ -23,7 +23,7 @@ const Comment = props => {
|
||||
<li tabIndex={props.index} className={`mdl-card mdl-shadow--2dp ${styles.listItem} ${props.isActive && !props.hideActive ? styles.activeItem : ''}`}>
|
||||
<div className={styles.itemHeader}>
|
||||
<div className={styles.author}>
|
||||
<span>{author.displayName || lang.t('comment.anon')}</span>
|
||||
<span>{author.username || lang.t('comment.anon')}</span>
|
||||
<span className={styles.created}>{timeago().format(comment.createdAt || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))}</span>
|
||||
{comment.flagged ? <p className={styles.flagged}>{lang.t('comment.flagged')}</p> : null}
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ const User = props => {
|
||||
<li tabIndex={props.index} className={`mdl-card mdl-shadow--2dp ${styles.listItem} ${props.isActive && !props.hideActive ? styles.activeItem : ''}`}>
|
||||
<div className={styles.itemHeader}>
|
||||
<div className={styles.author}>
|
||||
<span>{user.displayName}</span>
|
||||
<span>{user.username}</span>
|
||||
</div>
|
||||
<div className={styles.sideActions}>
|
||||
<div className={`actions ${styles.actions}`}>
|
||||
|
||||
@@ -13,7 +13,7 @@ const lang = new I18n(translations);
|
||||
const tableHeaders = [
|
||||
{
|
||||
title: lang.t('community.username_and_email'),
|
||||
field: 'displayName'
|
||||
field: 'username'
|
||||
},
|
||||
{
|
||||
title: lang.t('community.account_creation_date'),
|
||||
|
||||
@@ -44,7 +44,7 @@ class Table extends Component {
|
||||
{commenters.map((row, i)=> (
|
||||
<tr key={i}>
|
||||
<td className="mdl-data-table__cell--non-numeric">
|
||||
{row.displayName}
|
||||
{row.username}
|
||||
<span className={styles.email}>{row.profiles.map(({id}) => id)}</span>
|
||||
</td>
|
||||
<td className="mdl-data-table__cell--non-numeric">
|
||||
|
||||
@@ -21,12 +21,12 @@ const InitialStep = props => {
|
||||
|
||||
<FormField
|
||||
className={styles.formField}
|
||||
id="displayName"
|
||||
id="username"
|
||||
type="text"
|
||||
label='Username'
|
||||
onChange={handleUserChange}
|
||||
showErrors={install.showErrors}
|
||||
errorMsg={install.errors.displayName}
|
||||
errorMsg={install.errors.username}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
|
||||
@@ -9,7 +9,7 @@ const initialState = Map({
|
||||
organizationName: ''
|
||||
}),
|
||||
user: Map({
|
||||
displayName: '',
|
||||
username: '',
|
||||
email: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
@@ -17,7 +17,7 @@ const initialState = Map({
|
||||
}),
|
||||
errors: Map({
|
||||
organizationName: '',
|
||||
displayName: '',
|
||||
username: '',
|
||||
email: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
},
|
||||
"bandialog": {
|
||||
"ban_user": "Quieres suspender el Usuario?",
|
||||
"are_you_sure": "Estas segura que quieres suspender a {props.author.displayName}?",
|
||||
"are_you_sure": "Estas segura que quieres suspender a {props.author.username}?",
|
||||
"note": "Nota: Suspender este usuario también va a colocar este comentario en la cola de Rechazados.",
|
||||
"cancel": "Cancelar",
|
||||
"yes_ban_user": "Si, Suspendan el usuario"
|
||||
|
||||
@@ -201,7 +201,7 @@ const mapDispatchToProps = dispatch => ({
|
||||
});
|
||||
},
|
||||
clearNotification: () => dispatch(clearNotification()),
|
||||
editName: (displayName) => dispatch(editName(displayName)),
|
||||
editName: (username) => dispatch(editName(username)),
|
||||
showSignInDialog: (offset) => dispatch(showSignInDialog(offset)),
|
||||
logout: () => dispatch(logout()),
|
||||
dispatch: d => dispatch(d)
|
||||
|
||||
@@ -10,7 +10,7 @@ class Stream extends React.Component {
|
||||
asset: PropTypes.object.isRequired,
|
||||
comments: PropTypes.array.isRequired,
|
||||
currentUser: PropTypes.shape({
|
||||
displayName: PropTypes.string,
|
||||
username: PropTypes.string,
|
||||
id: PropTypes.string
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISP
|
||||
const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS});
|
||||
const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error});
|
||||
|
||||
export const updateDisplayName = ({displayName}) => ({type: actions.UPDATE_DISPLAYNAME, displayName});
|
||||
export const updateDisplayName = ({username}) => ({type: actions.UPDATE_DISPLAYNAME, username});
|
||||
|
||||
export const createDisplayName = (userId, formData) => dispatch => {
|
||||
dispatch(createDisplayNameRequest());
|
||||
coralApi('/account/displayname', {method: 'PUT', body: formData})
|
||||
coralApi('/account/username', {method: 'PUT', body: formData})
|
||||
.then(() => {
|
||||
dispatch(createDisplayNameSuccess());
|
||||
dispatch(hideCreateDisplayNameDialog());
|
||||
|
||||
@@ -5,8 +5,8 @@ import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from './../translations';
|
||||
const lang = new I18n(translations);
|
||||
|
||||
export const editName = (displayName) => (dispatch) => {
|
||||
return coralApi('/account/displayname', {method: 'PUT', body: {displayName}})
|
||||
export const editName = (username) => (dispatch) => {
|
||||
return coralApi('/account/username', {method: 'PUT', body: {username}})
|
||||
.then(() => {
|
||||
dispatch(addNotification('success', lang.t('successNameUpdate')));
|
||||
});
|
||||
|
||||
@@ -14,16 +14,16 @@ class SuspendedAccount extends Component {
|
||||
}
|
||||
|
||||
state = {
|
||||
displayName: '',
|
||||
username: '',
|
||||
alert: ''
|
||||
}
|
||||
|
||||
onSubmitClick = (e) => {
|
||||
const {editName} = this.props;
|
||||
const {displayName} = this.state;
|
||||
const {username} = this.state;
|
||||
e.preventDefault();
|
||||
if (validate.displayName(displayName)) {
|
||||
editName(displayName)
|
||||
if (validate.username(username)) {
|
||||
editName(username)
|
||||
.then(() => location.reload())
|
||||
.catch((error) => {
|
||||
this.setState({alert: lang.t(`error.${error.message}`)});
|
||||
@@ -36,7 +36,7 @@ class SuspendedAccount extends Component {
|
||||
|
||||
render () {
|
||||
const {canEditName} = this.props;
|
||||
const {displayName, alert} = this.state;
|
||||
const {username, alert} = this.state;
|
||||
|
||||
return <div className={styles.message}>
|
||||
<span>{
|
||||
@@ -51,7 +51,7 @@ class SuspendedAccount extends Component {
|
||||
{alert}
|
||||
</div>
|
||||
<label
|
||||
htmlFor='displayName'
|
||||
htmlFor='username'
|
||||
className="screen-reader-text"
|
||||
aria-hidden={true}>
|
||||
{lang.t('editName.label')}
|
||||
@@ -59,10 +59,10 @@ class SuspendedAccount extends Component {
|
||||
<input
|
||||
type='text'
|
||||
className={styles.editNameInput}
|
||||
value={displayName}
|
||||
value={username}
|
||||
placeholder={lang.t('editName.label')}
|
||||
id='displayName'
|
||||
onChange={(e) => this.setState({displayName: e.target.value})}
|
||||
id='username'
|
||||
onChange={(e) => this.setState({username: e.target.value})}
|
||||
rows={3}/><br/>
|
||||
<Button
|
||||
onClick={this.onSubmitClick}>
|
||||
|
||||
@@ -10,7 +10,7 @@ fragment commentView on Comment {
|
||||
}
|
||||
user {
|
||||
id
|
||||
name: displayName
|
||||
name: username
|
||||
}
|
||||
action_summaries {
|
||||
...actionSummaryView
|
||||
|
||||
@@ -5,7 +5,7 @@ const lang = new I18n(translations);
|
||||
export default {
|
||||
email: lang.t('error.email'),
|
||||
password: lang.t('error.password'),
|
||||
displayName: lang.t('error.displayName'),
|
||||
username: lang.t('error.username'),
|
||||
confirmPassword: lang.t('error.confirmPassword'),
|
||||
organizationName: lang.t('error.organizationName'),
|
||||
};
|
||||
|
||||
@@ -2,6 +2,6 @@ export default {
|
||||
email: email => (/^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(email)),
|
||||
password: pass => (/^(?=.{8,}).*$/.test(pass)),
|
||||
confirmPassword: () => true,
|
||||
displayName: displayName => (/^[a-zA-Z0-9_]+$/.test(displayName)),
|
||||
username: username => (/^[a-zA-Z0-9_]+$/.test(username)),
|
||||
organizationName: org => (/^[a-zA-Z0-9_ ]+$/).test(org)
|
||||
};
|
||||
|
||||
@@ -133,7 +133,7 @@ export default function auth (state = initialState, action) {
|
||||
case actions.UPDATE_DISPLAYNAME:
|
||||
console.log('Action', action);
|
||||
return state
|
||||
.setIn(['user', 'displayName'], action.displayName);
|
||||
.setIn(['user', 'username'], action.username);
|
||||
case actions.VERIFY_EMAIL_FAILURE:
|
||||
return state
|
||||
.set('emailVerificationFailure', true)
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as actions from '../constants/user';
|
||||
import * as assetActions from '../constants/assets';
|
||||
|
||||
const initialState = Map({
|
||||
displayName: '',
|
||||
username: '',
|
||||
profiles: [],
|
||||
settings: {},
|
||||
myComments: [],
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"en": {
|
||||
"successUpdateSettings": "The changes you have made have been applied to the comment stream on this article",
|
||||
"successNameUpdate": "Your display name has been updated",
|
||||
"successNameUpdate": "Your username has been updated",
|
||||
"contentNotAvailable": "This content is not available",
|
||||
"bannedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
|
||||
"editName": {
|
||||
"msg": "Your account is currently suspended because your display name has been deemed inappropriate. To restore your account, please enter a new username. You may contact moderator@fakeurl.com for more information.",
|
||||
"label": "New Display Name",
|
||||
"msg": "Your account is currently suspended because your username has been deemed inappropriate. To restore your account, please enter a new username. You may contact moderator@fakeurl.com for more information.",
|
||||
"label": "New Username",
|
||||
"button": "Submit",
|
||||
"error": "Display names can contain letters, numbers and _ only"
|
||||
},
|
||||
@@ -14,7 +14,7 @@
|
||||
"emailNotVerified": "Email address {0} not verified.",
|
||||
"email": "Not a valid E-Mail",
|
||||
"password": "Password must be at least 8 characters",
|
||||
"displayName": "Display names can contain letters, numbers and _ only",
|
||||
"username": "Display names can contain letters, numbers and _ only",
|
||||
"confirmPassword": "Passwords don't match. Please, check again",
|
||||
"organizationName": "Organization name must only contain letters or numbers.",
|
||||
"emailPasswordError": "Email and/or password combination incorrect.",
|
||||
@@ -22,9 +22,9 @@
|
||||
"PASSWORD_REQUIRED": "Must input a password",
|
||||
"PASSWORD_LENGTH": "Password is too short",
|
||||
"EMAIL_IN_USE": "Email address already in use",
|
||||
"EMAIL_DISPLAY_NAME_IN_USE": "Email address or display name already in use",
|
||||
"EMAIL_DISPLAY_NAME_IN_USE": "Email address or username already in use",
|
||||
"DISPLAYNAME_IN_USE": "Display name already in use",
|
||||
"DISPLAY_NAME_REQUIRED": "Must input a display name",
|
||||
"DISPLAY_NAME_REQUIRED": "Must input a username",
|
||||
"NO_SPECIAL_CHARACTERS": "Display names can contain letters, numbers and _ only",
|
||||
"PROFANITY_ERROR": "Display names must not contain profanity. Please contact the administrator if you believe this to be in error."
|
||||
}
|
||||
@@ -39,7 +39,7 @@
|
||||
"emailNotVerified": "Dirección de correo electrónico {0} no verificada.",
|
||||
"email": "No es un email válido",
|
||||
"password": "La contraseña debe tener por lo menos 8 caracteres",
|
||||
"displayName": "Los nombres pueden contener letras, números y _",
|
||||
"username": "Los nombres pueden contener letras, números y _",
|
||||
"organizationName": "El nombre de la organización debe contener letras y/o números.",
|
||||
"confirmPassword": "Las contraseñas no coinciden",
|
||||
"emailPasswordError": "Email y/o contraseña incorrecta.",
|
||||
|
||||
@@ -32,7 +32,7 @@ const postComment = gql`
|
||||
id
|
||||
body
|
||||
user {
|
||||
name: displayName
|
||||
name: username
|
||||
}
|
||||
actions {
|
||||
type: action_type
|
||||
|
||||
@@ -56,7 +56,7 @@ const StreamQuery = gql`fragment commentView on Comment {
|
||||
id
|
||||
body
|
||||
user {
|
||||
name: displayName
|
||||
name: username
|
||||
}
|
||||
tags {
|
||||
name
|
||||
|
||||
@@ -3,7 +3,7 @@ import styles from './SettingsHeader.css';
|
||||
|
||||
export default ({userData}) => (
|
||||
<div className={styles.header}>
|
||||
<h1>{userData.displayName}</h1>
|
||||
<h1>{userData.username}</h1>
|
||||
|
||||
{
|
||||
|
||||
|
||||
@@ -25,17 +25,17 @@ const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSub
|
||||
</h1>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="displayName">{lang.t('createdisplay.yourusername')}</label>
|
||||
<label htmlFor="username">{lang.t('createdisplay.yourusername')}</label>
|
||||
{ props.auth.error && <Alert>{props.auth.error}</Alert> }
|
||||
<form id="saveDisplayName" onSubmit={handleSubmitDisplayName}>
|
||||
<FormField
|
||||
id="displayName"
|
||||
id="username"
|
||||
type="string"
|
||||
label={lang.t('createdisplay.displayName')}
|
||||
value={formData.displayName}
|
||||
label={lang.t('createdisplay.username')}
|
||||
value={formData.username}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
{ props.errors.displayName && <span className={styles.hint}> {lang.t('createdisplay.specialCharacters')} </span> }
|
||||
{ props.errors.username && <span className={styles.hint}> {lang.t('createdisplay.specialCharacters')} </span> }
|
||||
<div className={styles.action}>
|
||||
<Button id="save" type="submit" className={styles.saveButton}>{lang.t('createdisplay.save')}</Button>
|
||||
</div>
|
||||
|
||||
@@ -21,13 +21,13 @@ class SignUpContent extends React.Component {
|
||||
showErrors: PropTypes.bool,
|
||||
errors: PropTypes.shape({
|
||||
email: PropTypes.string,
|
||||
displayName: PropTypes.string,
|
||||
username: PropTypes.string,
|
||||
password: PropTypes.string,
|
||||
confirmPassword: PropTypes.string,
|
||||
}),
|
||||
formData: PropTypes.shape({
|
||||
email: PropTypes.string,
|
||||
displayName: PropTypes.string,
|
||||
username: PropTypes.string,
|
||||
password: PropTypes.string,
|
||||
confirmPassword: PropTypes.string
|
||||
})
|
||||
@@ -89,12 +89,12 @@ class SignUpContent extends React.Component {
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<FormField
|
||||
id="displayName"
|
||||
id="username"
|
||||
type="text"
|
||||
label={lang.t('signIn.displayName')}
|
||||
value={formData.displayName}
|
||||
label={lang.t('signIn.username')}
|
||||
value={formData.username}
|
||||
showErrors={showErrors}
|
||||
errorMsg={errors.displayName}
|
||||
errorMsg={errors.username}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<FormField
|
||||
|
||||
@@ -7,7 +7,7 @@ const lang = new I18n(translations);
|
||||
const UserBox = ({className, user, logout, changeTab}) => (
|
||||
<div className={`${styles.userBox} ${className ? className : ''}`}>
|
||||
{lang.t('signIn.loggedInAs')}
|
||||
<a onClick={() => changeTab(1)}>{user.displayName}</a>. {lang.t('signIn.notYou')}
|
||||
<a onClick={() => changeTab(1)}>{user.username}</a>. {lang.t('signIn.notYou')}
|
||||
<a className={styles.logout} onClick={logout} id='logout'>{lang.t('signIn.logout')}</a>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
class ChangeDisplayNameContainer extends Component {
|
||||
initialState = {
|
||||
formData: {
|
||||
displayName: '',
|
||||
username: '',
|
||||
},
|
||||
errors: {},
|
||||
showErrors: false
|
||||
|
||||
@@ -29,7 +29,7 @@ class SignInContainer extends Component {
|
||||
initialState = {
|
||||
formData: {
|
||||
email: '',
|
||||
displayName: '',
|
||||
username: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ export default {
|
||||
register: 'Register',
|
||||
signUp: 'Sign Up',
|
||||
confirmPassword: 'Confirm Password',
|
||||
displayName: 'Display Name',
|
||||
username: 'Username',
|
||||
alreadyHaveAnAccount: 'Already have an account?',
|
||||
recoverPassword: 'Recover password',
|
||||
emailInUse: 'Email address already in use',
|
||||
@@ -32,10 +32,10 @@ export default {
|
||||
'createdisplay': {
|
||||
writeyourusername: 'Write your username',
|
||||
yourusername: 'Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.',
|
||||
displayName: 'Display Name',
|
||||
username: 'Username',
|
||||
save: 'Save',
|
||||
requiredField: 'Required field',
|
||||
errorCreate: 'Error when changing display name',
|
||||
errorCreate: 'Error when changing username',
|
||||
checkTheForm: 'Invalid Form. Please, check the fields',
|
||||
specialCharacters: 'Display names can contain letters, numbers and _ only'
|
||||
},
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
register: 'Regístrate',
|
||||
signUp: 'Registro',
|
||||
confirmPassword: 'Confirmar Contraseña',
|
||||
displayName: 'Nombre',
|
||||
username: 'Nombre',
|
||||
alreadyHaveAnAccount: 'Ya tienes una cuenta?',
|
||||
recoverPassword: 'Recuperar contraseña',
|
||||
emailInUse: 'Este email se encuentra en uso',
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
'createdisplay': {
|
||||
writeyourusername: 'Escribe tu nombre',
|
||||
yourusername: 'Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.',
|
||||
displayName: 'Nombre a mostrar',
|
||||
username: 'Nombre a mostrar',
|
||||
save: 'Guardar',
|
||||
requiredField: 'Campo necesario',
|
||||
errorCreate: 'Hubo un error al cambiar el nombre de usuario',
|
||||
|
||||
+3
-3
@@ -515,7 +515,7 @@ paths:
|
||||
- name: value
|
||||
in: query
|
||||
type: string
|
||||
description: A term to search users' displayNames and email addresses.
|
||||
description: A term to search users' usernames and email addresses.
|
||||
- name: sort
|
||||
in: query
|
||||
type: string
|
||||
@@ -576,7 +576,7 @@ paths:
|
||||
format: email
|
||||
password:
|
||||
type: string
|
||||
displayName:
|
||||
username:
|
||||
type: string
|
||||
responses:
|
||||
201:
|
||||
@@ -899,7 +899,7 @@ definitions:
|
||||
id:
|
||||
type: string
|
||||
description: The uuid.v4 id of the user.
|
||||
displayName:
|
||||
username:
|
||||
type: string
|
||||
description: The name appearing next to the user's comments.
|
||||
disabled:
|
||||
|
||||
@@ -59,12 +59,12 @@ const ErrDisplayTaken = new APIError('Display name already in use', {
|
||||
status: 400
|
||||
});
|
||||
|
||||
const ErrSpecialChars = new APIError('No special characters are allowed in a display name', {
|
||||
const ErrSpecialChars = new APIError('No special characters are allowed in a username', {
|
||||
translation_key: 'NO_SPECIAL_CHARACTERS',
|
||||
status: 400
|
||||
});
|
||||
|
||||
const ErrMissingDisplay = new APIError('A display name is required to create a user', {
|
||||
const ErrMissingDisplay = new APIError('A username is required to create a user', {
|
||||
translation_key: 'DISPLAY_NAME_REQUIRED',
|
||||
status: 400
|
||||
});
|
||||
|
||||
@@ -27,8 +27,8 @@ type User {
|
||||
# The ID of the User.
|
||||
id: ID!
|
||||
|
||||
# display name of a user.
|
||||
displayName: String!
|
||||
# username of a user.
|
||||
username: String!
|
||||
|
||||
# Action summaries against the user.
|
||||
action_summaries: [ActionSummary]
|
||||
|
||||
+11
-4
@@ -12,7 +12,7 @@ const USER_STATUS = [
|
||||
'ACTIVE',
|
||||
'BANNED',
|
||||
'PENDING',
|
||||
'APPROVED' // Indicates that the users' displayname has been approved
|
||||
'APPROVED' // Indicates that the users' username has been approved
|
||||
];
|
||||
|
||||
// ProfileSchema is the mongoose schema defined as the representation of a
|
||||
@@ -61,13 +61,20 @@ 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: {
|
||||
username: {
|
||||
type: String,
|
||||
unique: true,
|
||||
lowercase: true,
|
||||
required: true
|
||||
},
|
||||
|
||||
// TODO: find a way that we can instead utilize MongoDB 3.4's collation
|
||||
// options to build the index in a case insenstive manner:
|
||||
// https://docs.mongodb.com/manual/reference/collation/
|
||||
lowercaseUsername: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
|
||||
// This is true when the user account is disabled, no action should be
|
||||
// acknowledged when they are disabled. Logins are also prevented.
|
||||
disabled: Boolean,
|
||||
|
||||
@@ -115,9 +115,9 @@ router.put('/password/reset', (req, res, next) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.put('/displayname', authorization.needed(), (req, res, next) => {
|
||||
router.put('/username', authorization.needed(), (req, res, next) => {
|
||||
UsersService
|
||||
.editName(req.user.id, req.body.displayName)
|
||||
.editName(req.user.id, req.body.username)
|
||||
.then(() => {
|
||||
res.status(204).end();
|
||||
})
|
||||
|
||||
@@ -70,7 +70,7 @@ const HandleAuthPopupCallback = (req, res, next) => (err, user) => {
|
||||
return res.render('auth-callback', {err: JSON.stringify(errors.ErrNotAuthorized), data: null});
|
||||
}
|
||||
|
||||
// Authorize the user to edit their displayName.
|
||||
// Authorize the user to edit their username.
|
||||
UsersService.toggleNameEdit(user.id, true)
|
||||
.then(() => {
|
||||
|
||||
|
||||
@@ -32,11 +32,11 @@ router.post('/', (req, res, next) => {
|
||||
|
||||
const {
|
||||
settings,
|
||||
user: {email, password, displayName}
|
||||
user: {email, password, username}
|
||||
} = req.body;
|
||||
|
||||
SetupService
|
||||
.setup({settings, user: {email, password, displayName}})
|
||||
.setup({settings, user: {email, password, username}})
|
||||
.then(() => {
|
||||
|
||||
// We're setup!
|
||||
|
||||
@@ -120,11 +120,11 @@ const SendEmailConfirmation = (app, userID, email, referer) => UsersService
|
||||
|
||||
// create a local user.
|
||||
router.post('/', (req, res, next) => {
|
||||
const {email, password, displayName} = req.body;
|
||||
const {email, password, username} = req.body;
|
||||
const redirectUri = req.header('X-Pym-Url') || req.header('Referer');
|
||||
|
||||
UsersService
|
||||
.createLocalUser(email, password, displayName)
|
||||
.createLocalUser(email, password, username)
|
||||
.then((user) => {
|
||||
|
||||
// Send an email confirmation. The Front end will know about the
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# fail the e2e if any of these fail
|
||||
set -e
|
||||
|
||||
# install selenium
|
||||
selenium-standalone install --config=./selenium.config.js
|
||||
|
||||
|
||||
@@ -102,6 +102,9 @@ if (process.env.TALK_FACEBOOK_APP_ID && process.env.TALK_FACEBOOK_APP_SECRET &&
|
||||
clientID: process.env.TALK_FACEBOOK_APP_ID,
|
||||
clientSecret: process.env.TALK_FACEBOOK_APP_SECRET,
|
||||
callbackURL: `${process.env.TALK_ROOT_URL}/api/v1/auth/facebook/callback`,
|
||||
|
||||
// TODO: remove displayName reference when we have steps in the FE to handle
|
||||
// the username create flow.
|
||||
profileFields: ['id', 'displayName', 'picture.type(large)']
|
||||
}, (accessToken, refreshToken, profile, done) => {
|
||||
UsersService
|
||||
|
||||
+5
-5
@@ -45,7 +45,7 @@ module.exports = class SetupService {
|
||||
/**
|
||||
* This verifies that the current input for the setup is valid.
|
||||
*/
|
||||
static validate({settings, user: {email, displayName, password}}) {
|
||||
static validate({settings, user: {email, username, password}}) {
|
||||
|
||||
// Verify the email address of the user.
|
||||
if (!email) {
|
||||
@@ -57,7 +57,7 @@ module.exports = class SetupService {
|
||||
|
||||
// Verify other properties of the user.
|
||||
return Promise.all([
|
||||
UsersService.isValidDisplayName(displayName, false),
|
||||
UsersService.isValidDisplayName(username, false),
|
||||
UsersService.isValidPassword(password),
|
||||
settingsModel.validate()
|
||||
]);
|
||||
@@ -66,11 +66,11 @@ module.exports = class SetupService {
|
||||
/**
|
||||
* This will perform the setup.
|
||||
*/
|
||||
static setup({settings, user: {email, password, displayName}}) {
|
||||
static setup({settings, user: {email, password, username}}) {
|
||||
|
||||
// Validate the settings first.
|
||||
return SetupService
|
||||
.validate({settings, user: {email, password, displayName}})
|
||||
.validate({settings, user: {email, password, username}})
|
||||
.then(() => {
|
||||
return SettingsService.update(settings);
|
||||
})
|
||||
@@ -80,7 +80,7 @@ module.exports = class SetupService {
|
||||
|
||||
// Create the user.
|
||||
return UsersService
|
||||
.createLocalUser(email, password, displayName)
|
||||
.createLocalUser(email, password, username)
|
||||
|
||||
// Grant them administrative privileges and confirm the email account.
|
||||
.then((user) => {
|
||||
|
||||
+40
-34
@@ -99,19 +99,23 @@ module.exports = class UsersService {
|
||||
.then(() => dstUser.save());
|
||||
}
|
||||
|
||||
static castDisplayName(displayName) {
|
||||
return displayName.replace(/ /g, '_').replace(/[^a-zA-Z_]/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a user given a social profile and if the user does not exist, creates
|
||||
* them.
|
||||
* @param {Object} profile - User social/external profile
|
||||
* @param {Function} done [description]
|
||||
*/
|
||||
static findOrCreateExternalUser(profile) {
|
||||
static findOrCreateExternalUser({id, provider, displayName}) {
|
||||
return UserModel
|
||||
.findOne({
|
||||
profiles: {
|
||||
$elemMatch: {
|
||||
id: profile.id,
|
||||
provider: profile.provider
|
||||
id,
|
||||
provider
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -120,16 +124,16 @@ module.exports = class UsersService {
|
||||
return user;
|
||||
}
|
||||
|
||||
// TODO: remove displayName reference when we have steps in the FE to handle
|
||||
// the username create flow.
|
||||
let username = UsersService.castDisplayName(displayName);
|
||||
|
||||
// The user was not found, lets create them!
|
||||
user = new UserModel({
|
||||
displayName: profile.displayName,
|
||||
username,
|
||||
lowercaseUsername: username.toLowerCase(),
|
||||
roles: [],
|
||||
profiles: [
|
||||
{
|
||||
id: profile.id,
|
||||
provider: profile.provider
|
||||
}
|
||||
]
|
||||
profiles: [{id, provider}]
|
||||
});
|
||||
|
||||
return user.save();
|
||||
@@ -164,24 +168,24 @@ module.exports = class UsersService {
|
||||
static createLocalUsers(users) {
|
||||
return Promise.all(users.map((user) => {
|
||||
return UsersService
|
||||
.createLocalUser(user.email, user.password, user.displayName);
|
||||
.createLocalUser(user.email, user.password, user.username);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the requested displayname for naughty words (currently in English) and special chars
|
||||
* @param {String} displayName word to be checked for profanity
|
||||
* Check the requested username for blocked words and special chars
|
||||
* @param {String} username word to be checked for profanity
|
||||
* @param {Boolean} checkAgainstWordlist enables cheching against the wordlist
|
||||
* @return {Promise} rejected if the machine's sensibilites are offended
|
||||
* @return {Promise}
|
||||
*/
|
||||
static isValidDisplayName(displayName, checkAgainstWordlist = true) {
|
||||
static isValidDisplayName(username, checkAgainstWordlist = true) {
|
||||
const onlyLettersNumbersUnderscore = /^[A-Za-z0-9_]+$/;
|
||||
|
||||
if (!displayName) {
|
||||
if (!username) {
|
||||
return Promise.reject(errors.ErrMissingDisplay);
|
||||
}
|
||||
|
||||
if (!onlyLettersNumbersUnderscore.test(displayName)) {
|
||||
if (!onlyLettersNumbersUnderscore.test(username)) {
|
||||
|
||||
return Promise.reject(errors.ErrSpecialChars);
|
||||
}
|
||||
@@ -189,11 +193,11 @@ module.exports = class UsersService {
|
||||
if (checkAgainstWordlist) {
|
||||
|
||||
// check for profanity
|
||||
return Wordlist.displayNameCheck(displayName);
|
||||
return Wordlist.usernameCheck(username);
|
||||
}
|
||||
|
||||
// No errors found!
|
||||
return Promise.resolve(displayName);
|
||||
return Promise.resolve(username);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,23 +219,23 @@ module.exports = class UsersService {
|
||||
* Creates the local user with a given email, password, and name.
|
||||
* @param {String} email email of the new user
|
||||
* @param {String} password plaintext password of the new user
|
||||
* @param {String} displayName name of the display user
|
||||
* @param {String} username name of the display user
|
||||
* @param {Function} done callback
|
||||
*/
|
||||
static createLocalUser(email, password, displayName) {
|
||||
static createLocalUser(email, password, username) {
|
||||
|
||||
if (!email) {
|
||||
return Promise.reject(errors.ErrMissingEmail);
|
||||
}
|
||||
|
||||
email = email.toLowerCase().trim();
|
||||
displayName = displayName.toLowerCase().trim();
|
||||
username = username.trim();
|
||||
|
||||
return Promise.all([
|
||||
UsersService.isValidDisplayName(displayName),
|
||||
UsersService.isValidDisplayName(username),
|
||||
UsersService.isValidPassword(password)
|
||||
])
|
||||
.then(() => { // displayName is valid
|
||||
.then(() => { // username is valid
|
||||
return new Promise((resolve, reject) => {
|
||||
bcrypt.hash(password, SALT_ROUNDS, (err, hashedPassword) => {
|
||||
if (err) {
|
||||
@@ -239,7 +243,8 @@ module.exports = class UsersService {
|
||||
}
|
||||
|
||||
let user = new UserModel({
|
||||
displayName: displayName,
|
||||
username,
|
||||
lowercaseUsername: username.toLowerCase(),
|
||||
password: hashedPassword,
|
||||
roles: [],
|
||||
profiles: [
|
||||
@@ -253,7 +258,7 @@ module.exports = class UsersService {
|
||||
user.save((err) => {
|
||||
if (err) {
|
||||
if (err.code === 11000) {
|
||||
if (err.message.match('displayName')) {
|
||||
if (err.message.match('username')) {
|
||||
return reject(errors.ErrDisplayTaken);
|
||||
}
|
||||
return reject(errors.ErrEmailTaken);
|
||||
@@ -397,7 +402,7 @@ module.exports = class UsersService {
|
||||
static findPublicByIdArray(ids) {
|
||||
return UserModel.find({
|
||||
id: {$in: ids}
|
||||
}, 'id displayName');
|
||||
}, 'id username');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,7 +478,7 @@ module.exports = class UsersService {
|
||||
|
||||
/**
|
||||
* Finds a user using a value which gets compared using a prefix match against
|
||||
* the user's email address and/or their display name.
|
||||
* the user's email address and/or their username.
|
||||
* @param {String} value value to search by
|
||||
* @return {Promise}
|
||||
*/
|
||||
@@ -481,9 +486,9 @@ module.exports = class UsersService {
|
||||
return UserModel.find({
|
||||
$or: [
|
||||
|
||||
// Search by a prefix match on the displayName.
|
||||
// Search by a prefix match on the username.
|
||||
{
|
||||
'displayName': {
|
||||
'username': {
|
||||
$regex: new RegExp(`^${value}`),
|
||||
$options: 'i'
|
||||
}
|
||||
@@ -667,18 +672,19 @@ module.exports = class UsersService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user's displayName.
|
||||
* Updates the user's username.
|
||||
* @param {String} id the id of the user to be enabled.
|
||||
* @param {String} displayName The new displayname for the user.
|
||||
* @param {String} username The new username for the user.
|
||||
* @return {Promise}
|
||||
*/
|
||||
static editName(id, displayName) {
|
||||
static editName(id, username) {
|
||||
return UserModel.update({
|
||||
id,
|
||||
canEditName: true
|
||||
}, {
|
||||
$set: {
|
||||
displayName: displayName.toLowerCase(),
|
||||
username: username,
|
||||
lowercaseUsername: username.toLowerCase(),
|
||||
canEditName: false,
|
||||
status: 'PENDING'
|
||||
}
|
||||
|
||||
@@ -201,22 +201,22 @@ class Wordlist {
|
||||
/**
|
||||
* check potential username for banned words, special characters
|
||||
*/
|
||||
static displayNameCheck(displayName) {
|
||||
static usernameCheck(username) {
|
||||
const wl = new Wordlist();
|
||||
|
||||
return wl.load()
|
||||
.then(() => {
|
||||
displayName = displayName.replace(/_/g, '');
|
||||
username = username.replace(/_/g, '');
|
||||
|
||||
// test each word, and fail if we find a match
|
||||
const hasBadWords = wl.lists.banned.some(phrase => {
|
||||
return displayName.indexOf(phrase.join('')) !== -1;
|
||||
return username.indexOf(phrase.join('')) !== -1;
|
||||
});
|
||||
|
||||
if (hasBadWords) {
|
||||
throw Errors.ErrContainsProfanity;
|
||||
} else {
|
||||
return Promise.resolve(displayName);
|
||||
return Promise.resolve(username);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ const embedStreamCommands = {
|
||||
.setValue('@signInDialogEmail', user.email)
|
||||
.setValue('@signInDialogPassword', user.pass)
|
||||
.setValue('@signUpDialogConfirmPassword', user.pass)
|
||||
.setValue('@signUpDialogDisplayName', user.displayName)
|
||||
.setValue('@signUpDialogDisplayName', user.username)
|
||||
.waitForElementVisible('@signUpButton')
|
||||
.click('@signUpButton')
|
||||
.waitForElementVisible('@signInViewTrigger')
|
||||
@@ -96,7 +96,7 @@ module.exports = {
|
||||
selector: '#signInDialog #confirmPassword'
|
||||
},
|
||||
signUpDialogDisplayName: {
|
||||
selector: '#signInDialog #displayName'
|
||||
selector: '#signInDialog #username'
|
||||
},
|
||||
logInButton: {
|
||||
selector: '#coralLogInButton'
|
||||
|
||||
@@ -37,7 +37,7 @@ module.exports = {
|
||||
.click('#coralRegister')
|
||||
.waitForElementVisible('#email', 1000)
|
||||
.setValue('#email', mockUser.email)
|
||||
.setValue('#displayName', mockUser.name)
|
||||
.setValue('#username', mockUser.name)
|
||||
.setValue('#password', mockUser.pw)
|
||||
.setValue('#confirmPassword', mockUser.pw)
|
||||
.click('#coralSignUpButton')
|
||||
@@ -125,7 +125,7 @@ module.exports = {
|
||||
|
||||
// Add a mock user
|
||||
.then(() => mocks.users([{
|
||||
displayName: 'Baby Blue',
|
||||
username: 'Baby Blue',
|
||||
email: 'whale@tale.sea',
|
||||
password: 'krill'
|
||||
}]))
|
||||
|
||||
@@ -13,7 +13,7 @@ module.exports = {
|
||||
embedStreamPage
|
||||
.signUp({
|
||||
email: `visitor_${Date.now()}@test.com`,
|
||||
displayName: `visitor${Date.now()}`,
|
||||
username: `visitor${Date.now()}`,
|
||||
pass: 'testtest'
|
||||
});
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ chai.use(require('chai-http'));
|
||||
|
||||
const UsersService = require('../../../../services/users');
|
||||
|
||||
describe('/api/v1/account/displayname', () => {
|
||||
describe('/api/v1/account/username', () => {
|
||||
let mockUser;
|
||||
|
||||
beforeEach(() => SettingsService.init(settings).then(() => {
|
||||
@@ -29,9 +29,9 @@ describe('/api/v1/account/displayname', () => {
|
||||
.post(`/api/v1/users/${mockUser.id}/username-enable`)
|
||||
.set(passport.inject({id: '456', roles: ['ADMIN']}))
|
||||
.then(() => chai.request(app)
|
||||
.put('/api/v1/account/displayname')
|
||||
.put('/api/v1/account/username')
|
||||
.set(passport.inject({id: mockUser.id, roles: []}))
|
||||
.send({displayName: 'MojoJojo'}))
|
||||
.send({username: 'MojoJojo'}))
|
||||
.then((res) => {
|
||||
expect(res).to.have.status(204);
|
||||
});
|
||||
@@ -42,9 +42,9 @@ describe('/api/v1/account/displayname', () => {
|
||||
.post(`/api/v1/users/${mockUser.id}/username-enable`)
|
||||
.set(passport.inject({id: '456', roles: ['ADMIN']}))
|
||||
.then(() => chai.request(app)
|
||||
.put('/api/v1/account/displayname')
|
||||
.put('/api/v1/account/username')
|
||||
.set(passport.inject({id: 'wrongid', roles: []}))
|
||||
.send({displayName: 'MojoJojo'}))
|
||||
.send({username: 'MojoJojo'}))
|
||||
.then(() => {
|
||||
done(new Error('Exected Error'));
|
||||
})
|
||||
@@ -56,7 +56,7 @@ describe('/api/v1/account/displayname', () => {
|
||||
|
||||
it('it should return an error when the user tries to edit their username if canEditName is disabled', (done) => {
|
||||
chai.request(app)
|
||||
.put('/api/v1/account/displayname')
|
||||
.put('/api/v1/account/username')
|
||||
.set(passport.inject({id: mockUser.id, roles: []}))
|
||||
.send({username: 'MojoJojo'})
|
||||
.then(() => {
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('/api/v1/auth/local', () => {
|
||||
expect(res2).to.have.status(200);
|
||||
expect(res2).to.be.json;
|
||||
expect(res2.body).to.have.property('user');
|
||||
expect(res2.body.user).to.have.property('displayName', 'maria');
|
||||
expect(res2.body.user).to.have.property('username', 'Maria');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -91,7 +91,7 @@ describe('/api/v1/auth/local', () => {
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.be.json;
|
||||
expect(res.body).to.have.property('user');
|
||||
expect(res.body.user).to.have.property('displayName', 'maria');
|
||||
expect(res.body.user).to.have.property('username', 'Maria');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,11 +49,11 @@ describe('/api/v1/comments', () => {
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
displayName: 'Ana',
|
||||
username: 'Ana',
|
||||
email: 'ana@gmail.com',
|
||||
password: '123456789'
|
||||
}, {
|
||||
displayName: 'Maria',
|
||||
username: 'Maria',
|
||||
email: 'maria@gmail.com',
|
||||
password: '123456789'
|
||||
}];
|
||||
@@ -183,11 +183,11 @@ describe('/api/v1/comments/:comment_id', () => {
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
displayName: 'Ana',
|
||||
username: 'Ana',
|
||||
email: 'ana@gmail.com',
|
||||
password: '123456789'
|
||||
}, {
|
||||
displayName: 'Maria',
|
||||
username: 'Maria',
|
||||
email: 'maria@gmail.com',
|
||||
password: '123456789'
|
||||
}];
|
||||
|
||||
@@ -45,11 +45,11 @@ describe('/api/v1/queue', () => {
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
displayName: 'Ana',
|
||||
username: 'Ana',
|
||||
email: 'ana@gmail.com',
|
||||
password: '123456789'
|
||||
}, {
|
||||
displayName: 'Maria',
|
||||
username: 'Maria',
|
||||
email: 'maria@gmail.com',
|
||||
password: '123456789'
|
||||
}];
|
||||
@@ -103,7 +103,7 @@ describe('/api/v1/queue', () => {
|
||||
expect(res).to.have.status(200);
|
||||
expect(res.body.comments).to.have.length(1);
|
||||
expect(res.body.comments[0]).to.have.property('body');
|
||||
expect(res.body.users[0]).to.have.property('displayName');
|
||||
expect(res.body.users[0]).to.have.property('username');
|
||||
expect(res.body.actions[0]).to.have.property('action_type');
|
||||
});
|
||||
});
|
||||
@@ -115,7 +115,7 @@ describe('/api/v1/queue', () => {
|
||||
.end(function(err, res){
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
expect(res.body.users[0]).to.have.property('displayName');
|
||||
expect(res.body.users[0]).to.have.property('username');
|
||||
expect(res.body.actions[0]).to.have.property('action_type');
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -69,15 +69,12 @@ describe('services.CommentsService', () => {
|
||||
|
||||
const users = [{
|
||||
email: 'stampi@gmail.com',
|
||||
displayName: 'Stampi',
|
||||
password: '1Coral!!',
|
||||
roles: ['ADMIN'],
|
||||
_id: '1'
|
||||
username: 'Stampi',
|
||||
password: '1Coral!!'
|
||||
}, {
|
||||
email: 'sockmonster@gmail.com',
|
||||
displayName: 'Sockmonster',
|
||||
password: '2Coral!!',
|
||||
_id : '2'
|
||||
username: 'Sockmonster',
|
||||
password: '2Coral!!'
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
@@ -257,42 +254,5 @@ describe('services.CommentsService', () => {
|
||||
expect(c.status_history[1]).to.have.property('assigned_by', '123');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#tagByStaff()', () => {
|
||||
|
||||
it('creates a new comment by admin', () => {
|
||||
return UsersService.findLocalUser('stampi@gmail.com', '1Coral!!').then((user) => {
|
||||
return UsersService.addRoleToUser(user.id, 'ADMIN').then(() => {
|
||||
UsersService.findById(user.id).then((u) => {
|
||||
return CommentsService
|
||||
.publicCreate({
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED',
|
||||
author_id: u.id
|
||||
}).then((c) => {
|
||||
expect(c).to.not.be.null;
|
||||
expect(c.tags).to.not.have.length(0);
|
||||
expect(c.tags[0].name).to.be.equal('STAFF');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a new comment by non admin', () => {
|
||||
return UsersService.findLocalUser('sockmonster@gmail.com', '2Coral!!').then((user) => {
|
||||
return CommentsService
|
||||
.publicCreate({
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED',
|
||||
author_id: user.id
|
||||
}).then((c) => {
|
||||
expect(c).to.not.be.null;
|
||||
expect(c.tags).to.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+11
-12
@@ -12,15 +12,15 @@ describe('services.UsersService', () => {
|
||||
return SettingsService.init(settings).then(() => {
|
||||
return UsersService.createLocalUsers([{
|
||||
email: 'stampi@gmail.com',
|
||||
displayName: 'Stampi',
|
||||
username: 'Stampi',
|
||||
password: '1Coral!-'
|
||||
}, {
|
||||
email: 'sockmonster@gmail.com',
|
||||
displayName: 'Sockmonster',
|
||||
username: 'Sockmonster',
|
||||
password: '2Coral!2'
|
||||
}, {
|
||||
email: 'marvel@gmail.com',
|
||||
displayName: 'Marvel',
|
||||
username: 'Marvel',
|
||||
password: '3Coral!3'
|
||||
}]).then((users) => {
|
||||
mockUsers = users;
|
||||
@@ -33,7 +33,7 @@ describe('services.UsersService', () => {
|
||||
return UsersService
|
||||
.findById(mockUsers[0].id)
|
||||
.then((user) => {
|
||||
expect(user).to.have.property('displayName', 'stampi');
|
||||
expect(user).to.have.property('username', 'Stampi');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -53,11 +53,11 @@ describe('services.UsersService', () => {
|
||||
return UsersService.findPublicByIdArray(ids).then((result) => {
|
||||
expect(result).to.have.length(3);
|
||||
const sorted = result.sort((a, b) => {
|
||||
if(a.displayName < b.displayName) {return -1;}
|
||||
if(a.displayName > b.displayName) {return 1;}
|
||||
if(a.username < b.username) {return -1;}
|
||||
if(a.username > b.username) {return 1;}
|
||||
return 0;
|
||||
});
|
||||
expect(sorted[0]).to.have.property('displayName', 'marvel');
|
||||
expect(sorted[0]).to.have.property('username', 'Marvel');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -68,8 +68,7 @@ describe('services.UsersService', () => {
|
||||
return UsersService
|
||||
.findLocalUser(mockUsers[0].profiles[0].id, '1Coral!-')
|
||||
.then((user) => {
|
||||
expect(user).to.have.property('displayName')
|
||||
.and.to.equal(mockUsers[0].displayName.toLowerCase());
|
||||
expect(user).to.have.property('username', mockUsers[0].username);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,10 +83,10 @@ describe('services.UsersService', () => {
|
||||
});
|
||||
|
||||
describe('#createLocalUser', () => {
|
||||
it('should not create a user with duplicate display name', () => {
|
||||
it('should not create a user with duplicate username', () => {
|
||||
return UsersService.createLocalUsers([{
|
||||
email: 'otrostampi@gmail.com',
|
||||
displayName: 'StampiTheSecond',
|
||||
username: 'StampiTheSecond',
|
||||
password: '1Coralito!'
|
||||
}])
|
||||
.then((user) => {
|
||||
@@ -227,7 +226,7 @@ describe('services.UsersService', () => {
|
||||
.then(() => UsersService.editName(mockUsers[0].id, 'Jojo'))
|
||||
.then(() => UsersService.findById(mockUsers[0].id))
|
||||
.then((user) => {
|
||||
expect(user).to.have.property('displayName', 'jojo');
|
||||
expect(user).to.have.property('username', 'Jojo');
|
||||
expect(user).to.have.property('canEditName', false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
window.opener.authCallback(<% if (err) { %>'<%- err %>'<% } else { %>null<% } %>, '<%- data %>');
|
||||
setTimeout(function() { window.close(); }, 50);
|
||||
// setTimeout(function() { window.close(); }, 50);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user