Sid Gifari File Manager
🏠 Root
/
home
/
ailwtbdh
/
lynchestinegroup.com
/
wp-content
/
plugins
/
ninja-forms
/
blocks
/
Editing: bootstrap.php
<?php /** * Register blocks and there scripts */ add_action('init', function () { /** * Form Block */ // automatically load dependencies and version $block_asset_file = include dirname(__DIR__) . '/build/form-block.asset.php'; $block = (array)json_decode(file_get_contents(__DIR__ . '/form/block.json'), true); wp_register_script( 'ninja-forms/form', plugins_url('../build/form-block.js', __FILE__), $block_asset_file['dependencies'], $block_asset_file['version'] ); register_block_type('ninja-forms/form', array_merge($block, [ 'title' => esc_attr__('Ninja Form', 'ninja-forms'), 'render_callback' => function ($atts) { $formID = isset($atts['formID']) ? $atts['formID'] : 1; ob_start(); Ninja_Forms()->display( absint($formID), true ); return ob_get_clean(); }, 'editor_script' => 'ninja-forms/form' ])); /** * Views Block */ // automatically load dependencies and version $block_asset_file = include dirname(__DIR__) . '/build/sub-table-block.asset.php'; wp_register_script( 'ninja-forms/submissions-table/block', plugins_url('../build/sub-table-block.js', __FILE__), $block_asset_file['dependencies'], $block_asset_file['version'] ); // Note: Token will be generated per-page in render_callback with specific form IDs $render_asset_file = include dirname(__DIR__) . '/build/sub-table-render.asset.php'; wp_register_script( 'ninja-forms/submissions-table/render', plugins_url('../build/sub-table-render.js', __FILE__), $render_asset_file['dependencies'], $render_asset_file['version'] ); register_block_type('ninja-forms/submissions-table', array( 'editor_script' => 'ninja-forms/submissions-table/block', 'render_callback' => function ($attributes, $content) { if (isset($attributes['formID']) && $attributes['formID']) { // SECURITY: For non-published posts (draft previews, pending review, etc.), // require submission-viewing capability before issuing a token. // This prevents Contributor/Author users from obtaining tokens by adding // a submissions-table block to a draft post and previewing it. // Published pages intentionally issue tokens to all viewers (admin chose to // display submissions publicly by placing the block on a published page). $current_post = get_post(); if ( $current_post && 'publish' !== $current_post->post_status ) { $views_capability = apply_filters( 'ninja_forms_views_token_capability', apply_filters( 'ninja_forms_admin_submissions_capabilities', 'manage_options' ) ); if ( ! current_user_can( $views_capability ) ) { return ''; } } wp_enqueue_script('ninja-forms/submissions-table/render'); // Generate a token bound to THIS specific form ID only $formId = absint($attributes['formID']); $token = NinjaForms\Blocks\Authentication\TokenFactory::make(); $publicKey = NinjaForms\Blocks\Authentication\KeyFactory::make(); // Create token with form ID binding and expiration wp_localize_script('ninja-forms/submissions-table/render', 'ninjaFormsViews', [ 'token' => $token->create($publicKey, array($formId)), ]); // Enqueue signature fonts for proper display in Gutenberg block wp_enqueue_style( 'nf-signature-fonts', Ninja_Forms::$url . 'assets/fonts/signature/google-fonts.css', [], Ninja_Forms::VERSION ); $className = 'ninja-forms-views-submissions-table'; if (isset($attributes['alignment'])) { $className .= ' align' . $attributes['alignment']; } return sprintf("<div class='%s' data-attributes='%s'></div>", esc_attr($className), esc_attr(wp_json_encode($attributes))); } } )); /** * Have Translations set in scripts via i18n package * https://developer.wordpress.org/block-editor/packages/packages-i18n/ * https://developer.wordpress.org/reference/functions/wp_set_script_translations/ * https://developer.wordpress.org/block-editor/developers/internationalization/ */ wp_set_script_translations( "ninja-forms/form", "ninja-forms", plugin_dir_path( __FILE__ ) . 'lang' ); wp_set_script_translations( "ninja-forms/submissions-table/block", "ninja-forms", plugin_dir_path( __FILE__ ) . 'lang' ); wp_set_script_translations( "ninja-forms/submissions-table/render", "ninja-forms", plugin_dir_path( __FILE__ ) . 'lang' ); }); /** * Localize data for blocks */ add_action('admin_enqueue_scripts', function () { //Conditionally load data for Blocks $screen = get_current_screen(); if( is_null( $screen ) ) return; if( ! $screen->is_block_editor() ) return; //Get all forms, to base form selector on. $formsBuilder = (new NinjaForms\Blocks\DataBuilder\FormsBuilderFactory)->make(); $forms = $formsBuilder->get(); if (!empty($forms)) { //Escape for use in JavaScript foreach ($forms as $key => $form) { $forms[$key] = [ 'formID' => absint($form['formID']), 'formTitle' => esc_textarea($form['formTitle']) ]; } } wp_localize_script('ninja-forms/form', 'nfFormsBlock', [ 'forms' => $forms,//array keys escaped above 'homeUrl' => esc_url_raw( home_url() ), //URL to serve the iFrame that displays the form in blocks editor 'previewToken' => wp_create_nonce('nf_iframe' ) ]); // For block editor, provide a token that allows access to all forms // SECURITY: Only users with appropriate capability can receive tokens for viewing submissions // This prevents Contributors/Authors from accessing form submission data via the REST API // // Uses ninja_forms_admin_submissions_capabilities filter for consistency with Submissions menu // Additional filter ninja_forms_views_token_capability allows specific customization for Views API $views_capability = apply_filters( 'ninja_forms_views_token_capability', apply_filters( 'ninja_forms_admin_submissions_capabilities', 'manage_options' ) ); if ( current_user_can( $views_capability ) ) { $token = NinjaForms\Blocks\Authentication\TokenFactory::make(); $publicKey = NinjaForms\Blocks\Authentication\KeyFactory::make(); $allFormIds = array_map(function($form) { return absint($form['formID']); }, $forms); wp_localize_script('ninja-forms/submissions-table/block', 'ninjaFormsViews', [ 'token' => $token->create($publicKey, $allFormIds), ]); } }); /** * Register REST API routes related to blocks */ add_action('rest_api_init', function () { /** * Enhanced permission callback that validates token and checks form-level authorization. * * Security improvements: * - Rate limiting to prevent DoS attacks * - Validates token authenticity (hash, expiration) * - Checks if token is authorized for the requested form ID * - Falls back to WordPress capability check for admin users * * @param WP_REST_Request $request * @return bool|WP_Error */ $tokenAuthenticationCallback = function (WP_REST_Request $request) { // Check rate limit first (lightweight check) $endpoint = $request->get_route(); $rateLimitCheck = NinjaForms\Blocks\Authentication\RateLimiter::check($endpoint); if (is_wp_error($rateLimitCheck)) { return $rateLimitCheck; } $tokenValidator = NinjaForms\Blocks\Authentication\TokenFactory::make(); $tokenHeader = $request->get_header('X-NinjaFormsViews-Auth'); $formId = $request->get_param('id'); // If user is logged in and has appropriate capability, allow access // This provides fallback for admin users // Uses same capability filter as token generation for consistency $views_capability = apply_filters( 'ninja_forms_views_token_capability', apply_filters( 'ninja_forms_admin_submissions_capabilities', 'manage_options' ) ); if (is_user_logged_in() && current_user_can($views_capability)) { return true; } // Validate token with form ID authorization if ($formId) { return $tokenValidator->validate($tokenHeader, intval($formId)); } // For routes without a specific form ID (like /forms list), only validate token structure // The token must still be valid (not expired, proper signature) return $tokenValidator->validate($tokenHeader); }; register_rest_route('ninja-forms-views', 'forms', array( 'methods' => 'GET', 'callback' => function (WP_REST_Request $request) { $tokenValidator = NinjaForms\Blocks\Authentication\TokenFactory::make(); $tokenHeader = $request->get_header('X-NinjaFormsViews-Auth'); // Get all forms $formsBuilder = (new NinjaForms\Blocks\DataBuilder\FormsBuilderFactory)->make(); $allForms = $formsBuilder->get(); // If user has appropriate capability, return all forms $views_capability = apply_filters( 'ninja_forms_views_token_capability', apply_filters( 'ninja_forms_admin_submissions_capabilities', 'manage_options' ) ); if (is_user_logged_in() && current_user_can($views_capability)) { return $allForms; } // Otherwise, filter forms based on token authorization $authorizedFormIds = $tokenValidator->getFormIds($tokenHeader); if ($authorizedFormIds === false) { return new WP_Error('invalid_token', 'Invalid token', array('status' => 403)); } // Filter to only return forms the token has access to $filteredForms = array_filter($allForms, function($form) use ($authorizedFormIds) { return in_array(intval($form['formID']), $authorizedFormIds, true); }); return array_values($filteredForms); }, 'permission_callback' => $tokenAuthenticationCallback, )); register_rest_route('ninja-forms-views', 'forms/(?P<id>\d+)/fields', [ 'methods' => 'GET', 'args' => [ 'id' => [ 'required' => true, 'description' => esc_attr__('Unique identifier for the object.', 'ninja-forms'), 'type' => 'integer', 'validate_callback' => 'rest_validate_request_arg', ], ], 'callback' => function (WP_REST_Request $request) { $fieldsBuilder = (new NinjaForms\Blocks\DataBuilder\FieldsBuilderFactory)->make( $request->get_param('id') ); return $fieldsBuilder->get(); }, 'permission_callback' => $tokenAuthenticationCallback, ]); register_rest_route('ninja-forms-views', 'forms/(?P<id>\d+)/submissions', [ 'methods' => 'GET', 'args' => [ 'id' => [ 'required' => true, 'description' => esc_attr__('Unique identifier for the object.', 'ninja-forms'), 'type' => 'integer', 'validate_callback' => 'rest_validate_request_arg', ], 'perPage' => [ 'description' => esc_attr__('Maximum number of items to be returned in result set.', 'ninja-forms'), 'type' => 'integer', 'minimum' => 1, 'maximum' => 100, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ], 'page' => [ 'description' => esc_attr__('Current page of the collection.', 'ninja-forms'), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', 'minimum' => 1, ] ], 'callback' => function (WP_REST_Request $request) { $submissionsBuilder = (new NinjaForms\Blocks\DataBuilder\SubmissionsBuilderFactory)->make( $request->get_param('id'), $request->get_param('perPage'), $request->get_param('page') ); return $submissionsBuilder->get(); }, 'permission_callback' => $tokenAuthenticationCallback, ]); /** * Token Refresh Endpoint * * Generates a new token scoped to the same form ID as the previous token. * Used for automatic token refresh when tokens expire or after secret rotation. * * SECURITY: Requires the old token to be provided. This ensures: * - Only tokens that were legitimately issued can be refreshed * - Tokens can only be refreshed for the same form ID * - No reliance on spoofable Referer headers */ register_rest_route('ninja-forms-views', 'token/refresh', array( 'methods' => 'POST', 'callback' => function (WP_REST_Request $request) { $tokenValidator = NinjaForms\Blocks\Authentication\TokenFactory::make(); // SECURITY: Require the old token for refresh // This prevents attackers from generating tokens without having a legitimate one first $oldToken = $request->get_header('X-NinjaFormsViews-Auth'); if (!$oldToken) { return new WP_Error( 'missing_token', __('A valid token is required for refresh. Include the current token in X-NinjaFormsViews-Auth header.', 'ninja-forms'), array('status' => 401) ); } // Validate the old token's signature (allows expired tokens for refresh) // This ensures the token was legitimately issued by this site if (!$tokenValidator->validateSignatureOnly($oldToken)) { return new WP_Error( 'invalid_token', __('The provided token is invalid or has been tampered with.', 'ninja-forms'), array('status' => 403) ); } // Extract form IDs from the old token - these are the only forms allowed for refresh $authorizedFormIds = $tokenValidator->getFormIds($oldToken); if ($authorizedFormIds === false || empty($authorizedFormIds)) { return new WP_Error( 'invalid_token_payload', __('Could not extract form authorization from token.', 'ninja-forms'), array('status' => 403) ); } // Get the requested form ID (optional - defaults to first form in old token) $formId = $request->get_param('formID'); // Check for legacy formIds parameter for backward compatibility if (!$formId && $request->get_param('formIds')) { $formIds = $request->get_param('formIds'); if (is_array($formIds) && !empty($formIds)) { $formId = $formIds[0]; } } // If no form ID specified, use the first (and typically only) form from old token if (!$formId) { $formId = $authorizedFormIds[0]; } // Sanitize form ID $formId = absint($formId); if (!$formId) { return new WP_Error( 'invalid_form_id', __('Valid form ID is required', 'ninja-forms'), array('status' => 400) ); } // SECURITY: Verify the requested form ID was in the old token // This prevents upgrading a single-form token to access other forms if (!in_array($formId, array_map('intval', $authorizedFormIds), true)) { return new WP_Error( 'unauthorized_form_access', __('The requested form was not authorized in your original token.', 'ninja-forms'), array('status' => 403) ); } // Validate that the form still exists $form = Ninja_Forms()->form($formId)->get(); if (!$form) { return new WP_Error( 'form_not_found', __('The requested form does not exist', 'ninja-forms'), array('status' => 404) ); } // Generate new token scoped to the single requested form $publicKey = NinjaForms\Blocks\Authentication\KeyFactory::make(32); $tokenGenerator = NinjaForms\Blocks\Authentication\TokenFactory::make(); $newToken = $tokenGenerator->create($publicKey, array($formId)); return array( 'token' => $newToken, 'publicKey' => $publicKey, 'expiresIn' => 900, // 15 minutes in seconds 'formID' => $formId, ); }, 'permission_callback' => function (WP_REST_Request $request) { // Apply stricter rate limiting to refresh endpoint $rateLimitCheck = NinjaForms\Blocks\Authentication\RateLimiter::check( '/ninja-forms-views/token/refresh', 50, // limit: 50 requests 300 // window: 5 minutes ); if (is_wp_error($rateLimitCheck)) { return $rateLimitCheck; // Returns 429 Too Many Requests } return true; // Rate-limited, but token validation happens in callback }, )); }); /** * Handler for form preview iFrame used in Forms block */ add_action( 'wp_head', function () { // check for preview and iframe get parameters if( isset( $_GET[ 'nf_preview_form' ] ) && isset( $_GET[ 'nf_iframe' ] ) ){ if( ! wp_verify_nonce( $_GET['nf_iframe'], 'nf_iframe') ){ wp_die( esc_html__('Preview token failed validation', 'ninja-forms')); exit; } //Attempt to get theme background color $background = '#fff'; $supports = get_theme_support('editor-color-palette','background'); if( is_array($supports) ){ foreach($supports[0] as $index => $support ){ if( 'background' === $support['slug']){ $background = $support['color']; break; } } } $js_lib_dir = Ninja_Forms::$url . 'assets/js/lib/'; $form_id = absint( $_GET[ 'nf_preview_form' ] ); // Style below: update width and height for particular form ?> <style media="screen"> #wpadminbar { display: none; } #nf-form-<?php echo $form_id; ?>-cont { z-index: 90000001; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: <?php echo sanitize_hex_color($background ); ?>; } div.site-branding, header.entry-header, .site-footer, header, .footer-nav-widgets-wrapper { display:none !important; } </style> <?php // register our script to target the form iFrame in page builder wp_register_script( 'ninja-forms-block-setup', $js_lib_dir . 'blockFrameSetup.js', array( 'underscore', 'jquery' ) ); wp_localize_script( 'ninja-forms-block-setup', 'ninjaFormsBlockSetup', array( 'form_id' => $form_id ) ); wp_enqueue_script( 'ninja-forms-block-setup' ); } }); /** * Schedule WP-Cron job for automatic secret rotation */ add_action('init', function() { if (!wp_next_scheduled('ninja_forms_views_check_rotation')) { wp_schedule_event(time(), 'daily', 'ninja_forms_views_check_rotation'); } }); /** * WP-Cron callback: Check if secret should be rotated and rotate if needed */ add_action('ninja_forms_views_check_rotation', function() { if (NinjaForms\Blocks\Authentication\SecretStore::shouldRotate()) { NinjaForms\Blocks\Authentication\SecretStore::rotate(); } }); /** * Clear scheduled events on plugin deactivation */ register_deactivation_hook(__FILE__, function() { $timestamp = wp_next_scheduled('ninja_forms_views_check_rotation'); if ($timestamp) { wp_unschedule_event($timestamp, 'ninja_forms_views_check_rotation'); } });
Save
Cancel