| | |
| | | public function registerRoutes(): void |
| | | { |
| | | // Send magic link |
| | | register_rest_route($this->namespace, '/magic-link', [ |
| | | register_rest_route($this->namespace, '/magic', [ |
| | | 'methods' => 'POST', |
| | | 'callback' => [$this, 'sendMagicLink'], |
| | | 'permission_callback' => '__return_true', // Public endpoint |
| | | 'args' => [ |
| | | 'email' => [ |
| | | 'required' => true, |
| | | 'type' => 'string', |
| | | 'format' => 'email', |
| | | 'validate_callback' => function($param) { |
| | | return is_email($param); |
| | | } |
| | | ], |
| | | 'type' => [ |
| | | 'required' => false, |
| | | 'type' => 'string', |
| | | 'default' => 'login', |
| | | 'enum' => ['login', 'signup', 'referral', 'reset'] |
| | | ], |
| | | 'context' => [ |
| | | 'required' => false, |
| | | 'type' => 'object', |
| | | 'default' => [] |
| | | ] |
| | | ] |
| | | 'permission_callback' => [$this, 'checkRateLimit'], |
| | | // 'args' => [ |
| | | // 'email' => [ |
| | | // 'required' => true, |
| | | // 'type' => 'string', |
| | | // 'format' => 'email', |
| | | // 'validate_callback' => function($param) { |
| | | // return is_email($param); |
| | | // } |
| | | // ], |
| | | // 'type' => [ |
| | | // 'required' => false, |
| | | // 'type' => 'string', |
| | | // 'default' => 'login', |
| | | // 'enum' => ['login', 'signup', 'referral', 'reset'] |
| | | // ], |
| | | // 'context' => [ |
| | | // 'required' => false, |
| | | // 'type' => 'object', |
| | | // 'default' => [] |
| | | // ] |
| | | // ] |
| | | ]); |
| | | |
| | | // Resend magic link |
| | | register_rest_route($this->namespace, '/magic-link/resend', [ |
| | | register_rest_route($this->namespace, '/magic/resend', [ |
| | | 'methods' => 'POST', |
| | | 'callback' => [$this, 'resendMagicLink'], |
| | | 'permission_callback' => '__return_true', |
| | | 'permission_callback' => [$this, 'checkRateLimit'], |
| | | 'args' => [ |
| | | 'email' => [ |
| | | 'required' => true, |
| | |
| | | ]); |
| | | |
| | | // Check token validity (useful for frontend) |
| | | register_rest_route($this->namespace, '/magic-link/verify', [ |
| | | register_rest_route($this->namespace, '/magic/verify', [ |
| | | 'methods' => 'POST', |
| | | 'callback' => [$this, 'verifyToken'], |
| | | 'permission_callback' => '__return_true', |
| | |
| | | */ |
| | | public function sendMagicLink(WP_REST_Request $request): WP_REST_Response |
| | | { |
| | | $email = sanitize_email($request->get_param('email')); |
| | | $email = sanitize_email($request->get_param('email')??$request->get_param('user_email')??''); |
| | | $type = sanitize_text_field($request->get_param('type')); |
| | | $context = $request->get_param('context') ?? []; |
| | | |
| | |
| | | ], 400); |
| | | } |
| | | |
| | | // Check if email exists |
| | | $exists = email_exists($email); |
| | | if (!$exists) { |
| | | |
| | | return new WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'User account not found' |
| | | ], 400); |
| | | } |
| | | |
| | | // Send the magic link |
| | | $result = $this->magic_link->sendMagicLink($email, $type, $context); |
| | | error_log('Result: '.print_r($result, true)); |
| | |
| | | $token = sanitize_text_field($request->get_param('token')); |
| | | $email = sanitize_email($request->get_param('email')); |
| | | |
| | | $cache_key = 'magic_token_' . $token; |
| | | $token_data = get_transient($cache_key); |
| | | // This returns array|WP_Error - check for error first |
| | | $token_data = $this->magic_link->verifyToken($token, $email); |
| | | |
| | | if (!$token_data) { |
| | | if (is_wp_error($token_data)) { |
| | | return new WP_REST_Response([ |
| | | 'valid' => false, |
| | | 'message' => 'Token expired or invalid' |
| | | 'message' => $token_data->get_error_message() |
| | | ], 400); |
| | | } |
| | | |
| | | if ($token_data['email'] !== $email) { |
| | | // Now check the data |
| | | if (!isset($token_data['email']) || $token_data['email'] !== $email) { |
| | | return new WP_REST_Response([ |
| | | 'valid' => false, |
| | | 'message' => 'Invalid token' |
| | | ], 400); |
| | | } |
| | | |
| | | if (time() > $token_data['expires_at']) { |
| | | return new WP_REST_Response([ |
| | | 'valid' => false, |
| | | 'message' => 'Token expired' |
| | | ], 400); |
| | | } |
| | | |
| | | // Check expiration - but your cache-based system doesn't store expires_at |
| | | // If token wasn't expired, it wouldn't have been returned from cache |
| | | // So just return valid: |
| | | return new WP_REST_Response([ |
| | | 'valid' => true, |
| | | 'type' => $token_data['type'], |
| | | 'expires_in' => $token_data['expires_at'] - time() |
| | | 'type' => $token_data['type'] ?? 'unknown' |
| | | ], 200); |
| | | } |
| | | |