PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.7
Yatra – Travel Booking & Tour Operator Software v3.0.2.7
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
yatra / app / Core / Handlers / LoginPageHandler.php

LoginPageHandler.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.7, at app/Core/Handlers/LoginPageHandler.php

215 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Core\Handlers;
6
7 /**
8 * Login Page Handler
9 *
10 * Production-optimized handler for login page routing and template loading
11 *
12 * @package Yatra
13 * @version 1.0.0
14 */
15 class LoginPageHandler extends BasePageHandler
16 {
17 /**
18 * Handle the login page request with enhanced security
19 */
20 public function handle(array $params): bool
21 {
22 // Security: Validate request method
23 if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
24 $this->sendErrorResponse(405, __('Method not allowed', 'yatra'));
25 return false;
26 }
27
28 // Security: Rate limiting for login page access
29 if (!$this->checkRateLimit()) {
30 $this->sendErrorResponse(429, __('Too many requests', 'yatra'));
31 return false;
32 }
33
34 // Security: Check if user is already logged in and redirect securely
35 if (is_user_logged_in()) {
36 $current_user = wp_get_current_user();
37 $redirect_url = apply_filters('yatra_login_redirect_url', home_url('/my-account'), $current_user);
38
39 // Use safe redirect to prevent open redirects
40 wp_safe_redirect($redirect_url, 302);
41 exit;
42 }
43
44 // Security: Validate nonce if present (for form submissions)
45 if (isset($_GET['_wpnonce']) && !wp_verify_nonce($_GET['_wpnonce'], 'yatra_login_page')) {
46 $this->sendErrorResponse(403, __('Security check failed', 'yatra'));
47 return false;
48 }
49
50 // Load the login page template with error handling
51 $template_path = YATRA_PLUGIN_PATH . 'templates/login-page.php';
52
53 if (!file_exists($template_path)) {
54 // Log error for debugging
55 if (defined('WP_DEBUG') && WP_DEBUG) {
56 error_log('Yatra Login Page Handler: Template not found at ' . $template_path);
57 }
58
59 // Fallback to shortcode if template is missing
60 return $this->handleFallback();
61 }
62
63 try {
64 // Set up WordPress environment
65 $this->setupWordPressEnvironment();
66
67 // Security headers
68 $this->setSecurityHeaders();
69
70 // Include the template
71 include $template_path;
72 exit;
73
74 } catch (Exception $e) {
75 // Log error for debugging
76 if (defined('WP_DEBUG') && WP_DEBUG) {
77 error_log('Yatra Login Page Handler Error: ' . $e->getMessage());
78 }
79
80 return $this->handleFallback();
81 }
82 }
83
84 /**
85 * Get the route pattern for this handler
86 */
87 public function getPattern(): string
88 {
89 return '^login/?$';
90 }
91
92 /**
93 * Get the route name for this handler
94 */
95 public function getName(): string
96 {
97 return 'login';
98 }
99
100 /**
101 * Check rate limiting for login page access
102 */
103 private function checkRateLimit(): bool
104 {
105 $ip = $this->getClientIp();
106 $transient_key = 'yatra_login_page_limit_' . md5($ip);
107 $attempts = get_transient($transient_key) ?: 0;
108
109 // Allow 30 requests per 5 minutes
110 if ($attempts >= 30) {
111 return false;
112 }
113
114 set_transient($transient_key, $attempts + 1, 5 * MINUTE_IN_SECONDS);
115 return true;
116 }
117
118 /**
119 * Setup WordPress environment for the login page
120 */
121 private function setupWordPressEnvironment(): void
122 {
123 global $wp_query;
124
125 // Prevent 404
126 $wp_query->is_404 = false;
127 $wp_query->is_page = true;
128 $wp_query->is_singular = true;
129
130 // Set proper headers
131 status_header(200);
132
133 // Set page title and metadata
134 $wp_query->set('page_title', __('Login', 'yatra'));
135 $wp_query->set('meta_description', __('Login to your Yatra account', 'yatra'));
136
137 // Set up post data for compatibility
138 $wp_query->set('post', (object) [
139 'ID' => 0,
140 'post_title' => __('Login', 'yatra'),
141 'post_content' => '',
142 'post_type' => 'page',
143 'post_status' => 'publish'
144 ]);
145 }
146
147 /**
148 * Set security headers
149 */
150 private function setSecurityHeaders(): void
151 {
152 if (!headers_sent()) {
153 header('X-Content-Type-Options: nosniff');
154 header('X-Frame-Options: SAMEORIGIN');
155 header('Referrer-Policy: strict-origin-when-cross-origin');
156 header('Content-Security-Policy: "default-src \'self\'; script-src \'self\' \'unsafe-inline\'; style-src \'self\' \'unsafe-inline\'; img-src \'self\' data: https:; font-src \'self\' data:; connect-src \'self\'"');
157 }
158 }
159
160 /**
161 * Handle fallback when template is not available
162 */
163 private function handleFallback(): bool
164 {
165 // Fallback to shortcode rendering
166 add_filter('template_include', function($template) {
167 return get_template_directory() . '/page.php';
168 });
169
170 // Create a virtual page
171 add_filter('the_content', function($content) {
172 return do_shortcode('[yatra_login]');
173 });
174
175 return true;
176 }
177
178 /**
179 * Send error response
180 */
181 private function sendErrorResponse(int $code, string $message): void
182 {
183 if (!headers_sent()) {
184 status_header($code);
185 header('Content-Type: text/html; charset=' . get_bloginfo('charset'));
186 }
187
188 wp_die(
189 esc_html($message),
190 esc_html__('Error', 'yatra'),
191 ['response' => $code]
192 );
193 }
194
195 /**
196 * Get client IP address
197 */
198 private function getClientIp(): string
199 {
200 $ip_keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
201
202 foreach ($ip_keys as $key) {
203 if (!empty($_SERVER[$key])) {
204 $ips = explode(',', $_SERVER[$key]);
205 $ip = trim($ips[0]);
206 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
207 return $ip;
208 }
209 }
210 }
211
212 return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
213 }
214 }
215