two-factor icon indicating copy to clipboard operation
two-factor copied to clipboard

Assets URIs computed wrong if plugin is loaded from /vendor

Open kadamwhite opened this issue 3 years ago • 3 comments

If you have an application structure where this plugin gets installed into vendor due to a composer install override, the asset URLs do not resolve properly in subdomain multisite installs.

For example, if you have a WP site at mydomain.com/site-name/, then because the asset URIs are computed using plugins_url( '/path', __FILE ), you'll get a final asset URI like this:

mydomain.com/site-name/vendor/wordpress/two-factor/providers/js/fido-u2f-admin.js

instead of

mydomain.com/vendor/wordpress/two-factor/providers/js/fido-u2f-admin.js

with /vendor in the site root. This causes the 2FA form to fail to render, and you cannot set a provider.

This small plugin resolves the issue:

/**
 * Fix URL resolution for plugins_url when used on a file within the vendor directory.
 *
 * @param string $url    URL being returned for this plugin.
 * @param string $path   Path of resource within plugin.
 * @param string $plugin Plugin path.
 * @return string The filtered URL.
 */
function prefix_fix_two_factor_asset_uris( string $url, string $path, string $plugin ) {
	if ( strpos( $plugin, 'vendor/' ) === false ) {
		return $url;
	}
	$site_url = parse_url( get_site_url() );
	return str_replace( trailingslashit( $site_url['path'] ) . 'vendor', '/vendor', $url );
}
add_filter( 'plugins_url', 'prefix_fix_two_factor_asset_uris', 10, 3 );

I understand if installation to vendor/ is an edge case this plugin isn't interested in handling, but I wanted to report this here in case it's something y'all felt worth fixing.

kadamwhite avatar Nov 01 '22 18:11 kadamwhite

Ensuring the plugin supports this case seems worthy to me, +1. I'm dropping into the Future Release milestone as there are some larger items targeted for a 0.8.0 and 0.9.0 releases, but if someone wants to work on a PR for this then we could look to pull into one of those two releases as feasible via code review/approvals.

jeffpaul avatar Nov 01 '22 19:11 jeffpaul

plugins_url() is the conventional/official approach though, isn't it? Do other plugins do something different that doesn't conflict with vendor installs, or would you need the prefix_fix_two_factor_asset_uris() workaround for other plugins too?

IIRC what I've seen done before is configuring Composer to install plugins into wp-content/plugins/ instead.

iandunn avatar Nov 02 '22 20:11 iandunn

I agree with @iandunn here - It sounds like this is simply Core's behaviour when __FILE__ exists outside of ABSPATH and WP_CONTENT_DIR, which necessitates such hosting environments to have a filter on plugins_url (amongst others) to set the correct public URL for those files.

dd32 avatar Nov 04 '22 03:11 dd32