XF 2.1 Welcome to XenForo 2.1 / Assorted improvements

Welcome to XenForo 2.1!

We said there would be something special accompanying the final HYS in this series for XF 2.1, and here it is. This is your first opportunity to help us put the new feature set through its paces.

We also said there would be a number of other miscellaneous changes/improvements to show you, so read on for more 👇
 
JSON conversion

Traditionally we have always used PHP's built-in serialization features as a way to encode data arrays as strings for database storage. Although there are still some benefits to using serialization, we have updated most of our schema to use JSON going forward.

There are also some immediate benefits to using JSON including that it is technically "safer" as it cannot encode/decode PHP objects. But there are also some longer term benefits which may be more relevant in the future.

One such benefit is that newer versions of MySQL support JSON as a data type more natively, which adds a myriad of new ways to interact with array-like data directly. We're not ready to support this, yet, as it would require MySQL 5.7/8.0 (or equivalent), but this would certainly be something useful to us and third party developers in the future. The biggest barrier to this currently is that over 70% of our existing customer base are using versions of MySQL which would not support the additional JSON functions, so if you fall into that category then we recommend starting to plan your MySQL upgrades now :)

From a development point of view, we would recommend developers follow suit and move their existing data to JSON if they haven't already and they are able to. To help with the conversion we have added some helper methods you can use from your Setup classes. Here's an example of an upgrade step in XFMG:
PHP:
public function upgrade902010010Step5(array $stepParams)
{
    $position = empty($stepParams[0]) ? 0 : $stepParams[0];

    return $this->entityColumnsToJson('XFMG:MediaNote', ['note_data'], $position, $stepParams);
}
This takes a short entity name and an array of column names to perform the conversion on. The last two arguments are optional, but recommended if you're converting a significant amount of data as it allows the process to be chunked and resumable.
 
Rounded avatars by default

XF 2.1 introduces round avatars by default. They are a bit more aesthetically pleasing:

localhost_21x_index.php (16).webp

roundavs.webp

This explains the new online indicator 😉
That said, some people may prefer non-round avatars and if that's the case you can use this new style property to make them square again:

localhost_21x_admin.php_styles_default-style.1_style-properties_group&group=avatar.webp

Changing this value to 2px will give them the same appearance as XF 2.0.
 
Last poster avatar on the forum list

Speaking of avatars, we've also added last poster avatars to the forum list.

localhost_21x_index.php (17).webp

To give us enough space here to fit the avatars in, we've changed the threads/messages stats to display in a short number format, e.g. 1.4K rather than 1,396.
 
BB code and rich text editing for profile posts and comments

For some communities, profile posts are an essential factor in helping your members to engage with each other. Yet the overall experience in terms of creating this content isn't quite as advanced as, say, standard forum posts. So we thought it was time to change that :)

localhost_21x_index.php_members_chris-d.1_ (1).webp

profile_bbcode.webp

Creating profile posts now allows you to use the rich text editor, full BB code (and Markdown), smilies and everything that comes with it.

Profile post pages can have quite a few editors on the screen at any given time. Trying to initialise all of the rich text editors on page load would be fairly intensive, so we have added a new deferred initialisation so that we only load the editor when you click on it, as demonstrated by the above two screenshots.

Here's a completed profile post with some richer formatting:

localhost_21x_index.php_members_chris-d.1_ (2).webp

You may notice something else slightly different here too. To comment on profile posts you previously had to click a "Comment" link in the profile post action bar.

The main issue with that is if you've got a long list of comments then you would have to scroll up to tap the Comment link. As you can see above we now have a "Write a comment..." input directly below the list of comments. Clicking this, as mentioned above, loads the editor which, again, also supports rich formatting:

localhost_21x_index.php_members_chris-d.1_ (3).webp

In case you prefer the old approach to triggering the comment input, then we still support that too. You would just enable this style property:

localhost_21x_admin.php_styles_default-style.1_style-properties_group&group=member.webp
 
Better support for iPhone X/Xr/Xs displays

Anyone who currently has an iPhone with a "notch" or "display cut out" such as the iPhone X series will be familiar with something like this:

live.browserstack.com_dashboard_utm_source=chrome&utm_medium=extension&utm_campaign=quick-lau...webp

iOS automatically has a behaviour to ensure that no content is ever hidden by the notch. It essentially constrains the viewport so that the content fits within the "safe inset areas".

In XF 2.1 however, we've improved this slightly so that we can make use of the full width of the viewport whilst still ensuring that content is not hidden behind the notch. It looks like this!

live.browserstack.com_dashboard_utm_source=chrome&utm_medium=extension&utm_campaign=quick-lau...webp

This is currently confirmed to work in Safari on iOS but theoretically it should work on Android P based devices (such as the Google Pixel 3) too. If not now, then it's certainly something we will look to support in the future (it's a fairly new Chrome feature).

If you happen to have a Google Pixel 3 running Android P it would be great if you can let us know whether it looks similar to the XF 2.0 screenshot above or more like the XF 2.1 screenshot :)
 
Support and automatically process unsubscribe requests using the List-Unsubscribe header in emails

Most emails within XenForo are purely transactional and do not require the same treatment in terms of unsubscribing from them. But for emails sent through the "Email users" page in the Admin CP, users will only receive these if they've been opted into, and we provide an easy link in the footer of the email for opting out of them (which does not require a login and disables the "Receive news and update emails" checkbox).

However, most email services provide a more convenient way of being able to unsubscribe to these types of emails which, until now, we haven't exposed.

Clients which support this feature will display a more prominent unsubscribe link so your users don't need to go hunting for it in the email itself. Here are some examples:

email_unsub1.webp


email_unsub2.webp

The mechanism which displays the "Unsubscribe" link is the inclusion of a special header in the email called List-Unsubscribe. The value that most email clients prefer this to contain is an email address. When clicked, an email is sent to that address. There's a new option under Email options which allows you to specify the email address which the unsubscribe requests are sent to:

localhost_21x_admin.php_options_groups_emailOptions_ (1).webp

You could just process these emails manually if you want to. But there has to be a better way!

localhost_21x_admin.php_options_groups_emailOptions_ (2).webp

If you have ever configured automated bounce email handling, this will seem familiar to you. To process unsubscribe requests automatically, you will need to create a new mailbox specifically for that purpose and ensure it is accessible through either a POP3 or IMAP connection. Once you populate these fields with the relevant login information, XF will periodically log in to that mailbox for you, read any emails that have been sent there, and disable the "Receive news and updates emails" preference for the users who requested to be unsubscribed.
 
New authentication configuration

Now we have finally said goodbye to PHP 5.4 we can begin to improve even further our tools used to create and verify password hashes. Since XF 2.0 we have already attempted to use the following functions which were added in PHP 5.5 if they were available:
Now everyone will be running PHP 5.6 as a minimum, we can solely use these native PHP functions for all our password hashing needs.

Since XF 1.2 we have used Bcrypt for our password hashes, this was before it was even natively supported by PHP and even today it remains to be the default hashing algorithm for even PHP 7.2 and 7.3.

But, over time, PHP will add additional hashing methods, and it would be ideal if we could just support them out of the box without us having to make any code changes. The aforementioned functions serve as a consistent interface and therefore get us part of the way there towards being that flexible, but until now there wasn't actually a straightforward way to use a different algorithm if one was available, or support a more granular configuration.

However, PHP actually has implemented (technically) two new password hashing algorithms based around Argon2. This was first introduced in PHP 7.2 using a variant known as Argon2i and it is further improved in PHP 7.3 using a variant known as Argon2id.

By default, XF will always aim to use the default or most widely supported password hashing algorithm available, so in this case that is still Bcrypt. But should you have an appropriate PHP version and the required prerequisites installed (PHP has to be compiled explicitly with Argon2 support) then we should allow you to use that, so in XF 2.1, now you can. And it's as simple as a couple of additional lines in src/config.php.

The following will enable Argon2i support if you're using PHP 7.2:
PHP:
$config['auth'] = [
   'algo' => PASSWORD_ARGON2I
];

The following will enable Argon2id support if you're using PHP 7.3:
PHP:
$config['auth'] = [
   'algo' => PASSWORD_ARGON2ID
];

And, although not required because the PHP defaults should be sufficient (and will potentially increase over time), you can even make your password hashes even more secure by passing in additional parameters to control various cost factors:
PHP:
$config['auth'] = [
   'algo' => PASSWORD_ARGON2ID,
   'options' => [
      'memory_cost' => 1<<17,
      'time_cost' => 4,
      'threads' => 2
   ]
];

