PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
← All changes | app/Controllers/EnquiryController.php +66 -13 3.0.4 → 3.0.16 View file →
@@ -45,9 +45,9 @@
45 45 register_rest_route($namespace, '/' . $base, [
46 46 [
47 47 'methods' => \WP_REST_Server::READABLE,
48 48 'callback' => [$this, 'getEnquiries'],
49 - 'permission_callback' => [$this, 'checkAdminPermission'],
49 + 'permission_callback' => [$this, 'checkCanView'],
50 50 ],
51 51 [
52 52 'methods' => \WP_REST_Server::CREATABLE,
53 53 'callback' => [$this, 'createEnquiry'],
@@ -54,61 +54,93 @@
54 54 'permission_callback' => '__return_true', // Public endpoint
55 55 ],
56 56 ]);
57 57
58 - // Single enquiry operations
58 + // Single enquiry operations — read uses view, write uses respond,
59 + // delete uses the dedicated delete cap (high sensitivity).
59 60 register_rest_route($namespace, '/' . $base . '/(?P<id>[\d]+)', [
60 61 [
61 62 'methods' => \WP_REST_Server::READABLE,
62 63 'callback' => [$this, 'getEnquiry'],
63 - 'permission_callback' => [$this, 'checkAdminPermission'],
64 + 'permission_callback' => [$this, 'checkCanView'],
64 65 ],
65 66 [
66 67 'methods' => \WP_REST_Server::EDITABLE,
67 68 'callback' => [$this, 'updateEnquiry'],
68 - 'permission_callback' => [$this, 'checkAdminPermission'],
69 + 'permission_callback' => [$this, 'checkCanRespond'],
69 70 ],
70 71 [
71 72 'methods' => \WP_REST_Server::DELETABLE,
72 73 'callback' => [$this, 'deleteEnquiry'],
73 - 'permission_callback' => [$this, 'checkAdminPermission'],
74 + 'permission_callback' => [$this, 'checkCanDelete'],
74 75 ],
75 76 ]);
76 77
77 - // Bulk actions
78 + // Bulk actions — operations include status change, mark-read,
79 + // delete, etc. Gate on respond (the broadest mutation cap
80 + // short of delete). Bulk-delete callers should re-check
81 + // delete-cap inside the handler when the action is "delete".
78 82 register_rest_route($namespace, '/' . $base . '/bulk', [
79 83 [
80 84 'methods' => \WP_REST_Server::EDITABLE,
81 85 'callback' => [$this, 'bulkAction'],
82 - 'permission_callback' => [$this, 'checkAdminPermission'],
86 + 'permission_callback' => [$this, 'checkCanRespond'],
83 87 ],
84 88 ]);
85 89
86 - // Stats endpoint
90 + // Stats endpoint — read-only aggregation, view cap is enough.
87 91 register_rest_route($namespace, '/' . $base . '/stats', [
88 92 [
89 93 'methods' => \WP_REST_Server::READABLE,
90 94 'callback' => [$this, 'getStats'],
91 - 'permission_callback' => [$this, 'checkAdminPermission'],
95 + 'permission_callback' => [$this, 'checkCanView'],
92 96 ],
93 97 ]);
94 98
95 - // Respond to enquiry
99 + // Respond to enquiry — explicit respond-cap.
96 100 register_rest_route($namespace, '/' . $base . '/(?P<id>[\d]+)/respond', [
97 101 [
98 102 'methods' => \WP_REST_Server::CREATABLE,
99 103 'callback' => [$this, 'respondToEnquiry'],
100 - 'permission_callback' => [$this, 'checkAdminPermission'],
104 + 'permission_callback' => [$this, 'checkCanRespond'],
101 105 ],
102 106 ]);
103 107 }
104 108
105 109 /**
106 - * Check admin permission
110 + * Granular permission checks — one per operation so role bundles
111 + * (Sales Agent, Front Desk, etc.) can actually use the parts of
112 + * the enquiry surface their role grants. WP administrators pass
113 + * every cap automatically via the Team module's admin-fallback
114 + * filter, so `manage_options` doesn't need an explicit check
115 + * here — it's covered by the cap.
107 116 */
117 + public function checkCanView(): bool
118 + {
119 + return current_user_can('yatra_view_enquiries');
120 + }
121 +
122 + public function checkCanRespond(): bool
123 + {
124 + return current_user_can('yatra_respond_to_enquiries');
125 + }
126 +
127 + public function checkCanDelete(): bool
128 + {
129 + return current_user_can('yatra_delete_enquiries');
130 + }
131 +
132 + /**
133 + * @deprecated Kept for any external code (custom snippet, third-
134 + * party integration) that hooked the old method name. New code
135 + * should use checkCanView/Respond/Delete. Routes the call to
136 + * the view-only cap so behaviour is at-least-as-strict as before
137 + * for non-admin callers, and admin users keep passing via the
138 + * admin-fallback layer.
139 + */
108 140 public function checkAdminPermission(): bool
109 141 {
110 - return current_user_can('manage_options');
142 + return $this->checkCanView();
111 143 }
112 144
113 145 /**
114 146 * GET /enquiries - List all enquiries
@@ -172,8 +204,21 @@
172 204 if (empty($data)) {
173 205 $data = $request->get_params();
174 206 }
175 207
208 + // reCAPTCHA v3 (no-op unless the enquiry form is protected in settings).
209 + $recaptcha = \Yatra\Services\RecaptchaService::verifyForm(
210 + 'enquiry',
211 + (string) ($data['recaptcha_token'] ?? ''),
212 + $_SERVER['REMOTE_ADDR'] ?? null
213 + );
214 + if (empty($recaptcha['success'])) {
215 + return new WP_REST_Response([
216 + 'success' => false,
217 + 'message' => $recaptcha['message'] ?? __('reCAPTCHA verification failed.', 'yatra'),
218 + ], 400);
219 + }
220 +
176 221 $result = $this->enquiryService->createEnquiry($data);
177 222
178 223 if (!$result['success']) {
179 224 return new WP_REST_Response($result, 400);
@@ -241,8 +286,16 @@
241 286 break;
242 287
243 288 case 'mark_pending':
244 289 $result = $this->enquiryService->bulkUpdateStatus($ids, 'pending');
290 + break;
291 +
292 + case 'mark_completed':
293 + $result = $this->enquiryService->bulkUpdateStatus($ids, 'completed');
294 + break;
295 +
296 + case 'mark_closed':
297 + $result = $this->enquiryService->bulkUpdateStatus($ids, 'closed');
245 298 break;
246 299
247 300 case 'mark_spam':
248 301 $result = $this->enquiryService->bulkUpdateStatus($ids, 'spam');