Przeglądaj źródła

Fix user preferences not being applied correctly after sign-in

Bubka 2 lat temu
rodzic
commit
f359a1ade3

+ 4 - 3
app/Http/Controllers/Auth/LoginController.php

@@ -94,8 +94,9 @@ class LoginController extends Controller
         $this->authenticated($request, $this->guard()->user());
 
         return response()->json([
-            'message' => 'authenticated',
-            'name'    => $name,
+            'message'     => 'authenticated',
+            'name'        => $name,
+            'preferences' => $this->guard()->user()->preferences,
         ], Response::HTTP_OK);
     }
 
@@ -107,7 +108,7 @@ class LoginController extends Controller
      */
     protected function sendFailedLoginResponse(Request $request)
     {
-        return response()->json(['message' => 'unauthorised'], Response::HTTP_UNAUTHORIZED);
+        return response()->json(['message' => 'unauthorized'], Response::HTTP_UNAUTHORIZED);
     }
 
     /**

+ 9 - 1
app/Http/Controllers/Auth/WebAuthnLoginController.php

@@ -7,6 +7,7 @@ use App\Models\User;
 use Carbon\Carbon;
 use Illuminate\Contracts\Support\Responsable;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Response;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\Log;
 use Laragear\WebAuthn\Http\Requests\AssertedRequest;
@@ -73,12 +74,19 @@ class WebAuthnLoginController extends Controller
             }
         }
 
+        /**
+         * @var \App\Models\User|null
+         */
         $user = $request->login();
 
         if ($user) {
             $this->authenticated($user);
 
-            return response()->noContent();
+            return response()->json([
+                'message'     => 'authenticated',
+                'name'        => $user->name,
+                'preferences' => $user->preferences,
+            ], Response::HTTP_OK);
         }
 
         return response()->noContent(422);

+ 19 - 9
app/Http/Controllers/SinglePageController.php

@@ -18,21 +18,31 @@ class SinglePageController extends Controller
     {
         event(new ScanForNewReleaseCalled());
 
-        $subdir = config('2fauth.config.appSubdirectory') ? '/' . config('2fauth.config.appSubdirectory') : '';
+        $settings        = Settings::all()->toJson();
+        $proxyAuth       = config('auth.defaults.guard') === 'reverse-proxy-guard' ? true : false;
+        $proxyLogoutUrl  = config('2fauth.config.proxyLogoutUrl') ? config('2fauth.config.proxyLogoutUrl') : false;
+        $subdir          = config('2fauth.config.appSubdirectory') ? '/' . config('2fauth.config.appSubdirectory') : '';
+        $userPreferences = Auth::user()->preferences ?? collect(config('2fauth.preferences')); /** @phpstan-ignore-line */
+        $isDemoApp       = config('2fauth.config.isDemoApp') ? 'true' : 'false';
+        $isTestingApp    = config('2fauth.config.isTestingApp') ? 'true' : 'false';
+        $lang            = App::getLocale();
+        $locales         = collect(config('2fauth.locales'))->toJson(); /** @phpstan-ignore-line */
+
+        // if (Auth::user()->preferences)
 
         return view('landing')->with([
-            'appSettings' => Settings::all()->toJson(),
+            'appSettings' => $settings,
             'appConfig'   => collect([
-                'proxyAuth'      => config('auth.defaults.guard') === 'reverse-proxy-guard' ? true : false,
-                'proxyLogoutUrl' => config('2fauth.config.proxyLogoutUrl') ? config('2fauth.config.proxyLogoutUrl') : false,
+                'proxyAuth'      => $proxyAuth,
+                'proxyLogoutUrl' => $proxyLogoutUrl,
                 'subdirectory'   => $subdir,
             ])->toJson(),
-            'userPreferences' => Auth::user()->preferences ?? collect(config('2fauth.preferences')),
+            'userPreferences' => $userPreferences,
             'subdirectory'    => $subdir,
-            'isDemoApp'       => config('2fauth.config.isDemoApp') ? 'true' : 'false',
-            'isTestingApp'    => config('2fauth.config.isTestingApp') ? 'true' : 'false',
-            'lang'            => App::getLocale(),
-            'locales'         => collect(config('2fauth.locales'))->toJson(), /** @phpstan-ignore-line */
+            'isDemoApp'       => $isDemoApp,
+            'isTestingApp'    => $isTestingApp,
+            'lang'            => $lang,
+            'locales'         => $locales,
         ]);
     }
 }

+ 4 - 1
app/Http/Kernel.php

@@ -23,7 +23,6 @@ class Kernel extends HttpKernel
         \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
         \App\Http\Middleware\TrimStrings::class,
         \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
-        \App\Http\Middleware\SetLanguage::class,
         \App\Http\Middleware\ForceJsonResponse::class,
     ];
 
@@ -40,6 +39,7 @@ class Kernel extends HttpKernel
             // \Illuminate\Session\Middleware\AuthenticateSession::class,
             \App\Http\Middleware\VerifyCsrfToken::class,
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
+            \App\Http\Middleware\SetLanguage::class,
             \App\Http\Middleware\CustomCreateFreshApiToken::class,
         ],
 
