PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / trunk
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! vtrunk
3.8.0 3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 All 112 releases
templately / modules / mcp-abilities / Abilities / AuthLoginWithApiKeyAbility.php

AuthLoginWithApiKeyAbility.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! trunk, at modules/mcp-abilities/Abilities/AuthLoginWithApiKeyAbility.php

113 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * `templately/auth-login-with-api-key` — connect this site to a Templately
4 * account using an account API key (spec 041-mcp-abilities, Auth Tools
5 * addendum).
6 *
7 * Deliberately does NOT proxy `Templately\API\Login::login()` via
8 * RestDispatcher: that method persists via `Options->set(..., $user_id =
9 * null)`, which internally resolves the target user through the same stale
10 * singleton cache described in MCP/CLAUDE.md — the call would report
11 * success but silently write the connection under the wrong (unauthenticated,
12 * id 0) user. This ability calls the same `connectWithApiKey` GraphQL
13 * mutation directly and persists with the acting user's id resolved fresh
14 * at execute time, explicitly threaded through every `Options` call.
15 *
16 * Scope: single-account connect only — the `global_signin` (shared/linked
17 * account) flow `Login::login()` also supports is intentionally not exposed
18 * here to keep this ability's behavior simple and predictable for an agent.
19 *
20 * @package Templately\Modules\McpAbilities\Abilities
21 */
22
23 namespace Templately\Modules\McpAbilities\Abilities;
24
25 use Templately\Modules\McpCore\Registry\ToolDescriptor;
26 use Templately\Modules\McpCore\Support\Permissions;
27 use Templately\Utils\Helper;
28 use Templately\Utils\Response\ErrorCode;
29 use Templately\Utils\Http;
30 use Templately\Utils\Options;
31 use WP_Error;
32
33 class AuthLoginWithApiKeyAbility {
34
35 const ID = 'templately/auth-login-with-api-key';
36
37 public static function descriptor(): array {
38 return [
39 'id' => self::ID,
40 'label' => __( 'Connect Templately with an API Key', 'templately' ),
41 'description' => __( 'Connect this site to a Templately account using an account API key.', 'templately' ),
42 'input_schema' => [
43 'type' => 'object',
44 'properties' => [
45 'api_key' => [ 'type' => 'string', 'description' => __( 'Templately account API key.', 'templately' ) ],
46 ],
47 'required' => [ 'api_key' ],
48 'additionalProperties' => false,
49 ],
50 'output_schema' => [
51 'type' => 'object',
52 ],
53 'execute_callback' => [ self::class, 'execute' ],
54 'permission_callback' => [ Permissions::class, 'can_use_abilities' ],
55 'access_level' => ToolDescriptor::ACCESS_FULL,
56 'annotations' => [ 'readonly' => false, 'destructive' => false, 'idempotent' => true ],
57 ];
58 }
59
60 /**
61 * @param array $input
62 * @return array|WP_Error
63 */
64 public static function execute( array $input ) {
65 $api_key = trim( (string) ( $input['api_key'] ?? '' ) );
66
67 if ( empty( $api_key ) ) {
68 return new WP_Error( ErrorCode::INVALID_API_KEY, __( 'An API key is required.', 'templately' ) );
69 }
70
71 $user_id = get_current_user_id();
72
73 $query = 'status, message, user{ id, name, first_name, last_name, display_name, email, profile_photo, joined, is_verified, is_company_user, api_key, plan, plan_expire_at }';
74
75 $response = Http::get_instance()->mutation(
76 'connectWithApiKey',
77 $query,
78 [
79 'ip' => Helper::get_ip(),
80 'site_url' => home_url( '/' ),
81 'api_key' => $api_key,
82 ]
83 )->post();
84
85 if ( is_wp_error( $response ) ) {
86 return $response;
87 }
88
89 if ( empty( $response['user']['api_key'] ) ) {
90 return new WP_Error( ErrorCode::INVALID_API_KEY, $response['message'] ?? __( 'Invalid API key.', 'templately' ) );
91 }
92
93 $options = Options::get_instance();
94 $options->set( 'api_key', $response['user']['api_key'], $user_id );
95 unset( $response['user']['api_key'] );
96
97 $response['user']['ip'] = Helper::get_ip();
98 $response['user']['site_url'] = base64_encode( home_url( '/' ) );
99
100 $options->set( 'user', $response['user'], $user_id );
101
102 return [
103 'status' => 'success',
104 'user' => [
105 'id' => $response['user']['id'] ?? null,
106 'name' => $response['user']['name'] ?? null,
107 'email' => $response['user']['email'] ?? null,
108 'plan' => $response['user']['plan'] ?? null,
109 ],
110 ];
111 }
112 }
113