PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.0
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.0
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
← All changes | app/Http/Controllers/AgentController.php +111 -60 1.10.42.4.0 View file →
@@ -5,9 +5,9 @@
5 5 use FluentSupport\App\Models\Agent;
6 6 use FluentSupport\App\Modules\StatModule;
7 7 use FluentSupport\App\Services\AvatarUploder;
8 8 use FluentSupport\App\Services\Helper;
9 -use FluentSupport\Framework\Request\Request;
9 +use FluentSupport\Framework\Http\Request\Request;
10 10 use FluentSupport\App\Modules\PermissionManager;
11 11 use FluentSupport\App\Http\Requests\AgentCreateRequest;
12 12
13 13 /**
@@ -22,11 +22,11 @@
22 22 {
23 23 public function index(Request $request, Agent $agent)
24 24 {
25 25 return [
26 - 'agents' => $agent->getAgents($request->getSafe('search','sanitize_text_field')),
27 - 'permissions' => PermissionManager::getReadablePermissionGroups(),
28 - 'businessBoxes' => PermissionManager::getBusinessBoxesForRestriction(),
26 + 'agents' => $agent->getAgents($request->getSafe('search', 'sanitize_text_field')),
27 + 'permissions' => PermissionManager::getReadablePermissionGroups(),
28 + 'businessBoxes' => PermissionManager::getMailboxesForRestriction(),
29 29 ];
30 30 }
31 31
32 32 /**
@@ -36,16 +36,9 @@
36 36 * @throws \FluentSupport\Framework\Validator\ValidationException
37 37 */
38 38 public function addAgent(AgentCreateRequest $request, Agent $agent)
39 39 {
40 - $data = [
41 - 'email' => $request->getSafe('email', 'sanitize_email'),
42 - 'first_name' => $request->getSafe('first_name', 'sanitize_text_field'),
43 - 'last_name' => $request->getSafe('last_name', 'sanitize_text_field'),
44 - 'title' => $request->getSafe('title', 'sanitize_text_field'),
45 - 'permissions' => $request->getSafe('permissions', null, []),
46 - 'restrictions' => $request->getSafe('restrictions', null, []),
47 - ];
40 + $data = $this->sanitizeAgentPayload($request, true);
48 41
49 42 try {
50 43 return [
51 44 'message' => __('Support Staff has been added', 'fluent-support'),
@@ -50,12 +43,11 @@
50 43 return [
51 44 'message' => __('Support Staff has been added', 'fluent-support'),
52 45 'agent' => $agent->createAgent($data)
53 46 ];
54 -
55 47 } catch (\Exception $e) {
56 48 return $this->sendError([
57 - 'message' => $e->getMessage()
49 + 'message' => Helper::getSafeErrorMessage($e)
58 50 ]);
59 51 }
60 52 }
61 53
@@ -69,37 +61,24 @@
69 61 */
70 62 public function updateAgent(AgentCreateRequest $request, Agent $agent, $agent_id)
71 63 {
72 64 $agent = $agent::findOrFail($agent_id);
65 + $data = $this->sanitizeAgentPayload($request);
73 66
74 - $data = [
75 - 'first_name' => $request->getSafe('first_name', 'sanitize_text_field'),
76 - 'last_name' => $request->getSafe('last_name', 'sanitize_text_field'),
77 - 'title' => $request->getSafe('title', 'sanitize_text_field'),
78 - 'permissions' => $request->getSafe('permissions', null, []),
79 - 'telegram_chat_id' => $request->getSafe('telegram_chat_id', 'sanitize_text_field'),
80 - 'slack_user_id' => $request->getSafe('slack_user_id', 'sanitize_text_field'),
81 - 'whatsapp_number' => $request->getSafe('whatsapp_number', 'sanitize_text_field'),
82 - 'restrictions' => $request->getSafe('restrictions', null, []),
83 - ];
84 -
85 67 if (!$agent->user_id && ($user = get_user_by('email', $agent->email))) {
86 68 $agent->user_id = $user->ID;
87 69 }
88 70
89 - if ($agent) {
90 - try {
91 - return [
92 - 'message' => __('Support Staff has been updated', 'fluent-support'),
93 - 'agent' => $agent->updateAgent($data, $agent)
94 - ];
95 - } catch (\Exception $e) {
96 - return $this->sendError([
97 - 'message' => $e->getMessage()
98 - ]);
99 - }
71 + try {
72 + return [
73 + 'message' => __('Support Staff has been updated', 'fluent-support'),
74 + 'agent' => $agent->updateAgent($data, $agent)
75 + ];
76 + } catch (\Exception $e) {
77 + return $this->sendError([
78 + 'message' => Helper::getSafeErrorMessage($e)
79 + ]);
100 80 }
101 -
102 81 }
103 82
104 83 /**
105 84 * deleteAgent will delete an exiting agent and add an alternative agent as replacement
@@ -116,15 +95,13 @@
116 95
117 96 return [
118 97 'message' => __('Support Staff has been deleted', 'fluent-support')
119 98 ];
120 -
121 99 } catch (\Exception $e) {
122 100 return $this->sendError([
123 - 'message' => $e->getMessage()
101 + 'message' => Helper::getSafeErrorMessage($e)
124 102 ]);
125 103 }
126 -
127 104 }
128 105
129 106 /**
130 107 * @param Request $request
@@ -131,25 +108,27 @@
131 108 * @return \WP_REST_Response | array
132 109 */
133 110 public function myStats(Request $request)
134 111 {
112 + // Get logged in agent information.
113 + $agent = Helper::getAgentByUserId();
135 114
136 - $agent = Helper::getAgentByUserId();//Get logged in agent information
137 -
138 115 try {
139 - $stats = StatModule::getAgentStat($agent->id); //Get ticket statistics
116 + // Get ticket statistics.
117 + $stats = StatModule::getAgentStat($agent->id);
118 + $with = $request->get('with', []);
119 + $with = is_array($with) ? map_deep($with, 'sanitize_text_field') : [];
140 120
141 - $with = $request->getSafe('with');
142 -
143 121 $response = (new Agent())->getAgentStat($stats, $with, $agent->id);
144 122
145 123 if (defined('FLUENTSUPPORTPRO')) {
146 124 $response['dashboard_notice'] = apply_filters('fluent_support/dashboard_notice', '', $agent);
147 125 }
126 +
148 127 return $response;
149 128 } catch (\Exception $e) {
150 129 return $this->sendError([
151 - 'message' => $e->getMessage()
130 + 'message' => Helper::getSafeErrorMessage($e)
152 131 ]);
153 132 }
154 133 }
155 134
@@ -157,13 +136,14 @@
157 136 {
158 137 try {
159 138 if (PermissionManager::currentUserCan('fst_agent_today_performance')) {
160 139 $agentTodayStats = StatModule::getAgentTodayStats();
140 +
161 141 return ['agent_today_stats' => $agentTodayStats];
162 142 }
163 143 } catch (\Exception $e) {
164 144 return $this->sendError([
165 - 'message' => $e->getMessage()
145 + 'message' => Helper::getSafeErrorMessage($e)
166 146 ]);
167 147 }
168 148
169 149 return [];
@@ -178,12 +158,12 @@
178 158 */
179 159 public function addOrUpdateProfileImage(Request $request, AvatarUploder $avatarUploder)
180 160 {
181 161 try {
182 - return $avatarUploder->addOrUpdateProfileImage( $request->files(), $request->getSafe('agent_id', 'intval'), 'agent');
162 + return $avatarUploder->addOrUpdateProfileImage($request->files(), $request->getSafe('agent_id', 'intval'), 'agent');
183 163 } catch (\Exception $e) {
184 164 return $this->sendError([
185 - 'message' => $e->getMessage()
165 + 'message' => Helper::getSafeErrorMessage($e)
186 166 ]);
187 167 }
188 168 }
189 169
@@ -189,30 +169,35 @@
189 169
190 170 /**
191 171 * resetAvatar method will restore a Support Staff avatar
192 172 * For a successful upload it's required to send file object, Support Staff id and the user type(Support Staff)
193 - * @param Agent $agent
194 - * @param $agent_id
173 + *
174 + * No Agent type-hint here: route-model binding resolves inside the
175 + * permission callback, before any policy runs, which lets unauthenticated
176 + * callers probe agent ID existence (FS-PERM-001). Resolve after auth.
177 + * @param int|string $agent
195 178 * @return array
196 179 */
197 - public function resetAvatar(Agent $agent, $agent_id){
180 + public function resetAvatar($agent)
181 + {
198 182 try {
199 - $agent->restoreAvatar($agent, $agent_id);
183 + $agent = Agent::findOrFail((int) $agent);
184 + $agent->restoreAvatar();
200 185
201 186 return [
202 - 'message' => __('Support Staff avatar reset to gravatar default', 'fluent-support')
187 + 'message' => __('Support Staff avatar reset to gravatar default', 'fluent-support')
203 188 ];
204 189 } catch (\Exception $e) {
205 - return [
206 - 'message' => $e->getMessage()
207 - ];
190 + return $this->sendError([
191 + 'message' => Helper::getSafeErrorMessage($e)
192 + ]);
208 193 }
209 194 }
210 195
211 196 public function getAgentInsights(Request $request, Agent $agent)
212 - {
197 + {
213 198 return [
214 - 'agents' => $agent->agentInsights($request->getSafe('search','sanitize_text_field')),
199 + 'agents' => $agent->agentInsights($request->getSafe('search', 'sanitize_text_field')),
215 200 ];
216 201 }
217 202
218 203 public function ping(Request $request)
@@ -217,8 +202,74 @@
217 202
218 203 public function ping(Request $request)
219 204 {
220 205 return [
221 - 'ping' => 'pong'
206 + 'ping' => 'pong',
207 + ];
208 + }
209 +
210 + /**
211 + * Sanitize payload data for create/update operations.
212 + *
213 + * @param AgentCreateRequest $request
214 + * @param bool $includeEmail
215 + * @return array
216 + */
217 + private function sanitizeAgentPayload(AgentCreateRequest $request, $includeEmail = false)
218 + {
219 + $data = [
220 + 'first_name' => $request->getSafe('first_name', 'sanitize_text_field'),
221 + 'last_name' => $request->getSafe('last_name', 'sanitize_text_field'),
222 + 'title' => $request->getSafe('title', 'sanitize_text_field'),
223 + 'permissions' => is_array($request->get('permissions')) ? array_map('sanitize_key', $request->get('permissions')) : [],
224 + 'telegram_chat_id' => $request->getSafe('telegram_chat_id', 'sanitize_text_field'),
225 + 'slack_user_id' => $request->getSafe('slack_user_id', 'sanitize_text_field'),
226 + 'whatsapp_number' => $request->getSafe('whatsapp_number', 'sanitize_text_field'),
227 + 'restrictions' => $this->sanitizeRestrictions($request->get('restrictions')),
228 + ];
229 +
230 + if ($request->has('agent_signature')) {
231 + // Already unslashed at the request boundary; sanitize only, so literal
232 + // backslashes in the signature survive.
233 + $data['agent_signature'] = wp_kses_post($request->get('agent_signature', ''));
234 + }
235 +
236 + if ($request->has('agent_signature_enabled')) {
237 + $data['agent_signature_enabled'] = $request->get('agent_signature_enabled') === 'yes' ? 'yes' : 'no';
238 + }
239 +
240 + if ($includeEmail) {
241 + $data['email'] = $request->getSafe('email', 'sanitize_email');
242 + }
243 +
244 + return $data;
245 + }
246 +
247 + /**
248 + * Sanitize restrictions data for agent
249 + *
250 + * @param mixed $restrictions
251 + * @return array
252 + */
253 + private function sanitizeRestrictions($restrictions)
254 + {
255 + if (!is_array($restrictions)) {
256 + return [
257 + 'restrictedBusinessBoxes' => [],
258 + 'businessBoxRestrictions' => false,
259 + ];
260 + }
261 +
262 + $restrictedBusinessBoxes = isset($restrictions['restrictedBusinessBoxes']) && is_array($restrictions['restrictedBusinessBoxes'])
263 + ? array_map('absint', $restrictions['restrictedBusinessBoxes'])
264 + : [];
265 +
266 + $businessBoxRestrictions = isset($restrictions['businessBoxRestrictions'])
267 + ? rest_sanitize_boolean($restrictions['businessBoxRestrictions'])
268 + : false;
269 +
270 + return [
271 + 'restrictedBusinessBoxes' => $restrictedBusinessBoxes,
272 + 'businessBoxRestrictions' => $businessBoxRestrictions,
222 273 ];
223 274 }
224 275 }