From 5126b40538d0ca0116bfa18bf9469b6b67f9a466 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 24 Feb 2017 03:56:25 -0300 Subject: [PATCH] Ivan - Fix AreYouSure design, fix stats, rename get-api-keys, use allow-attachment, fix login verificationToken, fix deletion, fix ticket view permission, fix last events when empty, fix configuration in frontend, fix system preferences and my account --- client/src/actions/modal-actions.js | 4 +- client/src/app-components/activity-row.js | 2 +- client/src/app-components/activity-row.scss | 8 ++-- client/src/app-components/are-you-sure.js | 30 +++++++++---- client/src/app-components/are-you-sure.scss | 43 ++++++++++++++----- client/src/app-components/modal-container.js | 12 +++--- client/src/app-components/people-list.js | 2 +- client/src/app-components/ticket-viewer.js | 13 ++++-- .../panel/dashboard/admin-panel-my-account.js | 4 +- .../panel/dashboard/admin-panel-stats.js | 2 +- .../admin-panel-system-preferences.js | 6 +-- .../panel/staff/admin-panel-departments.scss | 1 + .../panel/staff/admin-panel-staff-members.js | 6 +-- .../src/app/admin/panel/staff/staff-editor.js | 4 ++ .../panel/users/admin-panel-list-users.js | 4 +- client/src/app/demo/components-demo-page.js | 4 +- .../dashboard-edit-profile-page.js | 5 +-- client/src/app/main/main-layout-header.js | 2 +- client/src/core-components/modal.js | 15 ++++++- client/src/core-components/modal.scss | 7 +++ client/src/data/languages/en.js | 4 +- client/src/lib-app/api-call.js | 1 + client/src/lib-app/session-store.js | 7 ++- client/src/reducers/admin-data-reducer.js | 10 ----- client/src/reducers/config-reducer.js | 4 ++ client/src/reducers/modal-reducer.js | 7 ++- server/controllers/staff/last-events.php | 9 ++-- server/controllers/system.php | 4 +- .../{get-all-keys.php => get-api-keys.php} | 4 +- server/controllers/ticket/get.php | 2 +- server/controllers/user/delete.php | 5 +++ server/controllers/user/login.php | 13 +++--- server/libs/Controller.php | 4 +- server/libs/DataStoreList.php | 4 ++ tests/init.rb | 2 +- .../{get-all-keys.rb => get-api-keys.rb} | 6 +-- 36 files changed, 169 insertions(+), 91 deletions(-) rename server/controllers/system/{get-all-keys.php => get-api-keys.php} (81%) rename tests/system/{get-all-keys.rb => get-api-keys.rb} (86%) diff --git a/client/src/actions/modal-actions.js b/client/src/actions/modal-actions.js index 06f6c939..903c1d63 100644 --- a/client/src/actions/modal-actions.js +++ b/client/src/actions/modal-actions.js @@ -1,9 +1,9 @@ export default { - openModal(content) { + openModal(config) { return { type: 'OPEN_MODAL', - payload: content + payload: config } }, diff --git a/client/src/app-components/activity-row.js b/client/src/app-components/activity-row.js index dab5d581..14396977 100644 --- a/client/src/app-components/activity-row.js +++ b/client/src/app-components/activity-row.js @@ -68,7 +68,7 @@ class ActivityRow extends React.Component { {i18n('ACTIVITY_' + this.props.type)} - {_.includes(ticketRelatedTypes, this.props.type) ? this.renderTicketNumber() : null} + {_.includes(ticketRelatedTypes, this.props.type) ? this.renderTicketNumber() : this.props.to} ); diff --git a/client/src/app-components/activity-row.scss b/client/src/app-components/activity-row.scss index 866d2aca..885d7f47 100644 --- a/client/src/app-components/activity-row.scss +++ b/client/src/app-components/activity-row.scss @@ -19,8 +19,8 @@ &__ticket-link { } -} -.separator { - margin: 15px; -} \ No newline at end of file + .separator { + margin: 15px; + } +} diff --git a/client/src/app-components/are-you-sure.js b/client/src/app-components/are-you-sure.js index 4bff7460..55dc6f8c 100644 --- a/client/src/app-components/are-you-sure.js +++ b/client/src/app-components/are-you-sure.js @@ -1,9 +1,12 @@ import React from 'react'; import i18n from 'lib-app/i18n'; +import ModalContainer from 'app-components/modal-container'; + import Button from 'core-components/button'; import Input from 'core-components/input'; -import ModalContainer from 'app-components/modal-container'; +import Icon from 'core-components/icon'; + class AreYouSure extends React.Component { static propTypes = { @@ -26,7 +29,8 @@ class AreYouSure extends React.Component { static openModal(description, onYes, type) { ModalContainer.openModal( - + , + true ); } @@ -40,21 +44,25 @@ class AreYouSure extends React.Component {
{i18n('ARE_YOU_SURE')}
+ + +
{this.props.description || (this.props.type === 'secure' && i18n('PLEASE_CONFIRM_PASSWORD'))}
{(this.props.type === 'secure') ? this.renderPassword() : null} +
-
- -
+
+ +
); @@ -62,7 +70,7 @@ class AreYouSure extends React.Component { renderPassword() { return ( - + ); } @@ -79,7 +87,11 @@ class AreYouSure extends React.Component { } onYes() { - if (this.props.type === 'default' || this.state.password){ + if (this.props.type === 'secure' && !this.state.password) { + this.refs.password.focus() + } + + if (this.props.type === 'default' || this.state.password) { this.closeModal(); if (this.props.onYes) { diff --git a/client/src/app-components/are-you-sure.scss b/client/src/app-components/are-you-sure.scss index 9bb1964a..0bfc4f0d 100644 --- a/client/src/app-components/are-you-sure.scss +++ b/client/src/app-components/are-you-sure.scss @@ -1,25 +1,30 @@ @import "../scss/vars"; .are-you-sure { - width: 400px; - text-align: center; + width: 800px; + text-align: left; &__header { - color: $primary-red; - font-size: $font-size--xl; + background-color: $secondary-blue; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + color: white; + font-size: $font-size--lg; font-weight: bold; - margin-bottom: 20px; - + margin-bottom: 10px; + padding: 10px; } &__description { color: $dark-grey; font-size: $font-size--md; - margin-bottom: 50px; + padding: 14px 5% 0; } &__buttons { - margin: 0 auto; + margin-top: 10px; + padding-bottom: 10px; + text-align: right; } &__yes-button, @@ -30,7 +35,25 @@ &__password { margin: 0 auto; - margin-top: -30px; - margin-bottom: 20px; + margin-top: 20px; + } + + &__close-icon { + cursor: pointer; + position: absolute; + top: 10px; + right: 10px; + color: white; + } + + .separator { + width: 90%; + margin: 30px auto; + } +} + +@media screen and (max-width: 800px) { + .are-you-sure { + width: auto; } } \ No newline at end of file diff --git a/client/src/app-components/modal-container.js b/client/src/app-components/modal-container.js index 4cd8e03e..ff8956eb 100644 --- a/client/src/app-components/modal-container.js +++ b/client/src/app-components/modal-container.js @@ -1,6 +1,7 @@ import React from 'react'; import { connect } from 'react-redux'; import keyCode from 'keycode'; +import classNames from 'classnames'; import store from 'app/store'; import ModalActions from 'actions/modal-actions'; @@ -8,11 +9,12 @@ import Modal from 'core-components/modal'; class ModalContainer extends React.Component { - static openModal(content) { + static openModal(content, noPadding) { store.dispatch( - ModalActions.openModal( - content - ) + ModalActions.openModal({ + content, + noPadding + }) ); } @@ -48,7 +50,7 @@ class ModalContainer extends React.Component { renderModal() { return ( - + ); } diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index 6a636bd3..401be219 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -13,7 +13,7 @@ class PeopleList extends React.Component { name: React.PropTypes.node, assignedTickets: React.PropTypes.number, closedTickets: React.PropTypes.number, - lastLogin: React.PropTypes.number + lastLogin: React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.string]) })), pageSize: React.PropTypes.number, page: React.PropTypes.number, diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index ff21c462..adc85536 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -1,6 +1,7 @@ import React from 'react'; import _ from 'lodash'; import RichTextEditor from 'react-rte-browserify'; +import {connect} from 'react-redux'; import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; @@ -190,7 +191,7 @@ class TicketViewer extends React.Component {
- + {(this.props.allowAttachments) ? : null} {i18n('RESPOND_TICKET')}
@@ -333,7 +334,9 @@ class TicketViewer extends React.Component { onCommentSuccess() { this.setState({ loading: false, - commentError: false + commentValue: RichTextEditor.createEmptyValue(), + commentError: false, + commentEdited: false }); this.onTicketModification(); @@ -353,4 +356,8 @@ class TicketViewer extends React.Component { } } -export default TicketViewer; +export default connect((store) => { + return { + allowAttachments: store.config['allow-attachments'] + }; +})(TicketViewer); diff --git a/client/src/app/admin/panel/dashboard/admin-panel-my-account.js b/client/src/app/admin/panel/dashboard/admin-panel-my-account.js index 165db779..2f53b03d 100644 --- a/client/src/app/admin/panel/dashboard/admin-panel-my-account.js +++ b/client/src/app/admin/panel/dashboard/admin-panel-my-account.js @@ -23,11 +23,11 @@ class AdminPanelMyAccount extends React.Component { getEditorProps() { return { myAccount: true, - staffId: this.props.userId, + staffId: this.props.userId * 1, name: this.props.userName, email: this.props.userEmail, profilePic: this.props.userProfilePic, - level: this.props.userLevel, + level: this.props.userLevel * 1, departments: this.props.userDepartments, onChange: () => this.props.dispatch(SessionActions.getUserData(null, null, true)) }; diff --git a/client/src/app/admin/panel/dashboard/admin-panel-stats.js b/client/src/app/admin/panel/dashboard/admin-panel-stats.js index c5452e50..e3be6ac3 100644 --- a/client/src/app/admin/panel/dashboard/admin-panel-stats.js +++ b/client/src/app/admin/panel/dashboard/admin-panel-stats.js @@ -8,7 +8,7 @@ class AdminPanelStats extends React.Component { render() { return ( -
+
diff --git a/client/src/app/admin/panel/settings/admin-panel-system-preferences.js b/client/src/app/admin/panel/settings/admin-panel-system-preferences.js index 226dd4cf..248a1f1b 100644 --- a/client/src/app/admin/panel/settings/admin-panel-system-preferences.js +++ b/client/src/app/admin/panel/settings/admin-panel-system-preferences.js @@ -213,15 +213,15 @@ class AdminPanelSystemPreferences extends React.Component { 'reCaptchaPrivate': result.data.reCaptchaPrivate, 'url': result.data['url'], 'title': result.data['title'], - 'layout': result.data['layout'] == 'full-width' ? 1 : 0, + 'layout': (result.data['layout'] == 'full-width') ? 1 : 0, 'time-zone': result.data['time-zone'], 'no-reply-email': result.data['no-reply-email'], 'smtp-host': result.data['smtp-host'], 'smtp-port': result.data['smtp-port'], 'smtp-user': result.data['smtp-user'], 'smtp-pass': '', - 'maintenance-mode': result.data['maintenance-mode'], - 'allow-attachments': result.data['allow-attachments'], + 'maintenance-mode': !!(result.data['maintenance-mode'] * 1), + 'allow-attachments': !!(result.data['allow-attachments'] * 1), 'max-size': result.data['max-size'], 'allowedLanguages': result.data.allowedLanguages.map(lang => (_.indexOf(languageKeys, lang))), 'supportedLanguages': result.data.supportedLanguages.map(lang => (_.indexOf(languageKeys, lang))) diff --git a/client/src/app/admin/panel/staff/admin-panel-departments.scss b/client/src/app/admin/panel/staff/admin-panel-departments.scss index 05a2441f..33eec06e 100644 --- a/client/src/app/admin/panel/staff/admin-panel-departments.scss +++ b/client/src/app/admin/panel/staff/admin-panel-departments.scss @@ -9,6 +9,7 @@ &__update-name-button { float: left; + min-width: 156px; } &__optional-buttons { diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 712d4185..4717d2eb 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -68,9 +68,9 @@ class AdminPanelStaffMembers extends React.Component { if(!this.state.selectedDepartment) { staffList = this.state.staffList; } else { - staffList = _.filter(this.state.staffList, (o) => { - return _.findIndex(o.departments, {id: this.state.selectedDepartment}) !== -1; - }) + staffList = _.filter(this.state.staffList, (staff) => { + return _.findIndex(staff.departments, {id: this.state.selectedDepartment}) !== -1; + }); } return staffList.map(staff => { diff --git a/client/src/app/admin/panel/staff/staff-editor.js b/client/src/app/admin/panel/staff/staff-editor.js index 6e0d0231..1375dfff 100644 --- a/client/src/app/admin/panel/staff/staff-editor.js +++ b/client/src/app/admin/panel/staff/staff-editor.js @@ -31,6 +31,10 @@ class StaffEditor extends React.Component { onDelete: React.PropTypes.func }; + static defaultProps = { + tickets: [] + }; + state = { email: this.props.email, level: this.props.level - 1, diff --git a/client/src/app/admin/panel/users/admin-panel-list-users.js b/client/src/app/admin/panel/users/admin-panel-list-users.js index 0b2896ec..25607145 100644 --- a/client/src/app/admin/panel/users/admin-panel-list-users.js +++ b/client/src/app/admin/panel/users/admin-panel-list-users.js @@ -151,8 +151,8 @@ class AdminPanelListUsers extends React.Component { onUsersRetrieved(result) { this.setState({ - page: result.data.page, - pages: result.data.pages, + page: result.data.page * 1, + pages: result.data.pages * 1, users: result.data.users, orderBy: result.data.orderBy, desc: (result.data.desc === '1'), diff --git a/client/src/app/demo/components-demo-page.js b/client/src/app/demo/components-demo-page.js index 68042fd4..9e42865c 100644 --- a/client/src/app/demo/components-demo-page.js +++ b/client/src/app/demo/components-demo-page.js @@ -153,9 +153,7 @@ let DemoPage = React.createClass({ title: 'ModalTrigger', render: ( diff --git a/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js b/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js index f2d8ad45..1ab5ab3a 100644 --- a/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js +++ b/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js @@ -3,7 +3,6 @@ import React from 'react'; import API from 'lib-app/api-call'; import i18n from 'lib-app/i18n'; -import ModalContainer from 'app-components/modal-container'; import AreYouSure from 'app-components/are-you-sure'; import Header from 'core-components/header'; @@ -64,11 +63,11 @@ class DashboardEditProfilePage extends React.Component { } } onSubmitEditEmail(formState) { - ModalContainer.openModal(); + AreYouSure.openModal(i18n('EMAIL_WILL_CHANGE'), this.callEditEmailAPI.bind(this, formState)); } onSubmitEditPassword(formState) { - ModalContainer.openModal(); + AreYouSure.openModal(i18n('PASSWORD_WILL_CHANGE'), this.callEditPassAPI.bind(this, formState)); } callEditEmailAPI(formState){ diff --git a/client/src/app/main/main-layout-header.js b/client/src/app/main/main-layout-header.js index 014afa5e..57979555 100644 --- a/client/src/app/main/main-layout-header.js +++ b/client/src/app/main/main-layout-header.js @@ -32,7 +32,7 @@ class MainLayoutHeader extends React.Component { result = (
- {(this.props.config['registration']) ? : null} + {(!!(this.props.config['registration'] * 1)) ? : null}
); } diff --git a/client/src/core-components/modal.js b/client/src/core-components/modal.js index 6a6f21a7..fc25ab0d 100644 --- a/client/src/core-components/modal.js +++ b/client/src/core-components/modal.js @@ -1,10 +1,12 @@ import React from 'react'; +import classNames from 'classnames'; import {Motion, spring} from 'react-motion'; class Modal extends React.Component { static propTypes = { - content: React.PropTypes.node + content: React.PropTypes.node, + noPadding: React.PropTypes.bool }; render() { @@ -30,13 +32,22 @@ class Modal extends React.Component { renderModal(animation) { return ( -
+
{this.props.content}
) } + + getClass() { + let classes = { + 'modal': true, + 'modal_no-padding': this.props.noPadding + }; + + return classNames(classes); + } } export default Modal; \ No newline at end of file diff --git a/client/src/core-components/modal.scss b/client/src/core-components/modal.scss index 965ab805..e8615704 100644 --- a/client/src/core-components/modal.scss +++ b/client/src/core-components/modal.scss @@ -18,4 +18,11 @@ padding: 50px; box-shadow: 0 0 10px white; } + + &_no-padding { + + .modal__content { + padding: 0; + } + } } \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 739c770f..84c342c0 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -281,7 +281,9 @@ export default { 'TICKET_SENT': 'Ticket has been created successfully.', 'VALID_RECOVER': 'Password recovered successfully', 'EMAIL_EXISTS': 'Email already exists', - 'ARE_YOU_SURE': 'Are you sure?', + 'ARE_YOU_SURE': 'Confirm action', + 'EMAIL_WILL_CHANGE': 'The current email will be changed', + 'PASSWORD_WILL_CHANGE': 'The current password will be changed', 'EMAIL_CHANGED': 'Email has been changed successfully', 'PASSWORD_CHANGED': 'Password has been changed successfully', 'OLD_PASSWORD_INCORRECT': 'Old password is incorrect', diff --git a/client/src/lib-app/api-call.js b/client/src/lib-app/api-call.js index 2979e9b9..b20cf618 100644 --- a/client/src/lib-app/api-call.js +++ b/client/src/lib-app/api-call.js @@ -29,6 +29,7 @@ function processData (data, dataAsForm = false) { module.exports = { call: function ({path, data, plain, dataAsForm}) { + console.log('request ' + path, data); return new Promise(function (resolve, reject) { APIUtils.post(apiUrl + path, processData(data, dataAsForm), dataAsForm) .then(function (result) { diff --git a/client/src/lib-app/session-store.js b/client/src/lib-app/session-store.js index 0deb8c60..142c4b6c 100644 --- a/client/src/lib-app/session-store.js +++ b/client/src/lib-app/session-store.js @@ -62,6 +62,7 @@ class SessionStore { this.setItem('title', configs.title); this.setItem('registration', configs.registration); this.setItem('user-system-enabled', configs['user-system-enabled']); + this.setItem('allow-attachments', configs['allow-attachments']); } getConfigs() { @@ -72,9 +73,11 @@ class SessionStore { allowedLanguages: JSON.parse(this.getItem('allowedLanguages')), supportedLanguages: JSON.parse(this.getItem('supportedLanguages')), layout: this.getItem('layout'), - registration: this.getItem('registration'), title: this.getItem('title'), - ['user-system-enabled']: this.getItem('user-system-enabled') + registration: !!(this.getItem('registration') * 1), + 'user-system-enabled': !!(this.getItem('user-system-enabled') * 1), + 'allow-attachments': !!(this.getItem('allow-attachments') * 1), + 'maintenance-mode': !!(this.getItem('maintenance-mode') * 1) }; } diff --git a/client/src/reducers/admin-data-reducer.js b/client/src/reducers/admin-data-reducer.js index 30fc80f2..e3de7207 100644 --- a/client/src/reducers/admin-data-reducer.js +++ b/client/src/reducers/admin-data-reducer.js @@ -26,7 +26,6 @@ class AdminDataReducer extends Reducer { getTypeHandlers() { return { 'CUSTOM_RESPONSES_FULFILLED': this.onCustomResponses, - 'SESSION_CHECKED': this.onSessionChecked, 'MY_TICKETS_FULFILLED': this.onMyTicketsRetrieved, 'MY_TICKETS_REJECTED': this.onMyTicketsRejected, @@ -51,15 +50,6 @@ class AdminDataReducer extends Reducer { }); } - onSessionChecked(state) { - const customResponses = sessionStore.getItem('customResponses'); - - return _.extend({}, state, { - customResponses: JSON.parse(customResponses), - customResponsesLoaded: true - }); - } - onMyTicketsRetrieved(state, payload) { return _.extend({}, state, { myTickets: payload.data, diff --git a/client/src/reducers/config-reducer.js b/client/src/reducers/config-reducer.js index 5aee8933..d3861851 100644 --- a/client/src/reducers/config-reducer.js +++ b/client/src/reducers/config-reducer.js @@ -37,6 +37,10 @@ class ConfigReducer extends Reducer { return _.extend({}, state, payload.data, { language: currentLanguage || payload.language, + registration: !!(payload.data.registration * 1), + 'user-system-enabled': !!(payload.data['user-system-enabled']* 1), + 'allow-attachments': !!(payload.data['allow-attachments']* 1), + 'maintenance-mode': !!(payload.data['maintenance-mode']* 1), initDone: true }); } diff --git a/client/src/reducers/modal-reducer.js b/client/src/reducers/modal-reducer.js index cb12dc70..a4d8bcea 100644 --- a/client/src/reducers/modal-reducer.js +++ b/client/src/reducers/modal-reducer.js @@ -7,6 +7,7 @@ class ModalReducer extends Reducer { getInitialState() { return { opened: false, + noPadding: false, content: null }; } @@ -23,7 +24,8 @@ class ModalReducer extends Reducer { return _.extend({}, state, { opened: true, - content: payload + content: payload.content, + noPadding: payload.noPadding || false }); } @@ -32,7 +34,8 @@ class ModalReducer extends Reducer { return _.extend({}, state, { opened: false, - content: null + content: null, + noPadding: false }); } } diff --git a/server/controllers/staff/last-events.php b/server/controllers/staff/last-events.php index aae4b470..d48141e7 100644 --- a/server/controllers/staff/last-events.php +++ b/server/controllers/staff/last-events.php @@ -28,8 +28,11 @@ class LastEventsStaffController extends Controller { $query = substr($query,0,-3); $query .= ') ORDER BY id desc LIMIT ? OFFSET ?' ; - $eventList = Ticketevent::find($query, [10, 10*($page-1)]); - - Response::respondSuccess($eventList->toArray()); + if(Ticketevent::count() && !$user->sharedTicketList->isEmpty()) { + $eventList = Ticketevent::find($query, [10, 10*($page-1)]); + Response::respondSuccess($eventList->toArray()); + } else { + Response::respondSuccess([]); + } } } \ No newline at end of file diff --git a/server/controllers/system.php b/server/controllers/system.php index b36fc8c6..4670a161 100644 --- a/server/controllers/system.php +++ b/server/controllers/system.php @@ -15,7 +15,7 @@ require_once 'system/disable-user-system.php'; require_once 'system/enabled-user-system.php'; require_once 'system/add-api-key.php'; require_once 'system/delete-api-key.php'; -require_once 'system/get-all-keys.php'; +require_once 'system/get-api-keys.php'; require_once 'system/get-stats.php'; require_once 'system/delete-all-users.php'; require_once 'system/csv-import.php'; @@ -40,7 +40,7 @@ $systemControllerGroup->addController(new EnableRegistrationController); $systemControllerGroup->addController(new GetStatsController); $systemControllerGroup->addController(new AddAPIKeyController); $systemControllerGroup->addController(new DeleteAPIKeyController); -$systemControllerGroup->addController(new GetAllKeyController); +$systemControllerGroup->addController(new GetAPIKeysController); $systemControllerGroup->addController(new DeleteAllUsersController); $systemControllerGroup->addController(new BackupDatabaseController); $systemControllerGroup->addController(new DownloadController); diff --git a/server/controllers/system/get-all-keys.php b/server/controllers/system/get-api-keys.php similarity index 81% rename from server/controllers/system/get-all-keys.php rename to server/controllers/system/get-api-keys.php index fa896451..b9beaa0f 100644 --- a/server/controllers/system/get-all-keys.php +++ b/server/controllers/system/get-api-keys.php @@ -1,8 +1,8 @@ ticket->author->id !== $user->id)) || - (Controller::isStaffLogged() && $this->ticket->owner && $this->ticket->owner->id !== $user->id); + (Controller::isStaffLogged() && !$user->sharedDepartmentList->includesId($this->ticket->department->id)); } } \ No newline at end of file diff --git a/server/controllers/user/delete.php b/server/controllers/user/delete.php index bfc86a06..6d935f45 100644 --- a/server/controllers/user/delete.php +++ b/server/controllers/user/delete.php @@ -30,6 +30,11 @@ class DeleteUserController extends Controller { Log::createLog('DELETE_USER', $user->name); RedBean::exec('DELETE FROM log WHERE author_user_id = ?', [$userId]); + + foreach($user->sharedTicketList as $ticket) { + $ticket->delete(); + } + $user->delete(); Response::respondSuccess(); diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php index 952578de..99dc1b07 100644 --- a/server/controllers/user/login.php +++ b/server/controllers/user/login.php @@ -24,6 +24,11 @@ class LoginController extends Controller { } if ($this->checkInputCredentials() || $this->checkRememberToken()) { + if($this->userInstance->verificationToken !== null) { + Response::respondError(ERRORS::UNVERIFIED_USER); + return; + } + $this->createUserSession(); $this->createSessionCookie(); if(Controller::request('staff')) { @@ -31,14 +36,6 @@ class LoginController extends Controller { $this->userInstance->store(); } - $email = Controller::request('email'); - $userRow = User::getDataStore($email, 'email'); - - if($userRow->verificationToken !== null) { - Response::respondError(ERRORS::UNVERIFIED_USER); - return; - } - Response::respondSuccess($this->getUserData()); } else { Response::respondError(ERRORS::INVALID_CREDENTIALS); diff --git a/server/libs/Controller.php b/server/libs/Controller.php index 3fe2db45..0f7119ee 100644 --- a/server/libs/Controller.php +++ b/server/libs/Controller.php @@ -79,7 +79,9 @@ abstract class Controller { } public function uploadFile() { - if(!isset($_FILES['file'])) return ''; + $allowAttachments = Setting::getSetting('allow-attachments')->getValue(); + + if(!isset($_FILES['file']) || !$allowAttachments) return ''; $maxSize = Setting::getSetting('max-size')->getValue(); $fileGap = Setting::getSetting('file-gap')->getValue(); diff --git a/server/libs/DataStoreList.php b/server/libs/DataStoreList.php index 6fd4b70f..84a75bd7 100644 --- a/server/libs/DataStoreList.php +++ b/server/libs/DataStoreList.php @@ -45,6 +45,10 @@ class DataStoreList implements IteratorAggregate { return $includes; } + public function isEmpty() { + return empty($list); + } + public function toBeanList() { $beanList = []; diff --git a/tests/init.rb b/tests/init.rb index 038e23b6..0b853b13 100644 --- a/tests/init.rb +++ b/tests/init.rb @@ -55,7 +55,7 @@ require './system/disable-registration.rb' require './system/enable-registration.rb' require './system/add-api-key.rb' require './system/delete-api-key.rb' -require './system/get-all-keys.rb' +require './system/get-api-keys.rb' require './system/file-upload-download.rb' require './system/csv-import.rb' require './system/disable-user-system.rb' diff --git a/tests/system/get-all-keys.rb b/tests/system/get-api-keys.rb similarity index 86% rename from tests/system/get-all-keys.rb rename to tests/system/get-api-keys.rb index a604af3d..518dc818 100644 --- a/tests/system/get-all-keys.rb +++ b/tests/system/get-api-keys.rb @@ -1,15 +1,15 @@ -describe'system/get-all-keys' do +describe'system/get-api-keys' do request('/user/logout') Scripts.login($staff[:email], $staff[:password], true) - it 'should get all API keys' do + it 'should get all API keys' do Scripts.createAPIKey('namekey1') Scripts.createAPIKey('namekey2') Scripts.createAPIKey('namekey3') Scripts.createAPIKey('namekey4') Scripts.createAPIKey('namekey5') - result= request('/system/get-all-keys', { + result = request('/system/get-api-keys', { csrf_userid: $csrf_userid, csrf_token: $csrf_token, })