PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.3
Yatra – Travel Booking & Tour Operator Software v3.0.3
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.3, at app/Core/Handlers/LoginPageHandler.php

208 lines 5.9 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('/' . \Yatra\Services\SettingsService::getAccountBase()), $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
55
56 // Fallback to shortcode if template is missing
57 return $this->handleFallback();
58 }
59
60 try {
61 // Set up WordPress environment
62 $this->setupWordPressEnvironment();
63
64 // Security headers
65 $this->setSecurityHeaders();
66
67 // Include the template
68 include $template_path;
69 exit;
70
71 } catch (\Exception $e) {
72
73 return $this->handleFallback();
74 }
75 }
76
77 /**
78 * Get the route pattern for this handler
79 */
80 public function getPattern(): string
81 {
82 return '^login/?$';
83 }
84
85 /**
86 * Get the route name for this handler
87 */
88 public function getName(): string
89 {
90 return 'login';
91 }
92
93 /**
94 * Check rate limiting for login page access
95 */
96 private function checkRateLimit(): bool
97 {
98 $ip = $this->getClientIp();
99 $transient_key = 'yatra_login_page_limit_' . md5($ip);
100 $attempts = get_transient($transient_key) ?: 0;
101
102 // Allow 30 requests per 5 minutes
103 if ($attempts >= 30) {
104 return false;
105 }
106
107 set_transient($transient_key, $attempts + 1, 5 * MINUTE_IN_SECONDS);
108 return true;
109 }
110
111 /**
112 * Setup WordPress environment for the login page
113 */
114 private function setupWordPressEnvironment(): void
115 {
116 global $wp_query;
117
118 // Prevent 404
119 $wp_query->is_404 = false;
120 $wp_query->is_page = true;
121 $wp_query->is_singular = true;
122
123 // Set proper headers
124 status_header(200);
125
126 // Set page title and metadata
127 $wp_query->set('page_title', __('Login', 'yatra'));
128 $wp_query->set('meta_description', __('Login to your Yatra account', 'yatra'));
129
130 // Set up post data for compatibility
131 $wp_query->set('post', (object) [
132 'ID' => 0,
133 'post_title' => __('Login', 'yatra'),
134 'post_content' => '',
135 'post_type' => 'page',
136 'post_status' => 'publish'
137 ]);
138 }
139
140 /**
141 * Set security headers
142 */
143 private function setSecurityHeaders(): void
144 {
145 if (!headers_sent()) {
146 header('X-Content-Type-Options: nosniff');
147 header('X-Frame-Options: SAMEORIGIN');
148 header('Referrer-Policy: strict-origin-when-cross-origin');
149 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\'"');
150 }
151 }
152
153 /**
154 * Handle fallback when template is not available
155 */
156 private function handleFallback(): bool
157 {
158 // Fallback to shortcode rendering
159 add_filter('template_include', function($template) {
160 return get_template_directory() . '/page.php';
161 });
162
163 // Create a virtual page
164 add_filter('the_content', function($content) {
165 return do_shortcode('[yatra_login]');
166 });
167
168 return true;
169 }
170
171 /**
172 * Send error response
173 */
174 private function sendErrorResponse(int $code, string $message): void
175 {
176 if (!headers_sent()) {
177 status_header($code);
178 header('Content-Type: text/html; charset=' . get_bloginfo('charset'));
179 }
180
181 wp_die(
182 esc_html($message),
183 esc_html__('Error', 'yatra'),
184 ['response' => $code]
185 );
186 }
187
188 /**
189 * Get client IP address
190 */
191 private function getClientIp(): string
192 {
193 $ip_keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
194
195 foreach ($ip_keys as $key) {
196 if (!empty($_SERVER[$key])) {
197 $ips = explode(',', $_SERVER[$key]);
198 $ip = trim($ips[0]);
199 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
200 return $ip;
201 }
202 }
203 }
204
205 return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
206 }
207 }
208