array( 'GET', 'OPTIONS' ), 'callback' => array( $this, 'get_domain_profile' ), // This endpoint is intentionally public - it serves domain profile data that should be accessible to anyone. 'permission_callback' => '__return_true', ) ); } /** * Add rewrite rule for .well-known/domain-profile.json. */ public function add_rewrite_rule() { add_rewrite_rule( '^\.well-known/domain-profile\.json$', 'index.php?aidd_endpoint=1', 'top' ); add_rewrite_tag( '%aidd_endpoint%', '([^&]+)' ); } /** * Handle .well-known/domain-profile.json requests. */ public function handle_well_known_request() { // Check if this is our endpoint request via query var or direct URI. $is_endpoint = get_query_var( 'aidd_endpoint' ); $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; if ( $is_endpoint || strpos( $request_uri, '/.well-known/domain-profile.json' ) !== false ) { // Handle OPTIONS request for CORS preflight. if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) { header( 'Access-Control-Allow-Origin: *' ); header( 'Access-Control-Allow-Methods: GET, OPTIONS' ); header( 'Access-Control-Allow-Headers: Content-Type' ); header( 'Content-Length: 0' ); status_header( 200 ); exit; } $profile = AIDD_Generator::generate(); $validation = AIDD_Validator::validate( $profile ); // Set headers. header( 'Content-Type: application/json; charset=utf-8' ); header( 'Cache-Control: public, max-age=3600, s-maxage=3600' ); header( 'Access-Control-Allow-Origin: *' ); header( 'Access-Control-Allow-Methods: GET, OPTIONS' ); header( 'Access-Control-Allow-Headers: Content-Type' ); if ( ! $validation['valid'] ) { status_header( 500 ); echo wp_json_encode( array( 'error' => __( 'Domain profile validation failed', 'ai-domain-data' ), 'errors' => $validation['errors'], ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ); exit; } status_header( 200 ); echo wp_json_encode( $profile, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ); exit; } } /** * Get the domain profile JSON. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function get_domain_profile( $request ) { // Handle OPTIONS request for CORS preflight. if ( $request->get_method() === 'OPTIONS' ) { return new WP_REST_Response( null, 200 ); } $profile = AIDD_Generator::generate(); $validation = AIDD_Validator::validate( $profile ); if ( ! $validation['valid'] ) { return new WP_Error( 'aidd_validation_failed', __( 'Domain profile validation failed', 'ai-domain-data' ), array( 'status' => 500, 'errors' => $validation['errors'], ) ); } $response = new WP_REST_Response( $profile, 200 ); $response->header( 'Content-Type', 'application/json; charset=utf-8' ); $response->header( 'Cache-Control', 'public, max-age=3600, s-maxage=3600' ); return $response; } /** * Add CORS headers to REST API responses. * * @param bool $served Whether the request has already been served. * @param WP_HTTP_Response $result Result to send to the client. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $server Server instance. * @return bool */ public function add_cors_headers( $served, $result, $request, $server ) { // Only add CORS headers for our endpoint. if ( strpos( $request->get_route(), '/aidd/v1/.well-known/domain-profile.json' ) !== false ) { header( 'Access-Control-Allow-Origin: *' ); header( 'Access-Control-Allow-Methods: GET, OPTIONS' ); header( 'Access-Control-Allow-Headers: Content-Type' ); } return $served; } }