@@ -52,6 +52,7 @@ class Kernel extends HttpKernel
             \App\Http\Middleware\Authenticate::class,
             \App\Http\Middleware\LogUserLastSeen::class,
             \App\Http\Middleware\KickOutInactiveUser::class,
+            \App\Http\Middleware\SetLanguage::class,
             \App\Http\Middleware\CustomCreateFreshApiToken::class,
         ],
 
@@ -60,6 +61,7 @@ class Kernel extends HttpKernel
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
             \App\Http\Middleware\KickOutInactiveUser::class,
             \App\Http\Middleware\LogUserLastSeen::class,
+            \App\Http\Middleware\SetLanguage::class,
         ],
     ];
 
@@ -94,6 +96,7 @@ class Kernel extends HttpKernel
         \Illuminate\Session\Middleware\StartSession::class,
         \Illuminate\View\Middleware\ShareErrorsFromSession::class,
         \App\Http\Middleware\Authenticate::class,
+        \App\Http\Middleware\SetLanguage::class,
         \Illuminate\Session\Middleware\AuthenticateSession::class,
         \Illuminate\Routing\Middleware\SubstituteBindings::class,
         \Illuminate\Auth\Middleware\Authorize::class,

+ 2 - 2
app/Http/Middleware/Authenticate.php

@@ -36,9 +36,9 @@ class Authenticate extends Middleware
 
                 // We now have an authenticated user so we override the locale already set
                 // by the SetLanguage global middleware
-                $lang = $this->auth->guard()->user()->preferences['lang'] ?? null;
+                $lang = $this->auth->guard()->user()->preferences['lang'];
 
-                if ($lang && in_array($lang, config('2fauth.locales')) && ! App::isLocale($lang)) {
+                if (in_array($lang, config('2fauth.locales')) && ! App::isLocale($lang)) {
                     App::setLocale($lang);
                 }
 

+ 9 - 3
app/Http/Middleware/SetLanguage.php

@@ -17,11 +17,12 @@ class SetLanguage
      */
     public function handle($request, Closure $next)
     {
-        // 2 possible cases here:
+        // 3 possible cases here:
         // - The http client send an accept-language header
-        // - No language is specified
+        // - There is an authenticated user with a possible language set
+        // - No language is specified at all
         //
-        // We honor the language requested in the header or we use the fallback one.
+        // Priority to the user preference, then the header request, otherwise the fallback language.
         // Note that if a user is authenticated later by the auth guard, the app locale
         // will be overriden if the user has set a specific language in its preferences.
 
@@ -57,6 +58,11 @@ class SetLanguage
             }
         }
 
+        $user = $request->user();
+        if (! is_null($user) && $request->user()->preferences['lang'] != 'browser') {
+            $lang = $request->user()->preferences['lang'];
+        }
+
         // If the language is not available (or partial), strings will be translated using the fallback language.
         App::setLocale($lang);
 

+ 3 - 2
app/Http/Middleware/SkipIfAuthenticated.php

@@ -22,11 +22,12 @@ class SkipIfAuthenticated
 
         foreach ($guards as $guard) {
             if (Auth::guard($guard)->check()) {
-                $user = Auth::guard($guard)->user()->name;
+                $user = Auth::guard($guard)->user();
 
                 return response()->json([
                     'message' => 'authenticated',
-                    'name'    => $user,
+                    'name'    => $user->name,
+                    'preferences' => $user->preferences,
                 ], 200);
             }
         }

+ 18 - 1
resources/js/mixins.js

@@ -1,4 +1,5 @@
 import Vue from 'vue'
+import i18n from './langs/i18n'
 
 Vue.mixin({
 
@@ -100,7 +101,23 @@ Vue.mixin({
 
         setTheme(theme) {
             document.documentElement.dataset.theme = theme;
-        }
+        },
+
+        applyPreferences(preferences) {
+            for (const preference in preferences) {
+                try {
+                    this.$root.userPreferences[preference] = preferences[preference]
+                 }
+                 catch (e) {
+                    console.log(e)
+                 }
+            }
+
+            if (this.$root.userPreferences.lang != 'browser') {
+                i18n.locale = this.$root.userPreferences.lang
+                document.documentElement.lang = this.$root.userPreferences.lang
+            }
+        },
     }
 
 })

+ 2 - 0
resources/js/views/auth/Login.vue

@@ -72,6 +72,7 @@
 
                 this.form.post('/user/login', {returnError: true})
                 .then(response => {
+                    this.applyPreferences(response.data.preferences);
                     this.$router.push({ name: 'accounts', params: { toRefresh: true } })
                 })
                 .catch(error => {
@@ -131,6 +132,7 @@
                 const publicKeyCredential = this.webauthn.parseOutgoingCredentials(credentials)
 
                 this.axios.post('/webauthn/login', publicKeyCredential, {returnError: true}).then(response => {
+                    this.applyPreferences(response.data.preferences);
                     this.$router.push({ name: 'accounts', params: { toRefresh: true } })
                 })
                 .catch(error => {