Experiencing a 401 Unauthorized Error During Update?

If you're seeing a 401 Unauthorized error when trying to update your Joomla extension, it's likely due to our new two-factor authentication (2FA) security measure for your Download ID.
To resolve this, check your email (Spam folder?) for a message to approve your server or device, or read our detailed blog post here( onlinecommunityhub.nl/best-practice/new-...-extension-downloads) to understand the steps involved. This will guide you through approving your server for future updates.

Implemented Email templates relative paths

More
2 months 1 week ago #3121 by Sakis Terz
Email templates relative paths was created by Sakis Terz
Hi Ruud

I am using some links and some images in my email templates, but every time i re-open them the urls become relevant (e.g. <a href="subscribe").
Not sure if there is some filtering from the editor or is coming from your code.
Any idea?

Kind regards,

Please Log in to join the conversation.

More
2 months 1 week ago #3122 by Ruud van Lent
Replied by Ruud van Lent on topic Email templates relative paths
Hi Sakis,

that is a editor 'feature' that (depending on your editor) can be turned on / off: note that this is then generic so when turning it off it will also be turned off in other extensions.

What I do is before saving the email template, turn off the editor (and check if all URL's are still absolute)

Please Log in to join the conversation.

More
2 months 1 week ago - 2 months 1 week ago #3123 by Ruud van Lent
Replied by Ruud van Lent on topic Email templates relative paths
Hi Sakis,
so did a deeper dive into this to see if I can improve :)

In the email send ochSubscriptions adds the following line:
<base href="[your domain]" />

What this does / should do, is instruct the email client to make a relative url (e.g. test-url) absolute (so: [your domain]/test-url)

This way you can use both absolute and relative urls in your email templates as these will then be handled by the email client.

but... what if the email client doesn't use / respect the 'base href' setting? Then the absolute urls will work, but the relative urls will not (as these point to nowhere).

tinyMCE can be configured to store urls as relative or absolute: this has impact on everything the editor is used for, so when changing it to store absolute urls (which we want in emails) then also in articles all urls will be absolute (which we don't want)...

So in the version above I have a version of ochSubscriptions that will convert all elements (a, img, link, script, form, input, video, audio, source) in the email template to absolute URLs when rendering and sending the email (so not in the template itself).
This way you can either use absolute or relative urls: absolute will stay unchanged 9as these can also point to another website) and relative urls will be made absolute pointing to your site.

Can you give this a test to see if it works as intended and solves this url nightmare :)
Last edit: 2 months 1 week ago by Ruud van Lent. Reason: new download versions!

Please Log in to join the conversation.

More
5 days 21 hours ago - 5 days 21 hours ago #3171 by Sakis Terz
Replied by Sakis Terz on topic Email templates relative paths
Hi Ruud

Sorry for the late reply. I tried both the [your domain] and [your_domain] and they do not work.
Btw. I see that the email placeholders are using curly braces {}

Kind regards,
Sakis
Last edit: 5 days 21 hours ago by Sakis Terz.

Please Log in to join the conversation.

More
5 days 21 hours ago - 5 days 21 hours ago #3172 by Ruud van Lent
Replied by Ruud van Lent on topic Email templates relative paths
Hi Sakis,
I think there is some confusion. With [you domain] I mean you actual website domain.
So on my server that would be:
  1. https ://onlinecommunityhub .nl/testlink
  2. or /testlink
Both would then in the mail be set as https :/onlinecommunityhub .nl/testlink (so with  the actual domain in the link)
Last edit: 5 days 21 hours ago by Ruud van Lent.

Please Log in to join the conversation.

More
5 days 21 hours ago #3173 by Sakis Terz
Replied by Sakis Terz on topic Email templates relative paths
But my problem is exactly that, when I enter my actual domain, it gets stripped. This happen only with my domain. If I use urls pointing to outside domains it works.

Is there a placeholder I could use, instead of my actual domain?

Please Log in to join the conversation.

More
5 days 21 hours ago #3174 by Sakis Terz
Replied by Sakis Terz on topic Email templates relative paths
Btw /testlink stays as is in the actual email message, leading nowhere

Please Log in to join the conversation.

More
5 days 21 hours ago #3175 by Ruud van Lent
Replied by Ruud van Lent on topic Email templates relative paths
What version of ochSubscriptions do you have installed?
In version 4.0.1 I have added the updated logic to always add the local domain name to the url: so when the editor strips it, when ochSubscriptions renders the email text from the template it will add it back

Please Log in to join the conversation.

More
5 days 21 hours ago #3176 by Sakis Terz
Replied by Sakis Terz on topic Email templates relative paths
Thanks for that!
I am currently on 3.13.3
Is 4.0.1 compatible with J4?

Please Log in to join the conversation.

More
5 days 21 hours ago #3177 by Ruud van Lent
Replied by Ruud van Lent on topic Email templates relative paths
No it is not.

in your current install, locate file ContentConstructor.php and replace the function "prepareEmailBody" with the one below:
BACKUP and TEST :)
Code:
    /**      * Function to prepare the Email body; add necessary HTML elements and framework      *      * @param   string  $body     The body of the email      * @param   string  $subject  The subject of the email      * @param   string  $style    The style (css) of the email      *      * @return string      */     private function prepareEmailBody($body, $subject, $style)     {         $charset = Factory::getApplication()->getDocument()->getCharset();         $preparedBody = '<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">' . "\n";         $preparedBody .= '<head>' . "\n";         $preparedBody .= '<!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->' . "\n";         $preparedBody .= '<meta http-equiv="Content-Type" content="text/html; charset=' . strtolower($charset) . '" />' . "\n";         $preparedBody .= '<meta name="viewport" content="width=device-width, initial-scale=1.0" />' . "\n";         $preparedBody .= '<base href="' . Uri::root(false) . '" />' . "\n";         $preparedBody .= '<title>' . $subject . '</title>' . "\n";         $preparedBody .= $style;         $preparedBody .= '</head>' . "\n";         $preparedBody .= '<body yahoo="fix">' . $body . '</body>' . "\n";         $preparedBody .= '</html>';         // Load HTML content into DOMDocument         $dom = new \DOMDocument();         libxml_use_internal_errors(true); // Suppress warnings due to malformed HTML         $dom->loadHTML($preparedBody);         libxml_clear_errors();         $baseUrl = Uri::root(false);         // Define elements and attributes to be checked for relative URLs         $elementsToCheck = [             'a'      => 'href',             'img'    => 'src',             'link'   => 'href',             'script' => 'src',             'form'   => 'action',             'input'  => 'src',             'video'  => 'src',             'audio'  => 'src',             'source' => ['src', 'srcset']         ];         // Loop through each element and attribute in the list         foreach ($elementsToCheck as $tag => $attributes) {             $attributes = (array) $attributes; // Ensure it's an array for easy iteration             foreach ($dom->getElementsByTagName($tag) as $element) {                 foreach ($attributes as $attribute) {                     $url = $element->getAttribute($attribute);                     // Check if the attribute value is a relative URL                     if ($url) {                         if (\strpos($url, $baseUrl) === 0) {                             // Remove the base URL portion to make it relative                             $url = \substr($url, \strlen($baseUrl));                             $element->setAttribute($attribute, $url);                         }                         if (\parse_url($url, PHP_URL_SCHEME) === null) {                             // Prepend base URL if it's a relative path                             $element->setAttribute($attribute, \rtrim($baseUrl, '/') . '/' . \ltrim($url, '/'));                         }                     }                 }             }         }         // // Handle inline styles (for background images)         // foreach ($dom->getElementsByTagName('*') as $element) {         //     $style = $element->getAttribute('style');         //     if (preg_match('/url\([\'"]?\/([^\'")]+)[\'"]?\)/i', $style, $matches)) {         //         // Replace relative URL with absolute URL in the style attribute         //         $absoluteUrl = rtrim($baseUrl, '/') . '/' . ltrim($matches[1], '/');         //         $newStyle = str_replace($matches[0], "url('$absoluteUrl')", $style);         //         $element->setAttribute('style', $newStyle);         //     }         // }         // Save updated HTML content         $preparedBody = $dom->saveHTML();         return $preparedBody;     }
 

Please Log in to join the conversation.