| 1 |
<?php |
| 2 |
/** |
| 3 |
* Abilities: Login, logout, sign up, and password reset for WDesignKit cloud. |
| 4 |
*/ |
| 5 |
|
| 6 |
declare(strict_types=1); |
| 7 |
|
| 8 |
if (!defined('ABSPATH')) { |
| 9 |
exit(); |
| 10 |
} |
| 11 |
|
| 12 |
wp_register_ability('wdesignkit/login', [ |
| 13 |
'label' => __('Login to WDesignKit Cloud', 'wdesignkit'), |
| 14 |
'description' => __( |
| 15 |
'Authenticates the user against the WDesignKit cloud using email and password, and stores the session token locally. Use remember_me: true for a 90-day session; false (default) for a 1-day session.', |
| 16 |
'wdesignkit', |
| 17 |
), |
| 18 |
'category' => 'wdesignkit', |
| 19 |
'input_schema' => [ |
| 20 |
'type' => 'object', |
| 21 |
'properties' => [ |
| 22 |
'email' => [ |
| 23 |
'type' => 'string', |
| 24 |
'description' => 'WDesignKit cloud account email address.', |
| 25 |
], |
| 26 |
'password' => [ |
| 27 |
'type' => 'string', |
| 28 |
'description' => 'WDesignKit cloud account password.', |
| 29 |
], |
| 30 |
'remember_me' => [ |
| 31 |
'type' => 'boolean', |
| 32 |
'description' => 'true = 90-day session (Remember Me). false (default) = 1-day session.', |
| 33 |
], |
| 34 |
], |
| 35 |
'required' => ['email', 'password'], |
| 36 |
'additionalProperties' => false, |
| 37 |
], |
| 38 |
'output_schema' => [ |
| 39 |
'type' => 'object', |
| 40 |
'properties' => [ |
| 41 |
'success' => ['type' => 'boolean'], |
| 42 |
'message' => ['type' => 'string'], |
| 43 |
'email' => ['type' => ['string', 'null']], |
| 44 |
], |
| 45 |
], |
| 46 |
'execute_callback' => 'wdesignkit_mcp_login', |
| 47 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 48 |
'meta' => [ |
| 49 |
'public' => true, |
| 50 |
'show_in_rest' => true, |
| 51 |
'mcp' => ['public' => true], |
| 52 |
'annotations' => [ |
| 53 |
'instructions' => implode("\n", [ |
| 54 |
'Logs in with email and password and stores the session locally.', |
| 55 |
'remember_me: true stores for 90 days; false (default) stores for 1 day.', |
| 56 |
'After logging in, use wdesignkit/get-login-status to confirm the session.', |
| 57 |
'All cloud operations (workspace, marketplace, upload) require a valid session.', |
| 58 |
]), |
| 59 |
'readonly' => false, |
| 60 |
'destructive' => false, |
| 61 |
'idempotent' => false, |
| 62 |
], |
| 63 |
], |
| 64 |
]); |
| 65 |
|
| 66 |
wp_register_ability('wdesignkit/login-api-key', [ |
| 67 |
'label' => __('Login to WDesignKit Cloud with API Key', 'wdesignkit'), |
| 68 |
'description' => __( |
| 69 |
'Authenticates the user against the WDesignKit cloud using a personal API token (instead of email and password), and stores the session locally. Useful for automation and CI workflows.', |
| 70 |
'wdesignkit', |
| 71 |
), |
| 72 |
'category' => 'wdesignkit', |
| 73 |
'input_schema' => [ |
| 74 |
'type' => 'object', |
| 75 |
'properties' => [ |
| 76 |
'api_key' => [ |
| 77 |
'type' => 'string', |
| 78 |
'description' => 'WDesignKit personal API token / key.', |
| 79 |
], |
| 80 |
], |
| 81 |
'required' => ['api_key'], |
| 82 |
'additionalProperties' => false, |
| 83 |
], |
| 84 |
'output_schema' => [ |
| 85 |
'type' => 'object', |
| 86 |
'properties' => [ |
| 87 |
'success' => ['type' => 'boolean'], |
| 88 |
'message' => ['type' => 'string'], |
| 89 |
'email' => ['type' => ['string', 'null']], |
| 90 |
], |
| 91 |
], |
| 92 |
'execute_callback' => 'wdesignkit_mcp_login_api_key', |
| 93 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 94 |
'meta' => [ |
| 95 |
'public' => true, |
| 96 |
'show_in_rest' => true, |
| 97 |
'mcp' => ['public' => true], |
| 98 |
'annotations' => [ |
| 99 |
'instructions' => implode("\n", [ |
| 100 |
'Logs in using a WDesignKit API token rather than email/password.', |
| 101 |
'Obtain the API key from wdesignkit.com account settings.', |
| 102 |
'Session is stored for 90 days on success.', |
| 103 |
'Use wdesignkit/get-login-status to confirm the session afterwards.', |
| 104 |
]), |
| 105 |
'readonly' => false, |
| 106 |
'destructive' => false, |
| 107 |
'idempotent' => false, |
| 108 |
], |
| 109 |
], |
| 110 |
]); |
| 111 |
|
| 112 |
wp_register_ability('wdesignkit/social-login', [ |
| 113 |
'label' => __('Login / Sign Up to WDesignKit Cloud via Google or Facebook', 'wdesignkit'), |
| 114 |
'description' => __( |
| 115 |
'Completes a WDesignKit Google or Facebook OAuth login/signup using the state code produced after the user authorises in the OAuth browser popup. Covers Login with Google, Login with Facebook, Sign Up with Google, and Sign Up with Facebook — all share the same backend endpoint.', |
| 116 |
'wdesignkit', |
| 117 |
), |
| 118 |
'category' => 'wdesignkit', |
| 119 |
'input_schema' => [ |
| 120 |
'type' => 'object', |
| 121 |
'properties' => [ |
| 122 |
'state' => [ |
| 123 |
'type' => 'string', |
| 124 |
'description' => 'The unique state ID generated before opening the OAuth popup. The server exchanges this for a token after the user authorises.', |
| 125 |
], |
| 126 |
], |
| 127 |
'required' => ['state'], |
| 128 |
'additionalProperties' => false, |
| 129 |
], |
| 130 |
'output_schema' => [ |
| 131 |
'type' => 'object', |
| 132 |
'properties' => [ |
| 133 |
'success' => ['type' => 'boolean'], |
| 134 |
'message' => ['type' => 'string'], |
| 135 |
'email' => ['type' => ['string', 'null']], |
| 136 |
'response' => ['type' => ['object', 'array']], |
| 137 |
], |
| 138 |
], |
| 139 |
'execute_callback' => 'wdesignkit_mcp_social_login', |
| 140 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 141 |
'meta' => [ |
| 142 |
'public' => true, |
| 143 |
'show_in_rest' => true, |
| 144 |
'mcp' => ['public' => true], |
| 145 |
'annotations' => [ |
| 146 |
'instructions' => implode("\n", [ |
| 147 |
'Step 2 of the Google/Facebook OAuth login or signup flow.', |
| 148 |
'First call wdesignkit/get-social-login-url(provider) to get the auth_url and state (Step 1).', |
| 149 |
'Open auth_url in a browser popup for the user to authorise, then call this ability with the state.', |
| 150 |
'Covers: Login with Google, Login with Facebook, Sign Up with Google, Sign Up with Facebook.', |
| 151 |
'On success the session is stored for 90 days.', |
| 152 |
]), |
| 153 |
'readonly' => false, |
| 154 |
'destructive' => false, |
| 155 |
'idempotent' => false, |
| 156 |
], |
| 157 |
], |
| 158 |
]); |
| 159 |
|
| 160 |
wp_register_ability('wdesignkit/signup', [ |
| 161 |
'label' => __('Sign Up for WDesignKit Cloud', 'wdesignkit'), |
| 162 |
'description' => __( |
| 163 |
'Creates a new WDesignKit cloud account with a full name, email address, and password, then stores the session token locally so cloud features are immediately available.', |
| 164 |
'wdesignkit', |
| 165 |
), |
| 166 |
'category' => 'wdesignkit', |
| 167 |
'input_schema' => [ |
| 168 |
'type' => 'object', |
| 169 |
'properties' => [ |
| 170 |
'fullname' => [ |
| 171 |
'type' => 'string', |
| 172 |
'description' => 'Full name for the new account.', |
| 173 |
], |
| 174 |
'email' => [ |
| 175 |
'type' => 'string', |
| 176 |
'description' => 'Email address for the new account.', |
| 177 |
], |
| 178 |
'password' => [ |
| 179 |
'type' => 'string', |
| 180 |
'description' => 'Password for the new account.', |
| 181 |
], |
| 182 |
], |
| 183 |
'required' => ['fullname', 'email', 'password'], |
| 184 |
'additionalProperties' => false, |
| 185 |
], |
| 186 |
'output_schema' => [ |
| 187 |
'type' => 'object', |
| 188 |
'properties' => [ |
| 189 |
'success' => ['type' => 'boolean'], |
| 190 |
'message' => ['type' => 'string'], |
| 191 |
'email' => ['type' => ['string', 'null']], |
| 192 |
], |
| 193 |
], |
| 194 |
'execute_callback' => 'wdesignkit_mcp_signup', |
| 195 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 196 |
'meta' => [ |
| 197 |
'public' => true, |
| 198 |
'show_in_rest' => true, |
| 199 |
'mcp' => ['public' => true], |
| 200 |
'annotations' => [ |
| 201 |
'instructions' => implode("\n", [ |
| 202 |
'Creates a new WDesignKit cloud account and stores the session.', |
| 203 |
'If successful, the user is immediately logged in (1-day session stored).', |
| 204 |
'Use wdesignkit/get-login-status to confirm the session afterwards.', |
| 205 |
]), |
| 206 |
'readonly' => false, |
| 207 |
'destructive' => false, |
| 208 |
'idempotent' => false, |
| 209 |
], |
| 210 |
], |
| 211 |
]); |
| 212 |
|
| 213 |
wp_register_ability('wdesignkit/forgot-password', [ |
| 214 |
'label' => __('WDesignKit Cloud Forgot Password', 'wdesignkit'), |
| 215 |
'description' => __( |
| 216 |
'Sends a password reset email to the specified WDesignKit cloud account address. This is a read-only operation — no local session is modified.', |
| 217 |
'wdesignkit', |
| 218 |
), |
| 219 |
'category' => 'wdesignkit', |
| 220 |
'input_schema' => [ |
| 221 |
'type' => 'object', |
| 222 |
'properties' => [ |
| 223 |
'email' => [ |
| 224 |
'type' => 'string', |
| 225 |
'description' => 'Email address of the WDesignKit cloud account to reset.', |
| 226 |
], |
| 227 |
], |
| 228 |
'required' => ['email'], |
| 229 |
'additionalProperties' => false, |
| 230 |
], |
| 231 |
'output_schema' => [ |
| 232 |
'type' => 'object', |
| 233 |
'properties' => [ |
| 234 |
'success' => ['type' => 'boolean'], |
| 235 |
'message' => ['type' => 'string'], |
| 236 |
], |
| 237 |
], |
| 238 |
'execute_callback' => 'wdesignkit_mcp_forgot_password', |
| 239 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 240 |
'meta' => [ |
| 241 |
'public' => true, |
| 242 |
'show_in_rest' => true, |
| 243 |
'mcp' => ['public' => true], |
| 244 |
'annotations' => [ |
| 245 |
'instructions' => implode("\n", [ |
| 246 |
'Sends a password reset email to the given address.', |
| 247 |
'No local session is created or modified.', |
| 248 |
'After resetting, use wdesignkit/login to start a new session.', |
| 249 |
]), |
| 250 |
'readonly' => true, |
| 251 |
'destructive' => false, |
| 252 |
'idempotent' => true, |
| 253 |
], |
| 254 |
], |
| 255 |
]); |
| 256 |
|
| 257 |
wp_register_ability('wdesignkit/logout', [ |
| 258 |
'label' => __('Logout from WDesignKit Cloud', 'wdesignkit'), |
| 259 |
'description' => __( |
| 260 |
'Logs the currently authenticated user out of WDesignKit cloud. Deletes the local session transient, calls the cloud logout endpoint to invalidate the token, and clears the cached licence data.', |
| 261 |
'wdesignkit', |
| 262 |
), |
| 263 |
'category' => 'wdesignkit', |
| 264 |
'input_schema' => [ |
| 265 |
'type' => 'object', |
| 266 |
], |
| 267 |
'output_schema' => [ |
| 268 |
'type' => 'object', |
| 269 |
'properties' => [ |
| 270 |
'success' => ['type' => 'boolean'], |
| 271 |
'message' => ['type' => 'string'], |
| 272 |
], |
| 273 |
], |
| 274 |
'execute_callback' => 'wdesignkit_mcp_logout', |
| 275 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 276 |
'meta' => [ |
| 277 |
'public' => true, |
| 278 |
'show_in_rest' => true, |
| 279 |
'mcp' => ['public' => true], |
| 280 |
'annotations' => [ |
| 281 |
'instructions' => implode("\n", [ |
| 282 |
'Logs out the current WDesignKit cloud session.', |
| 283 |
'Deletes the local auth transient and calls the cloud logout endpoint.', |
| 284 |
'Also clears cached licence data (wdkit_licence_data option).', |
| 285 |
'Use wdesignkit/get-login-status to confirm logout.', |
| 286 |
]), |
| 287 |
'readonly' => false, |
| 288 |
'destructive' => false, |
| 289 |
'idempotent' => true, |
| 290 |
], |
| 291 |
], |
| 292 |
]); |
| 293 |
|
| 294 |
wp_register_ability('wdesignkit/get-social-login-url', [ |
| 295 |
'label' => __('Get WDesignKit Social Login URL', 'wdesignkit'), |
| 296 |
'description' => __( |
| 297 |
'Generates a Google or Facebook OAuth authorisation URL and a unique state token. Step 1 of social login: open the returned auth_url in a browser popup for the user to authorise, then pass the state to wdesignkit/social-login (Step 2) once the popup closes.', |
| 298 |
'wdesignkit', |
| 299 |
), |
| 300 |
'category' => 'wdesignkit', |
| 301 |
'input_schema' => [ |
| 302 |
'type' => 'object', |
| 303 |
'properties' => [ |
| 304 |
'provider' => [ |
| 305 |
'type' => 'string', |
| 306 |
'description' => 'OAuth provider: "google" or "facebook".', |
| 307 |
'enum' => ['google', 'facebook'], |
| 308 |
], |
| 309 |
], |
| 310 |
'required' => ['provider'], |
| 311 |
'additionalProperties' => false, |
| 312 |
], |
| 313 |
'output_schema' => [ |
| 314 |
'type' => 'object', |
| 315 |
'properties' => [ |
| 316 |
'success' => ['type' => 'boolean'], |
| 317 |
'message' => ['type' => 'string'], |
| 318 |
'provider' => ['type' => 'string'], |
| 319 |
'auth_url' => ['type' => 'string'], |
| 320 |
'state' => ['type' => 'string'], |
| 321 |
'expires_in' => ['type' => 'integer'], |
| 322 |
], |
| 323 |
], |
| 324 |
'execute_callback' => 'wdesignkit_mcp_get_social_login_url', |
| 325 |
'permission_callback' => 'wdesignkit_mcp_permission_callback', |
| 326 |
'meta' => [ |
| 327 |
'public' => true, |
| 328 |
'show_in_rest' => true, |
| 329 |
'mcp' => ['public' => true], |
| 330 |
'annotations' => [ |
| 331 |
'instructions' => implode("\n", [ |
| 332 |
'Step 1 of the 2-step Google/Facebook OAuth login or signup flow.', |
| 333 |
'Returns auth_url and state. Open auth_url in a browser popup for the user to authorise.', |
| 334 |
'After the user authorises and the popup closes, pass state to wdesignkit/social-login.', |
| 335 |
'The state token is valid for approximately 10 minutes (expires_in seconds).', |
| 336 |
'Covers: Login with Google, Login with Facebook, Sign Up with Google, Sign Up with Facebook.', |
| 337 |
]), |
| 338 |
'readonly' => true, |
| 339 |
'destructive' => false, |
| 340 |
'idempotent' => false, |
| 341 |
], |
| 342 |
], |
| 343 |
]); |
| 344 |
|
| 345 |
// === Callback implementations === |
| 346 |
|
| 347 |
function wdesignkit_mcp_login(array $input): array { |
| 348 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 349 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 350 |
} |
| 351 |
|
| 352 |
$email = strtolower(sanitize_email((string) ($input['email'] ?? ''))); |
| 353 |
$password = sanitize_text_field((string) ($input['password'] ?? '')); |
| 354 |
$remember_me = (bool) ($input['remember_me'] ?? false); |
| 355 |
|
| 356 |
if ($email === '' || $password === '') { |
| 357 |
return ['success' => false, 'message' => 'email and password are required.']; |
| 358 |
} |
| 359 |
|
| 360 |
$user_key = wdesignkit_cloud_session_key($email); |
| 361 |
|
| 362 |
// Clear any existing session for this user |
| 363 |
delete_transient('wdkit_auth_' . $user_key); |
| 364 |
|
| 365 |
$response = wdesignkit_mcp_template_cloud_call('login', [ |
| 366 |
'user_email' => $email, |
| 367 |
'password' => $password, |
| 368 |
'site_url' => home_url(), |
| 369 |
], 'json'); |
| 370 |
|
| 371 |
if (empty($response['success'])) { |
| 372 |
return [ |
| 373 |
'success' => false, |
| 374 |
'message' => $response['message'] ?? $response['massage'] ?? 'Login failed. Check email and password.', |
| 375 |
'email' => null, |
| 376 |
]; |
| 377 |
} |
| 378 |
|
| 379 |
$token = sanitize_text_field((string) ($response['token'] ?? '')); |
| 380 |
|
| 381 |
if ($token === '') { |
| 382 |
return ['success' => false, 'message' => 'Login succeeded but no token returned.', 'email' => null]; |
| 383 |
} |
| 384 |
|
| 385 |
// Resolve cloud user_id — needed for download-widget u_id auto-resolution. |
| 386 |
// The login response may expose it under different keys depending on the endpoint. |
| 387 |
$user_data_login = $response['user'] ?? []; |
| 388 |
$cloud_user_id = (string) ($user_data_login['id'] ?? $user_data_login['user_id'] ?? $response['user_id'] ?? $response['id'] ?? ''); |
| 389 |
|
| 390 |
// Store session — 90 days for "remember me", 1 day for session-only |
| 391 |
$expiry = $remember_me ? 7776000 : 86400; |
| 392 |
set_transient('wdkit_auth_' . $user_key, [ |
| 393 |
'user_email' => $email, |
| 394 |
'token' => $token, |
| 395 |
'user_id' => $cloud_user_id, |
| 396 |
], $expiry); |
| 397 |
|
| 398 |
// Point every later cloud call at THIS account. The transient is keyed off the |
| 399 |
// cloud email, which rarely matches the WP user's email, so without the pointer |
| 400 |
// the session can only be found by scanning wp_options. |
| 401 |
wdesignkit_mcp_remember_session($user_key); |
| 402 |
|
| 403 |
return [ |
| 404 |
'success' => true, |
| 405 |
'message' => $response['message'] ?? 'Logged in successfully.', |
| 406 |
'email' => $email, |
| 407 |
]; |
| 408 |
} |
| 409 |
|
| 410 |
function wdesignkit_mcp_login_api_key(array $input): array { |
| 411 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 412 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 413 |
} |
| 414 |
|
| 415 |
$api_key = sanitize_text_field((string) ($input['api_key'] ?? '')); |
| 416 |
|
| 417 |
if ($api_key === '') { |
| 418 |
return ['success' => false, 'message' => 'api_key is required.']; |
| 419 |
} |
| 420 |
|
| 421 |
$response = wdesignkit_mcp_template_cloud_call('login/api', [ |
| 422 |
'token' => $api_key, |
| 423 |
'site_url' => home_url(), |
| 424 |
], 'form'); |
| 425 |
|
| 426 |
if (empty($response['success'])) { |
| 427 |
$message = $response['message'] ?? $response['massage'] ?? 'API key login failed.'; |
| 428 |
// Normalize raw HTTP-status messages ("WDesignKit cloud returned status 4xx") |
| 429 |
// that leak from the shared cloud-call helper on authentication failures. |
| 430 |
if (preg_match('/returned status\s+4\d\d/i', $message)) { |
| 431 |
$message = 'Invalid API key. Please check your WDesignKit API token.'; |
| 432 |
} |
| 433 |
return ['success' => false, 'message' => $message, 'email' => null]; |
| 434 |
} |
| 435 |
|
| 436 |
// Response data: user->user_email |
| 437 |
$user_data = $response['user'] ?? []; |
| 438 |
$user_email = strtolower(sanitize_email((string) ($user_data['user_email'] ?? ''))); |
| 439 |
$user_key = $user_email !== '' ? wdesignkit_cloud_session_key($user_email) : ''; |
| 440 |
|
| 441 |
if ($user_key !== '') { |
| 442 |
// $user_data already extracted above: $response['user'] ?? [] |
| 443 |
$cloud_user_id_api = (string) ($user_data['id'] ?? $user_data['user_id'] ?? $response['user_id'] ?? $response['id'] ?? ''); |
| 444 |
set_transient('wdkit_auth_' . $user_key, [ |
| 445 |
'user_email' => $user_email, |
| 446 |
'token' => $api_key, |
| 447 |
'user_id' => $cloud_user_id_api, |
| 448 |
], 7776000); // 90 days |
| 449 |
|
| 450 |
wdesignkit_mcp_remember_session($user_key); |
| 451 |
} |
| 452 |
|
| 453 |
return [ |
| 454 |
'success' => true, |
| 455 |
'message' => 'Logged in with API key successfully.', |
| 456 |
'email' => $user_email ?: null, |
| 457 |
]; |
| 458 |
} |
| 459 |
|
| 460 |
function wdesignkit_mcp_social_login(array $input): array { |
| 461 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 462 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 463 |
} |
| 464 |
|
| 465 |
$state = sanitize_text_field((string) ($input['state'] ?? '')); |
| 466 |
|
| 467 |
if ($state === '') { |
| 468 |
return ['success' => false, 'message' => 'state is required.']; |
| 469 |
} |
| 470 |
|
| 471 |
$response = wdesignkit_mcp_template_cloud_call('login/ip', [ |
| 472 |
'state' => $state, |
| 473 |
'site_url' => home_url(), |
| 474 |
], 'form'); |
| 475 |
|
| 476 |
if (empty($response['success'])) { |
| 477 |
return [ |
| 478 |
'success' => false, |
| 479 |
'message' => $response['message'] ?? $response['massage'] ?? 'Social login failed. Ensure OAuth was completed in the browser popup first.', |
| 480 |
'email' => null, |
| 481 |
'response' => $response, |
| 482 |
]; |
| 483 |
} |
| 484 |
|
| 485 |
// Response contains user->user_email and token at top level |
| 486 |
$user_data = $response['user'] ?? []; |
| 487 |
$user_email = strtolower(sanitize_email((string) ($user_data['user_email'] ?? ''))); |
| 488 |
$token = sanitize_text_field((string) ($response['token'] ?? '')); |
| 489 |
$user_key = $user_email !== '' ? wdesignkit_cloud_session_key($user_email) : ''; |
| 490 |
|
| 491 |
if ($user_key !== '' && $token !== '') { |
| 492 |
$cloud_user_id_social = (string) ($user_data['id'] ?? $user_data['user_id'] ?? $response['user_id'] ?? $response['id'] ?? ''); |
| 493 |
set_transient('wdkit_auth_' . $user_key, [ |
| 494 |
'user_email' => $user_email, |
| 495 |
'token' => $token, |
| 496 |
'user_id' => $cloud_user_id_social, |
| 497 |
], 7776000); // 90 days |
| 498 |
|
| 499 |
wdesignkit_mcp_remember_session($user_key); |
| 500 |
} |
| 501 |
|
| 502 |
return [ |
| 503 |
'success' => true, |
| 504 |
'message' => $response['message'] ?? 'Logged in via social account successfully.', |
| 505 |
'email' => $user_email ?: null, |
| 506 |
'response' => $response, |
| 507 |
]; |
| 508 |
} |
| 509 |
|
| 510 |
function wdesignkit_mcp_signup(array $input): array { |
| 511 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 512 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 513 |
} |
| 514 |
|
| 515 |
$fullname = sanitize_text_field((string) ($input['fullname'] ?? '')); |
| 516 |
$raw_email = trim((string) ($input['email'] ?? '')); |
| 517 |
$password = sanitize_text_field((string) ($input['password'] ?? '')); |
| 518 |
|
| 519 |
if ($fullname === '' || $raw_email === '' || $password === '') { |
| 520 |
return ['success' => false, 'message' => 'fullname, email, and password are required.', 'email' => null]; |
| 521 |
} |
| 522 |
|
| 523 |
// Validate email format before sanitizing — sanitize_email() returns '' for |
| 524 |
// malformed addresses, which would incorrectly trigger the "required" error above. |
| 525 |
if (!filter_var($raw_email, FILTER_VALIDATE_EMAIL)) { |
| 526 |
return ['success' => false, 'message' => 'Invalid email address.', 'email' => null]; |
| 527 |
} |
| 528 |
|
| 529 |
$email = strtolower(sanitize_email($raw_email)); |
| 530 |
$user_key = wdesignkit_cloud_session_key($email); |
| 531 |
|
| 532 |
// Clear any existing session before signup |
| 533 |
delete_transient('wdkit_auth_' . $user_key); |
| 534 |
|
| 535 |
$response = wdesignkit_mcp_template_cloud_call('signup', [ |
| 536 |
'fullname' => $fullname, |
| 537 |
'password' => $password, |
| 538 |
'user_email' => $email, |
| 539 |
], 'json'); |
| 540 |
|
| 541 |
if (empty($response['success'])) { |
| 542 |
return [ |
| 543 |
'success' => false, |
| 544 |
'message' => $response['message'] ?? $response['massage'] ?? 'Sign up failed.', |
| 545 |
'email' => null, |
| 546 |
]; |
| 547 |
} |
| 548 |
|
| 549 |
$token = sanitize_text_field((string) ($response['token'] ?? '')); |
| 550 |
|
| 551 |
if ($token !== '') { |
| 552 |
$signup_user_data = $response['user'] ?? []; |
| 553 |
$cloud_user_id_sig = (string) ($signup_user_data['id'] ?? $signup_user_data['user_id'] ?? $response['user_id'] ?? $response['id'] ?? ''); |
| 554 |
set_transient('wdkit_auth_' . $user_key, [ |
| 555 |
'user_email' => $email, |
| 556 |
'token' => $token, |
| 557 |
'user_id' => $cloud_user_id_sig, |
| 558 |
], 86400); // 1-day session after signup |
| 559 |
|
| 560 |
wdesignkit_mcp_remember_session($user_key); |
| 561 |
} |
| 562 |
|
| 563 |
return [ |
| 564 |
'success' => true, |
| 565 |
'message' => $response['message'] ?? 'Account created and logged in successfully.', |
| 566 |
'email' => $email, |
| 567 |
]; |
| 568 |
} |
| 569 |
|
| 570 |
function wdesignkit_mcp_forgot_password(array $input): array { |
| 571 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 572 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 573 |
} |
| 574 |
|
| 575 |
$email = strtolower(sanitize_email((string) ($input['email'] ?? ''))); |
| 576 |
|
| 577 |
if ($email === '') { |
| 578 |
return ['success' => false, 'message' => 'email is required.']; |
| 579 |
} |
| 580 |
|
| 581 |
$response = wdesignkit_mcp_template_cloud_call('password/forgot', [ |
| 582 |
'email' => $email, |
| 583 |
'site_url' => home_url(), |
| 584 |
], 'form'); |
| 585 |
|
| 586 |
$success = !empty($response['success']); |
| 587 |
$message = $response['message'] ?? $response['massage'] ?? ($success ? 'Password reset email sent.' : 'Failed to send reset email.'); |
| 588 |
|
| 589 |
return [ |
| 590 |
'success' => $success, |
| 591 |
'message' => $message, |
| 592 |
]; |
| 593 |
} |
| 594 |
|
| 595 |
function wdesignkit_mcp_get_social_login_url(array $input): array { |
| 596 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 597 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 598 |
} |
| 599 |
|
| 600 |
$provider = sanitize_text_field((string) ($input['provider'] ?? '')); |
| 601 |
|
| 602 |
if (!in_array($provider, ['google', 'facebook'], true)) { |
| 603 |
return ['success' => false, 'message' => 'provider must be "google" or "facebook".']; |
| 604 |
} |
| 605 |
|
| 606 |
// Generate a state token matching the JS keyUniqueID() format: |
| 607 |
// 6 base-36 alphanumeric chars + 2-digit year suffix (e.g. "ab3f2x26"). |
| 608 |
$year = substr(date('Y'), -2); |
| 609 |
$state = substr(base_convert(bin2hex(random_bytes(5)), 16, 36), 0, 6) . $year; |
| 610 |
|
| 611 |
$api_base = rtrim(WDKIT_SERVER_API_URL, '/'); |
| 612 |
$expires_in = 600; // OAuth state tokens are valid for ~10 minutes |
| 613 |
|
| 614 |
if ($provider === 'google') { |
| 615 |
$auth_url = add_query_arg([ |
| 616 |
'client_id' => '428406150181-7rui8lmg2m9nkqqahreida3j02apfnim.apps.googleusercontent.com', |
| 617 |
'redirect_uri' => $api_base . '/api/auth/google/callback-plugin', |
| 618 |
'response_type' => 'code', |
| 619 |
'scope' => 'email profile', |
| 620 |
'state' => $state, |
| 621 |
], 'https://accounts.google.com/o/oauth2/auth'); |
| 622 |
} else { |
| 623 |
$auth_url = add_query_arg([ |
| 624 |
'client_id' => '590712039607331', |
| 625 |
'redirect_uri' => $api_base . '/api/auth/facebook/callback-plugin', |
| 626 |
'response_type' => 'code', |
| 627 |
'scope' => 'email', |
| 628 |
'state' => $state, |
| 629 |
], 'https://www.facebook.com/v12.0/dialog/oauth'); |
| 630 |
} |
| 631 |
|
| 632 |
return [ |
| 633 |
'success' => true, |
| 634 |
'message' => "Open auth_url in a browser popup for the user to authorise with {$provider}, then pass state to wdesignkit/social-login.", |
| 635 |
'provider' => $provider, |
| 636 |
'auth_url' => $auth_url, |
| 637 |
'state' => $state, |
| 638 |
'expires_in' => $expires_in, |
| 639 |
]; |
| 640 |
} |
| 641 |
|
| 642 |
function wdesignkit_mcp_logout(array $input): array { |
| 643 |
if (!defined('WDKIT_SERVER_API_URL')) { |
| 644 |
return ['success' => false, 'message' => 'WDesignKit plugin is not active.']; |
| 645 |
} |
| 646 |
|
| 647 |
$auth = wdesignkit_mcp_template_get_auth(); |
| 648 |
|
| 649 |
if (empty($auth['logged_in'])) { |
| 650 |
return ['success' => true, 'message' => 'Already logged out — no active session found.']; |
| 651 |
} |
| 652 |
|
| 653 |
$token = $auth['token'] ?? ''; |
| 654 |
$email = $auth['email'] ?? ''; |
| 655 |
|
| 656 |
// Delete local session transient |
| 657 |
if ($email !== '') { |
| 658 |
$user_key = wdesignkit_cloud_session_key($email); |
| 659 |
delete_transient('wdkit_auth_' . $user_key); |
| 660 |
} |
| 661 |
|
| 662 |
// Drop the active-session pointer so no later call resolves the dead session |
| 663 |
wdesignkit_mcp_forget_session(); |
| 664 |
|
| 665 |
// Clear cached licence data |
| 666 |
delete_option('wdkit_licence_data'); |
| 667 |
|
| 668 |
// Notify cloud |
| 669 |
if ($token !== '') { |
| 670 |
wdesignkit_mcp_template_cloud_call('logout', ['token' => $token], 'json'); |
| 671 |
} |
| 672 |
|
| 673 |
return ['success' => true, 'message' => 'Logged out successfully.']; |
| 674 |
} |
| 675 |
|