Thanks to the flexibility of the password hashing API in PHP, any changes to the algorithm and options will automatically cause existing passwords to be rehashed when a user logs in.

Although we'd highly recommend using the latest PHP version we support, and also recommend using Argon2i/id hashing where available, you do have to plan carefully should you ever need to downgrade PHP or move to a different server. If Argon2 suddenly becomes unavailable for any reason, then you will likely encounter errors and be unable to verify any passwords without doing a password reset first.
 
Show password field when logging in

There is nothing quite so frustrating as that feeling you get when you've typed your password and you just know you somehow hit an extra key somewhere. You know the password will fail, but you can't check the password because it's obfuscated. You just have to start again.

localhost_21x_index.php (18).webp

I'm sure I made a mistake when typing out my super secure password... 🤔
Fairly self explanatory :) In XF 2.1 you simply click the "Show" button, to reveal the password:

localhost_21x_index.php (19).webp

I knew it! Damn you, fat fingers! 😡
Just make sure no one is watching over your shoulder 😉
 
Password strength checking with zxcvbn

Over the years there has been some desire for us to implement password complexity requirements but, fundamentally, they do not tend to work. They serve as an incredibly frustrating experience and when combined with automatic password expiry it just leads to using the same password over and over with a different number on the end :rolleyes:

In an ideal world, people would all be using password managers such as 1Password or LastPass, but in reality people are still picking (frankly) rubbish passwords in order to make them easier to remember. You might be familiar with the following comic:

password_strength.png

More than anything, simply educating users is the best approach. Most people genuinely have no idea what constitutes a good or strong password, and often they do not think about it.

The above comic pretty much inspired Dropbox to take on the challenge of coming up with a better way of estimating password complexity, and they came up with zxcvbn which we have now implemented in XF 2.1. Whenever a user is faced with an option to choose a new password, they will see this:

localhost_21x_index.php_account_security.webp

As well as a visual indication of the password strength, it also provides a description of why the password you have chosen isn't great:

localhost_21x_index.php_account_security (1).webp

All in the hope that, one day, they will see sense and use something strong, but easy to remember, like my favourite password:

localhost_21x_index.php_account_security (2).webp
 
New two-step verification provider: Authy OneTouch

Wait, did I just reveal my own password? Even if I did, it doesn't matter. I use two-step verification! As good as it is, though, sometimes the process can feel a little long winded. However, with XF 2.1 it is now possible to enable Authy OneTouch support on your forum which enables a push notification to be sent to your Authy app for login approval. Here it is in action:

authyonetouch.gif

To enable this, you first need to sign up for a Twilio account and create the necessary application and get an API key. This key can be entered into a new UI we've added for viewing two step verification providers.

localhost_21x_admin.php_two-step_.webp

Although there isn't a lot that can be done here for most providers, it does provide a new and consistent UI for developers to add more advanced options for custom two-step verification providers going forward.

Once the Authy provider has been configured, users can start setting it up. If they don't yet have the Authy app on their phones, they will be sent a link to it in the on-boarding process.

From the user perspective, the on-boarding process consists of providing a mobile/cell phone number so they can receive a verification code by SMS text message.

Before configuring Authy it may be worth checking out their pricing as they only have a fairly limited free tier. Subsequent push authentications are then charged at $0.09 each which could be a significant amount for some communities. That said, depending on your audience you may have fewer people actively using two step verification, and of those they are likely to only need to authenticate once every ~30 days.
 
Re-ordering custom field choices

In XF 2.1 we've added the ability to re-order custom field choices very simply by using drag and drop:

field_order.gif

For developers, if you wished to implement your own simple draggable lists in your own add-ons then we've made this simple to do with our new sort.js and XF.ListSorter class. For advanced use cases you may wish to use nestable.js or roll something more custom, but for simple cases as demonstrated above, it should be fairly useful.
 
But, check back here later this week for something special to accompany our final HYS which includes no-fewer than seven new features/changes (of the slightly smaller/miscellaneous/wouldn't fit anywhere else variety) ;)
Famous last words :rolleyes: It looks like we turned it up to 11, instead ;)

But enough talking about XF 2.1 features! Now go out there and break them all, so we can fix them all, so we can release XF 2.1 and then we can start working on XF 2.2 already! :D

Thanks to everyone for their support and we hope you enjoy XF 2.1 :)
 
Top Bottom