Skip to content

Make "status" session values more consistent and easily translatable #341

Closed
@alexandercrice

Description

@alexandercrice

Complaint

Currently Fortify flashes text values like "two-factor-authentication-enabled" to the session under the key "status". The Fortify documentation page suggests handling these status values, by checking for these values with an if-statement, and then displaying a suitable message.
image
https://laravel.com/docs/8.x/fortify#enabling-two-factor-authentication

It would be nice if it were easier to convert the original value to a human-friendly message using the trans() (translate) function. That way, if the message is displayed using some kind of general/global component, it can simply display the translated value rather than having to implement some kind of case statement.

Fortify is also inconsistent about the kind of status value used. In places where Fortify makes use of statuses returned from the Laravel Framework (which are formatted in an easily translatable dotted format, e.g., "passwords.throttled"), Fortify calls trans() on these values before saving them to the session. However, in places where Fortify implements it's own status values, it uses hyphenated strings, like "two-factor-authentication-enabled" and does not call trans() on them. Why this inconsistency? If Fortify translates the Laravel Framework's status values, Fortify should translate its own status values too.

Since Fortify's current status values are not dotted, it is also more difficult to translate them than if they were dotted. My understanding is that unless the value-to-be-translated contains a dot, it is necessary to translate them with a ".json" file, taking away the option of using PHP translation files. In order to use PHP translation files, there needs to be (at least) two segments separated by a dot, with the first segment giving the PHP translation file to use. E.g., the string value "fortify.two-factor-authentication-enabled" indicates to the trans() function that it should return the value at the array key "two-factor-authentication-enabled" in the array returned by the fortify.php translation file. If one prefers JSON translation files, the option still remains to define a translation in a JSON file at the key "fortify.two-factor-authentication-enabled".

Example

Compare how Fortify handles the status message in the Laravel\Fortify\Http\Controllers\TwoFactorAuthenticationController::store method

image

versus how the status message is handled in Laravel\Fortify\Http\Responses\PasswordResetResponse.
image

For examples of the dotted format, see the Laravel Framework's Illuminate\Contracts\Auth\PasswordBroker interface.
image

Which are handled in a passwords.php translation file.
image

Proposed Solution

Simply replacing the status values that Fortify uses with new values would break existing applications.

Instead, the change could be implemented in a non-breaking way by adding an (optionally present) variable in the fortify.php configuration file. By default, Fortify would continue to use the same status values as the current ones. However, changing this new configuration variable would cause Fortify to use different status values, following the pattern set by the Laravel Framework.

image

Then the places in the code could be updated to return one of two different values, depending on the value of this configuration variable. So, for example,

return $request->wantsJson()
                    ? new JsonResponse('', 200)
                    : back()->with('status', 'two-factor-authentication-enabled');

could become

return $request->wantsJson()
                    ? new JsonResponse('', 200)
                    : back()->with('status', config('fortify.use-more-easily-translatable-status-values', false) ? 'two-factor-authentication-enabled' : 'fortify.two-factor-authentication-enabled');

And, as stated above, Fortify should apply the trans() function for sake of consistency.

return $request->wantsJson()
                    ? new JsonResponse('', 200)
                    : back()->with('status', trans(config('fortify.use-more-easily-translatable-status-values', false) ? 'two-factor-authentication-enabled' : 'fortify.two-factor-authentication-enabled'));

It would would also be beneficial for Fortify to provide its own translation file. Besides serving as a model for consumers of the Fortify package who would like to define their own translations, it would also serve as documentation of Fortify's status values. Currently there is no good reference that lists these values together in one place. One must read through the Fortify page on the Laravel website to find the value used on a feature-by-feature basis, or open the source code to find the response and controller classes for a particular feature.

The translation file could even just map the value to itself.

return [
    'two-factor-authentication-enabled' => 'two-factor-authentication-enabled',
    // ...
];

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions