Skip to content

Commit b027cf8

Browse files
committed
Add SRI to external scripts.
1 parent da1b11c commit b027cf8

File tree

2 files changed

+101
-8
lines changed

2 files changed

+101
-8
lines changed

plugins/wpgraphql-logging/bin/run-codeception.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ run_tests() {
7777
fi
7878

7979
if [[ -z "$coverage_percent" && -f "tests/_output/coverage/index.html" ]]; then
80-
# macOS/BSD grep lacks -P; use -E and strip the percent sign
81-
coverage_percent=$(grep -Eo '([0-9]+(\.[0-9]+)?)%' "tests/_output/coverage/index.html" | head -1 | tr -d '%')
80+
coverage_percent=$(grep -Eo '[0-9]+\.[0-9]+%' "tests/_output/coverage/index.html" | head -1 | tr -d '%')
8281
fi
8382
if [[ -z "$coverage_percent" ]]; then
8483
echo "Warning: Could not determine code coverage percentage."

plugins/wpgraphql-logging/src/Admin/ViewLogsPage.php

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public function setup(): void {
6565

6666
/**
6767
* Registers the settings page for the view logs.
68+
*
69+
* @psalm-suppress HookNotFound
6870
*/
6971
public function register_settings_page(): void {
7072

@@ -91,7 +93,9 @@ public function register_settings_page(): void {
9193
add_action( 'load-' . $this->page_hook, [ $this, 'process_page_actions_before_rendering' ], 10, 0 );
9294

9395
// Enqueue scripts for the admin page.
94-
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
96+
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ], 9, 1 ); // Need to load before adding SRI attributes.
97+
add_action( 'script_loader_tag', [ $this, 'add_sri_to_scripts' ], 10, 2 );
98+
add_action( 'style_loader_tag', [ $this, 'add_sri_to_styles' ], 10, 2 );
9599
}
96100

97101
/**
@@ -104,29 +108,26 @@ public function enqueue_admin_scripts( string $hook_suffix ): void {
104108
return;
105109
}
106110

107-
// Enqueue WordPress's built-in datepicker and slider.
108111
wp_enqueue_script( 'jquery-ui-datepicker' );
109112
wp_enqueue_script( 'jquery-ui-slider' );
110113

111-
// Enqueue the timepicker addon script and styles from a CDN.
112114
wp_enqueue_script(
113115
'jquery-ui-timepicker-addon',
114116
'https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.js',
115117
[ 'jquery-ui-datepicker', 'jquery-ui-slider' ],
116118
'1.6.3',
117-
true
119+
true,
118120
);
121+
119122
wp_enqueue_style(
120123
'jquery-ui-timepicker-addon-style',
121124
'https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.css',
122125
[],
123126
'1.6.3'
124127
);
125128

126-
// Enqueue the base jQuery UI styles.
127129
wp_enqueue_style( 'jquery-ui-style', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css', [], '1.12.1' );
128130

129-
// Add inline script to initialize the datetimepicker.
130131
wp_add_inline_script(
131132
'jquery-ui-timepicker-addon',
132133
'jQuery(document).ready(function($){ $(".wpgraphql-logging-datepicker").datetimepicker({ dateFormat: "yy-mm-dd", timeFormat: "HH:mm:ss" }); });'
@@ -136,6 +137,99 @@ public function enqueue_admin_scripts( string $hook_suffix ): void {
136137
do_action( 'wpgraphql_logging_view_logs_admin_enqueue_scripts', $hook_suffix );
137138
}
138139

140+
/**
141+
* Adds integrity and crossorigin attributes to scripts.
142+
*
143+
* @param string $tag The script tag.
144+
* @param string $handle The script handle.
145+
*
146+
* @link https://www.srihash.org/ to generate the integrity and crossorigin attributes.
147+
*/
148+
public function add_sri_to_scripts($tag, $handle): void {
149+
150+
$scripts = [
151+
'jquery-ui-timepicker-addon' => [
152+
'integrity' => 'sha512-s5u/JBtkPg+Ff2WEr49/cJsod95UgLHbC000N/GglqdQuLnYhALncz8ZHiW/LxDRGduijLKzeYb7Aal9h3codZA==',
153+
'crossorigin' => 'anonymous',
154+
],
155+
];
156+
157+
$scripts = apply_filters( 'wpgraphql_logging_view_logs_add_sri_to_scripts', $scripts );
158+
159+
if ( ! isset( $scripts[ $handle ] ) ) {
160+
return;
161+
}
162+
163+
$integrity = $scripts[ $handle ]['integrity'];
164+
$crossorigin = $scripts[ $handle ]['crossorigin'];
165+
166+
$tag = str_replace(
167+
' src=',
168+
' integrity="' . esc_attr( $integrity ) . '" crossorigin="' . esc_attr( $crossorigin ) . '" src=',
169+
$tag
170+
);
171+
172+
echo wp_kses( $tag, [
173+
'script' => [
174+
'src' => [],
175+
'integrity' => [],
176+
'crossorigin' => [],
177+
'type' => [],
178+
'id' => [],
179+
],
180+
'link' => [
181+
'href' => [],
182+
'integrity' => [],
183+
'crossorigin' => [],
184+
'rel' => [],
185+
'type' => [],
186+
'id' => [],
187+
],
188+
] );
189+
}
190+
191+
/**
192+
* Adds integrity and crossorigin attributes to styles.
193+
*
194+
* @param string $tag The script tag.
195+
* @param string $handle The script handle.
196+
*
197+
* @link https://www.srihash.org/ to generate the integrity and crossorigin attributes.
198+
*/
199+
public function add_sri_to_styles($tag, $handle): void {
200+
201+
$styles = [
202+
'jquery-ui-timepicker-addon-style' => [
203+
'integrity' => 'sha512-LT9fy1J8pE4Cy6ijbg96UkExgOjCqcxAC7xsnv+mLJxSvftGVmmc236jlPTZXPcBRQcVOWoK1IJhb1dAjtb4lQ==',
204+
'crossorigin' => 'anonymous',
205+
],
206+
];
207+
$styles = apply_filters( 'wpgraphql_logging_view_logs_add_sri_to_styles', $styles );
208+
209+
if ( ! isset( $styles[ $handle ] ) ) {
210+
return;
211+
}
212+
213+
$integrity = $styles[ $handle ]['integrity'];
214+
$crossorigin = $styles[ $handle ]['crossorigin'];
215+
216+
$tag = str_replace(
217+
' href=',
218+
' integrity="' . esc_attr( $integrity ) . '" crossorigin="' . esc_attr( $crossorigin ) . '" href=',
219+
$tag
220+
);
221+
222+
echo wp_kses( $tag, [
223+
'link' => [
224+
'src' => [],
225+
'integrity' => [],
226+
'crossorigin' => [],
227+
'type' => [],
228+
'id' => [],
229+
],
230+
] );
231+
}
232+
139233
/**
140234
* Renders the admin page for the logs.
141235
*/

0 commit comments

Comments
 (0)