147 lines
5.7 KiB
PHP
147 lines
5.7 KiB
PHP
<?php
|
|
/**
|
|
* Plugin Name: AutoBooking Nav Guard
|
|
* Version: 1.1.0
|
|
* Description: Protege páginas por token de navegación. Redirige al login/home si no hay token válido.
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
/* ── Páginas protegidas: destino => URL ────────────────────────────── */
|
|
define('AB_NAV_PAGES', [
|
|
'driver' => '/driver-dashboard-2/',
|
|
'passenger' => '/customer-dashboard/',
|
|
'corporate' => '/corporate-dashboard/',
|
|
]);
|
|
|
|
/* ── Session ───────────────────────────────────────────────────────── */
|
|
add_action('init', function () {
|
|
if (!session_id() && !headers_sent()) session_start();
|
|
}, 1);
|
|
|
|
/* ── Roles permitidos por destino ───────────────────────────────────── */
|
|
function ab_nav_allowed_roles() {
|
|
return [
|
|
'driver' => ['driver', 'driver_pending'],
|
|
'passenger' => ['subscriber', 'customer'],
|
|
'corporate' => ['corporate_admin'],
|
|
];
|
|
}
|
|
|
|
/* ── Protección via template_redirect (antes de cualquier output) ──── */
|
|
add_action('template_redirect', function () {
|
|
global $post;
|
|
if (!$post) return;
|
|
|
|
$dest = get_post_meta($post->ID, '_ab_nav_page', true);
|
|
if (!$dest) return;
|
|
|
|
if (!is_user_logged_in()) {
|
|
wp_redirect(wp_login_url(get_permalink()));
|
|
exit;
|
|
}
|
|
|
|
$uid = get_current_user_id();
|
|
$user = wp_get_current_user();
|
|
$roles = (array) $user->roles;
|
|
|
|
// Admins y manage_autobooking: acceso siempre sin token
|
|
if (in_array('administrator', $roles) || user_can($uid, 'manage_autobooking')) {
|
|
return;
|
|
}
|
|
|
|
if (!session_id()) session_start();
|
|
$token = $_SESSION['ab_nav'][$dest] ?? null;
|
|
|
|
// Token válido → pasar
|
|
if ($token && $token['user'] === $uid && $token['exp'] >= time()) {
|
|
return;
|
|
}
|
|
|
|
// Sin token pero tiene el rol correcto → auto-token y pasar
|
|
$allowed = ab_nav_allowed_roles()[$dest] ?? [];
|
|
if (array_intersect($roles, $allowed)) {
|
|
$_SESSION['ab_nav'][$dest] = ['user' => $uid, 'exp' => time() + 300];
|
|
return;
|
|
}
|
|
|
|
// Rol incorrecto para esta página → home
|
|
wp_redirect(home_url('/'));
|
|
exit;
|
|
});
|
|
|
|
/* ── Auto-token en login → acceso directo al dashboard ─────────────── */
|
|
add_action('wp_login', function ($login, $user) {
|
|
if (!session_id()) session_start();
|
|
$roles = (array) $user->roles;
|
|
$exp = time() + 300;
|
|
|
|
$role_map = [
|
|
'driver' => 'driver',
|
|
'driver_pending' => 'driver',
|
|
'subscriber' => 'passenger',
|
|
'customer' => 'passenger',
|
|
'corporate_admin' => 'corporate',
|
|
];
|
|
foreach ($role_map as $role => $dest) {
|
|
if (in_array($role, $roles, true)) {
|
|
$_SESSION['ab_nav'][$dest] = ['user' => $user->ID, 'exp' => $exp];
|
|
}
|
|
}
|
|
if (user_can($user->ID, 'manage_autobooking') || in_array('administrator', $roles, true)) {
|
|
foreach (array_keys(AB_NAV_PAGES) as $dest) {
|
|
$_SESSION['ab_nav'][$dest] = ['user' => $user->ID, 'exp' => $exp];
|
|
}
|
|
}
|
|
}, 10, 2);
|
|
|
|
/* ── Redirect post-login al dashboard según rol ────────────────────── */
|
|
add_filter('login_redirect', function ($redirect, $request, $user) {
|
|
if (is_wp_error($user)) return $redirect;
|
|
$roles = (array) $user->roles;
|
|
|
|
if (in_array('driver', $roles) || in_array('driver_pending', $roles))
|
|
return home_url(AB_NAV_PAGES['driver']);
|
|
if (in_array('corporate_admin', $roles))
|
|
return home_url(AB_NAV_PAGES['corporate']);
|
|
if (in_array('subscriber', $roles) || in_array('customer', $roles))
|
|
return home_url(AB_NAV_PAGES['passenger']);
|
|
|
|
return $redirect;
|
|
}, 10, 3);
|
|
|
|
/* ── REST: generar token desde JS ───────────────────────────────────── */
|
|
add_action('rest_api_init', function () {
|
|
register_rest_route('ab/v1', '/nav-token', [
|
|
'methods' => 'POST',
|
|
'callback' => function (WP_REST_Request $req) {
|
|
$dest = sanitize_text_field($req->get_param('destination'));
|
|
if (!$dest) return new WP_Error('missing', 'destination required', ['status' => 400]);
|
|
if (!session_id()) session_start();
|
|
$_SESSION['ab_nav'][$dest] = ['user' => get_current_user_id(), 'exp' => time() + 300];
|
|
return rest_ensure_response(['ok' => true, 'destination' => $dest]);
|
|
},
|
|
'permission_callback' => fn() => is_user_logged_in(),
|
|
]);
|
|
});
|
|
|
|
/* ── JS helper global ───────────────────────────────────────────────── */
|
|
add_action('wp_footer', function () {
|
|
if (!is_user_logged_in()) return;
|
|
echo '<script>window.ab_nav_go=function(dest,url){'
|
|
. 'fetch(' . json_encode(rest_url('ab/v1/nav-token')) . ','
|
|
. '{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":' . json_encode(wp_create_nonce('wp_rest')) . '},'
|
|
. 'body:JSON.stringify({destination:dest})})'
|
|
. '.then(r=>r.json()).then(d=>{if(d.ok)window.location.href=url||"/"});'
|
|
. '};</script>';
|
|
});
|
|
|
|
/* ── Limpieza de tokens expirados ───────────────────────────────────── */
|
|
add_action('init', function () {
|
|
if (!session_id() || empty($_SESSION['ab_nav'])) return;
|
|
$now = time();
|
|
foreach ($_SESSION['ab_nav'] as $k => $d) {
|
|
if ($d['exp'] < $now) unset($_SESSION['ab_nav'][$k]);
|
|
}
|
|
}, 5);
|