瀏覽代碼

All hardcoded strings replaced by i18n translation

Bubka 5 年之前
父節點
當前提交
11c7ff20a6

+ 4 - 16
app/Http/Controllers/IconController.php

@@ -19,29 +19,17 @@ class IconController extends Controller
      */
     public function upload(Request $request)
     {
-        $messages = [
-            'icon.image' => 'Supported format are jpeg, png, bmp, gif, svg, or webp'
-        ];
-
         $validator = Validator::make($request->all(), [
             'icon' => 'required|image',
-        ], $messages);
+        ]);
 
         if ($validator->fails()) {
             return response()->json(['error' => $validator->errors()], 400);
         }
+        
+        $path = $request->file('icon')->storePublicly('public/icons');
 
-
-        // if($request->hasFile('icon')){
-
-            $path = $request->file('icon')->storePublicly('public/icons');
-
-            return response()->json(pathinfo($path)['basename'], 201);
-        // }
-        // else
-        // {
-        //     return response()->json('no file in $request', 204);
-        // }
+        return response()->json(pathinfo($path)['basename'], 201);
     }
 
 

+ 2 - 7
app/Http/Controllers/QrCodeController.php

@@ -23,19 +23,14 @@ class QrCodecontroller extends Controller
     {
 
         // input validation
-        $messages = [
-            'qrcode.image' => 'Supported format are jpeg, png, bmp, gif, svg, or webp'
-        ];
-
         $validator = Validator::make($request->all(), [
             'qrcode' => 'required|image',
-        ], $messages);
+        ]);
 
         if ($validator->fails()) {
             return response()->json(['error' => $validator->errors()], 400);
         }
 
-
         // qrcode analysis
         $path = $request->file('qrcode')->store('qrcodes');
         $qrcode = new QrReader(storage_path('app/' . $path));
@@ -71,7 +66,7 @@ class QrCodecontroller extends Controller
 
             return response()->json([
                 'error' => [
-                   'qrcode' => 'No valid TOTP resource in this QR code'
+                   'qrcode' => __('errors.response.no_valid_totp')
                 ]
             ], 400);
 

+ 4 - 7
app/Http/Controllers/TwoFAccountController.php

@@ -33,14 +33,11 @@ class TwoFAccountController extends Controller
 
         // see https://github.com/google/google-authenticator/wiki/Key-Uri-Format
         // for otpauth uri format validation
-        $messages = [
-            'uri.starts_with' => 'Only valid TOTP uri are supported',
-        ];
 
         $validator = Validator::make($request->all(), [
             'service' => 'required',
             'uri' => 'required|starts_with:otpauth://totp/',
-        ], $messages);
+        ]);
 
         if ($validator->fails()) {
             return response()->json(['error' => $validator->errors()], 400);
@@ -69,7 +66,7 @@ class TwoFAccountController extends Controller
             $twofaccount = TwoFAccount::FindOrFail($id);
             return response()->json($twofaccount, 200);
         } catch (\Exception $e) {
-            return response()->json(['error'=>'not found'], 404);
+            return response()->json( ['error' => 'not found' ], 404);
         }
     }
 
@@ -103,7 +100,7 @@ class TwoFAccountController extends Controller
         ]);
 
         if ($validator->fails()) {
-            return response()->json(['error' => $validator->errors()], 400);
+            return response()->json( ['error' => $validator->errors() ], 400);
         }
 
 
@@ -117,7 +114,7 @@ class TwoFAccountController extends Controller
         }
         catch (\Exception $e) {
 
-            return response()->json(['error'=>'not found'], 404);
+            return response()->json( ['error' => 'not found' ] , 404);
 
         }
     }

+ 1 - 6
app/Http/Controllers/UserController.php

@@ -17,15 +17,10 @@ class UserController extends Controller
      */
     public function login(Request $request)
     {
-
-        $messages = [
-            'email.exists' => 'No account found using this email',
-        ];
-
         $validator = Validator::make($request->all(), [
             'email' => 'required|exists:users,email',
             'password' => 'required',
-        ], $messages);
+        ]);
 
         if ($validator->fails()) {
             return response()->json(['error' => $validator->errors()], 400);

+ 11 - 11
resources/js/views/Accounts.vue

@@ -5,7 +5,7 @@
                 <div class="column is-three-quarters-mobile is-one-third-tablet is-one-quarter-desktop is-one-quarter-widescreen is-one-quarter-fullhd">
                     <div class="field">
                         <div class="control has-icons-right">
-                            <input type="text" class="input is-rounded is-search" v-model="search" placeholder="">
+                            <input type="text" class="input is-rounded is-search" v-model="search">
                             <span class="icon is-small is-right">
                                 <font-awesome-icon :icon="['fas', 'search']"  v-if="!search" />
                                 <a class="delete" v-if="search" @click="search = '' "></a>
@@ -35,9 +35,9 @@
         <div class="container has-text-centered" v-show="this.showNoAccount">
             <p class="no-account"></p>
             <p class="subtitle is-5 has-text-grey">
-                No 2FA here!
+                {{ $t('twofaccounts.no_account_here') }}
             </p>
-            <router-link :to="{ name: 'create' }" class="button is-medium is-link is-focused">Add one</router-link>
+            <router-link :to="{ name: 'create' }" class="button is-medium is-link is-focused">{{ $t('twofaccounts.add_one') }}</router-link>
         </div>
         <modal v-model="ShowTwofaccountInModal">
             <twofaccount-show
@@ -54,16 +54,16 @@
                     <div class="field is-grouped">
                         <p class="control">
                             <router-link :to="{ name: 'create' }" class="button is-link is-rounded is-focus">
-                                <span>New</span>
+                                <span>{{ $t('twofaccounts.new') }}</span>
                                 <span class="icon is-small">
                                     <font-awesome-icon :icon="['fas', 'qrcode']" />
                                 </span>
                             </router-link>
                         </p>
                         <p class="control">
-                            <a class="button is-dark is-rounded" @click="editMode = true" v-if="!editMode">Manage</a>
+                            <a class="button is-dark is-rounded" @click="editMode = true" v-if="!editMode">{{ $t('twofaccounts.manage') }}</a>
                             <a class="button is-success is-rounded" @click="editMode = false" v-if="editMode">
-                                <span>Done</span>
+                                <span>{{ $t('twofaccounts.done') }}</span>
                                 <span class="icon is-small">
                                     <font-awesome-icon :icon="['fas', 'check']" />
                                 </span>
@@ -74,14 +74,14 @@
             </div>
             <div class="content has-text-centered">
                 <span v-if="token">
-                    Hi {{username}} ! <a class="has-text-grey" @click="logout">Sign out</a>
+                    {{ $t('auth.hello', {username: username}) }} <a class="has-text-grey" @click="logout">{{ $t('auth.sign_out') }}</a>
                 </span>
                 <span v-else>
                     <router-link :to="{ name: 'login' }" class="button is-black">
-                        Sign in
+                        {{ $t('auth.sign_in') }}
                     </router-link>
                     <router-link :to="{ name: 'register' }" class="button is-black">
-                        Register
+                        {{ $t('auth.register') }}
                     </router-link>
                 </span>
             </div>
@@ -189,7 +189,7 @@
             },
 
             deleteAccount:  function (id) {
-                if(confirm("Are you sure you want to delete this account?")) {
+                if(confirm(this.$t('twofaccounts.confirm.delete'))) {
 
                     axios.defaults.headers.common['Content-Type'] = 'application/json'
                     axios.defaults.headers.common['Authorization'] = 'Bearer ' + this.token
@@ -204,7 +204,7 @@
             },
 
             logout(evt) {
-                if(confirm("Are you sure you want to log out?")) {
+                if(confirm(this.$t('auth.confirm.logout'))) {
                     axios.post('api/logout').then(response => {
 
                         localStorage.removeItem('jwt');

+ 14 - 14
resources/js/views/Create.vue

@@ -2,52 +2,52 @@
     <div class="section">
         <div class="columns is-mobile is-centered">
             <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen is-one-quarter-fullhd">
-                <h1 class="title">New account</h1>
+                <h1 class="title">{{ $t('twofaccounts.forms.new_account') }}</h1>
                 <form @submit.prevent="createAccount">
                     <div class="field">
                         <div class="file is-dark is-boxed">
-                            <label class="file-label" title="Use a QR code to fill the form magically">
+                            <label class="file-label" :title="$t('twofaccounts.forms.use_qrcode.title')">
                                 <input class="file-input" type="file" accept="image/*" v-on:change="uploadQrcode" ref="qrcodeInput">
                                 <span class="file-cta">
                                     <span class="file-icon">
                                         <font-awesome-icon :icon="['fas', 'qrcode']" size="lg" />
                                     </span>
-                                    <span class="file-label">Use a qrcode</span>
+                                    <span class="file-label">{{ $t('twofaccounts.forms.use_qrcode.val') }}</span>
                                 </span>
                             </label>
                         </div>
                     </div>
                     <p class="help is-danger help-for-file" v-if="errors.qrcode">{{ errors.qrcode.toString() }}</p>
                     <div class="field">
-                        <label class="label">Service</label>
+                        <label class="label">{{ $t('twofaccounts.service') }}</label>
                         <div class="control">
-                            <input class="input" type="text" placeholder="example.com" v-model="twofaccount.service"  autofocus />
+                            <input class="input" type="text" :placeholder="$t('twofaccounts.forms.service.placeholder')" v-model="twofaccount.service"  autofocus />
                         </div>
                         <p class="help is-danger" v-if="errors.service">{{ errors.service.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Account</label>
+                        <label class="label">{{ $t('twofaccounts.account') }}</label>
                         <div class="control">
-                            <input class="input" type="text" placeholder="John DOE" v-model="twofaccount.account"  />
+                            <input class="input" type="text" :placeholder="$t('twofaccounts.forms.account.placeholder')" v-model="twofaccount.account"  />
                         </div>
                         <p class="help is-danger" v-if="errors.account">{{ errors.account.toString() }}</p>
                     </div>
                     <div class="field" style="margin-bottom: 0.5rem;">
-                        <label class="label">TOTP Uri</label>
+                        <label class="label">{{ $t('twofaccounts.forms.totp_uri') }}</label>
                     </div>
                     <div class="field has-addons">
                         <div class="control is-expanded">
                             <input class="input" type="text" placeholder="otpauth://totp/..." v-model="twofaccount.uri" :disabled="uriIsLocked" />
                         </div>
                         <div class="control" v-if="uriIsLocked">
-                            <a class="button is-dark field-lock" @click="uriIsLocked = false" title="Unlock it (at your own risk)">
+                            <a class="button is-dark field-lock" @click="uriIsLocked = false" :title="$t('twofaccounts.forms.unlock.title')">
                                 <span class="icon">
                                     <font-awesome-icon :icon="['fas', 'lock']" />
                                 </span>
                             </a>
                         </div>
                         <div class="control" v-else>
-                            <a class="button is-dark field-unlock"  @click="uriIsLocked = true" title="Lock it">
+                            <a class="button is-dark field-unlock"  @click="uriIsLocked = true" :title="$t('twofaccounts.forms.lock.title')">
                                 <span class="icon has-text-danger">
                                     <font-awesome-icon :icon="['fas', 'lock-open']" />
                                 </span>
@@ -56,7 +56,7 @@
                     </div>
                     <p class="help is-danger help-for-file" v-if="errors.uri">{{ errors.uri.toString() }}</p>
                     <div class="field">
-                        <label class="label">Icon</label>
+                        <label class="label">{{ $t('twofaccounts.icon') }}</label>
                         <div class="file is-dark">
                             <label class="file-label">
                                 <input class="file-input" type="file" accept="image/*" v-on:change="uploadIcon" ref="iconInput">
@@ -64,7 +64,7 @@
                                     <span class="file-icon">
                                         <font-awesome-icon :icon="['fas', 'image']" />
                                     </span>
-                                    <span class="file-label">Choose an image…</span>
+                                    <span class="file-label">{{ $t('twofaccounts.forms.choose_image') }}</span>
                                 </span>
                             </label>
                             <span class="tag is-black is-large" v-if="tempIcon">
@@ -76,10 +76,10 @@
                     <p class="help is-danger help-for-file" v-if="errors.icon">{{ errors.icon.toString() }}</p>
                     <div class="field is-grouped">
                         <div class="control">
-                            <button type="submit" class="button is-link">Create</button>
+                            <button type="submit" class="button is-link">{{ $t('twofaccounts.forms.create') }}</button>
                         </div>
                         <div class="control">
-                            <button class="button is-text" @click="cancelCreation">Cancel</button>
+                            <button class="button is-text" @click="cancelCreation">{{ $t('commons.cancel') }}</button>
                         </div>
                     </div>
                 </form>

+ 9 - 9
resources/js/views/Edit.vue

@@ -2,24 +2,24 @@
     <div class="section" v-if="twofaccountExists">
         <div class="columns is-mobile is-centered">
             <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen is-one-quarter-fullhd">
-                <h1 class="title">Edit account</h1>
+                <h1 class="title">{{ $t('twofaccounts.forms.edit_account') }}</h1>
                 <form @submit.prevent="updateAccount">
                     <div class="field">
-                        <label class="label">Service</label>
+                        <label class="label">{{ $t('twofaccounts.service') }}</label>
                         <div class="control">
-                            <input class="input" type="text" placeholder="example.com" v-model="twofaccount.service" autofocus />
+                            <input class="input" type="text" :placeholder="$t('twofaccounts.forms.service.placeholder')" v-model="twofaccount.service" autofocus />
                         </div>
                         <p class="help is-danger" v-if="errors.service">{{ errors.service.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Account</label>
+                        <label class="label">{{ $t('twofaccounts.account') }}</label>
                         <div class="control">
-                            <input class="input" type="text" placeholder="John DOE" v-model="twofaccount.account" />
+                            <input class="input" type="text" :placeholder="$t('twofaccounts.forms.account.placeholder')" v-model="twofaccount.account" />
                         </div>
                         <p class="help is-danger" v-if="errors.account">{{ errors.account.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Icon</label>
+                        <label class="label">{{ $t('twofaccounts.icon') }}</label>
                         <div class="file is-dark">
                             <label class="file-label">
                                 <input class="file-input" type="file" accept="image/*" v-on:change="uploadIcon" ref="iconInput">
@@ -27,7 +27,7 @@
                                     <span class="file-icon">
                                         <font-awesome-icon :icon="['fas', 'image']" />
                                     </span>
-                                    <span class="file-label">Choose an image…</span>
+                                    <span class="file-label">{{ $t('twofaccounts.forms.choose_image') }}</span>
                                 </span>
                             </label>
                             <span class="tag is-black is-large" v-if="tempIcon">
@@ -39,10 +39,10 @@
                     <p class="help is-danger help-for-file" v-if="errors.icon">{{ errors.icon.toString() }}</p>
                     <div class="field is-grouped">
                         <div class="control">
-                            <button type="submit" class="button is-link">Save</button>
+                            <button type="submit" class="button is-link">{{ $t('twofaccounts.forms.save') }}</button>
                         </div>
                         <div class="control">
-                            <button class="button is-text" @click.prevent="cancelCreation">Cancel</button>
+                            <button class="button is-text" @click.prevent="cancelCreation">{{ $t('commons.cancel') }}</button>
                         </div>
                     </div>
                 </form>

+ 2 - 2
resources/js/views/Error.vue

@@ -3,11 +3,11 @@
         <modal v-model="ShowModal">
             <div v-if="$route.name == '404'">
                 <p class="error-404"></p>
-                <p>Resource not found, please <router-link :to="{ name: 'accounts' }" class="is-text has-text-white">refresh</router-link></p>
+                <p>{{ $t('errors.resource_not_found') }}<router-link :to="{ name: 'accounts' }" class="is-text has-text-white">{{ $t('errors.refresh') }}</router-link></p>
             </div>
             <div v-else>
                 <p class="error-generic"></p>
-                <p>An error occured, please <router-link :to="{ name: 'accounts' }" class="is-text has-text-white">refresh</router-link></p>
+                <p>{{ $t('errors.error_occured') }}<router-link :to="{ name: 'accounts' }" class="is-text has-text-white">{{ $t('errors.refresh') }}</router-link></p>
             </div>
             <div v-if="debugMode == 'development'">
                 <p v-if="debug" class="debug">

+ 7 - 7
resources/js/views/Login.vue

@@ -2,17 +2,17 @@
     <div class="section">
         <div class="columns is-mobile  is-centered">
             <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen is-one-quarter-fullhd">
-                <h1 class="title">Login</h1>
+                <h1 class="title">{{ $t('auth.forms.login') }}</h1>
                 <form method="POST" action="/login">
                     <div class="field">
-                        <label class="label">Email</label>
+                        <label class="label">{{ $t('auth.forms.email') }}</label>
                         <div class="control">
                             <input id="email" type="email" class="input" v-model="email" required autofocus />
                         </div>
                         <p class="help is-danger" v-if="errors.email">{{ errors.email.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Password</label>
+                        <label class="label">{{ $t('auth.forms.password') }}</label>
                         <div class="control">
                             <input id="password" type="password" class="input" v-model="password" required />
                         </div>
@@ -20,7 +20,7 @@
                     </div>
                     <div class="field">
                         <div class="control">
-                            <button type="submit" class="button is-link" @click="handleSubmit">Sign in</button>
+                            <button type="submit" class="button is-link" @click="handleSubmit">{{ $t('auth.sign_in') }}</button>
                         </div>
                     </div>
                 </form>
@@ -28,8 +28,8 @@
         </div>
         <div class="columns is-mobile is-centered">
             <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen is-one-quarter-fullhd">
-                Don't have an account yet? <router-link :to="{ name: 'register' }" class="is-link">
-                    Register
+                {{ $t('auth.forms.dont_have_account_yet') }}&nbsp;<router-link :to="{ name: 'register' }" class="is-link">
+                    {{ $t('auth.register') }}
                 </router-link>
             </div>
         </div>
@@ -66,7 +66,7 @@
                         this.errors = error.response.data.error
                     }
                     else {
-                        this.errors['password'] = [ 'Password do not match' ]
+                        this.errors['password'] = [ this.$t('auth.forms.passwords_do_not_match') ]
                     }
                 });
             }

+ 8 - 8
resources/js/views/Register.vue

@@ -2,31 +2,31 @@
     <div class="section">
         <div class="columns is-mobile  is-centered">
             <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen is-one-quarter-fullhd">
-                <h1 class="title">Register</h1>
+                <h1 class="title">{{ $t('auth.register') }}</h1>
                 <form method="POST" action="/register">
                     <div class="field">
-                        <label class="label">Name</label>
+                        <label class="label">{{ $t('auth.forms.name') }}</label>
                         <div class="control">
                             <input id="name" type="text" class="input" v-model="name" required autofocus />
                         </div>
                         <p class="help is-danger" v-if="errors.name">{{ errors.name.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Email</label>
+                        <label class="label">{{ $t('auth.forms.email') }}</label>
                         <div class="control">
                             <input id="email" type="email" class="input" v-model="email" required />
                         </div>
                         <p class="help is-danger" v-if="errors.email">{{ errors.email.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Password</label>
+                        <label class="label">{{ $t('auth.forms.password') }}</label>
                         <div class="control">
                             <input id="password" type="password" class="input" v-model="password" required />
                         </div>
                         <p class="help is-danger" v-if="errors.password">{{ errors.password.toString() }}</p>
                     </div>
                     <div class="field">
-                        <label class="label">Confirm Password</label>
+                        <label class="label">{{ $t('auth.forms.confirm_password') }}</label>
                         <div class="control">
                             <input id="password_confirmation" type="password" class="input" v-model="password_confirmation" required />
                         </div>
@@ -34,7 +34,7 @@
                     </div>
                     <div class="field">
                         <div class="control">
-                            <button type="submit" class="button is-link" @click="handleSubmit">Register</button>
+                            <button type="submit" class="button is-link" @click="handleSubmit">{{ $t('auth.register') }}</button>
                         </div>
                     </div>
                 </form>
@@ -42,8 +42,8 @@
         </div>
         <div class="columns is-mobile is-centered">
             <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen is-one-quarter-fullhd">
-                Already registered? <router-link :to="{ name: 'login' }" class="is-link">
-                    Sign in
+                {{ $t('auth.forms.already_register') }}&nbsp;<router-link :to="{ name: 'login' }" class="is-link">
+                    {{ $t('auth.sign_in') }}
                 </router-link>
             </div>
         </div>

+ 192 - 0
resources/js/vue-i18n-locales.generated.js

@@ -0,0 +1,192 @@
+export default {
+    "en": {
+        "auth": {
+            "sign_out": "Sign out",
+            "sign_in": "Sign in",
+            "register": "Register",
+            "hello": "Hi {username} !",
+            "confirm": {
+                "logout": "Are you sure you want to log out?"
+            },
+            "forms": {
+                "name": "Name",
+                "login": "Login",
+                "email": "Email",
+                "password": "Password",
+                "confirm_password": "Confirm password",
+                "dont_have_account_yet": "Don't have an account yet?",
+                "already_register": "Already registered?",
+                "passwords_do_not_match": "Passwords do not match"
+            }
+        },
+        "commons": {
+            "cancel": "Cancel"
+        },
+        "errors": {
+            "resource_not_found": "Resource not found, please ",
+            "error_occured": "An error occured, please ",
+            "refresh": "refresh"
+        },
+        "pagination": {
+            "previous": "&laquo; Previous",
+            "next": "Next &raquo;"
+        },
+        "passwords": {
+            "password": "Passwords must be at least eight characters and match the confirmation.",
+            "reset": "Your password has been reset!",
+            "sent": "We have e-mailed your password reset link!",
+            "token": "This password reset token is invalid.",
+            "user": "We can't find a user with that e-mail address."
+        },
+        "twofaccounts": {
+            "service": "Service",
+            "account": "Account",
+            "icon": "Icon",
+            "new": "New",
+            "no_account_here": "No 2FA here!",
+            "add_one": "Add one",
+            "manage": "Manage",
+            "done": "Done",
+            "forms": {
+                "service": {
+                    "placeholder": "example.com"
+                },
+                "account": {
+                    "placeholder": "John DOE"
+                },
+                "new_account": "New account",
+                "edit_account": "Edit account",
+                "totp_uri": "TOTP Uri",
+                "use_qrcode": {
+                    "val": "Use a qrcode",
+                    "title": "Use a QR code to fill the form magically"
+                },
+                "unlock": {
+                    "val": "Unlock",
+                    "title": "Unlock it (at your own risk)"
+                },
+                "lock": {
+                    "val": "Lock",
+                    "title": "Lock it"
+                },
+                "choose_image": "Choose an image…",
+                "create": "Create",
+                "save": "Save"
+            },
+            "confirm": {
+                "delete": "Are you sure you want to delete this account?"
+            }
+        },
+        "validation": {
+            "accepted": "The {attribute} must be accepted.",
+            "active_url": "The {attribute} is not a valid URL.",
+            "after": "The {attribute} must be a date after {date}.",
+            "after_or_equal": "The {attribute} must be a date after or equal to {date}.",
+            "alpha": "The {attribute} may only contain letters.",
+            "alpha_dash": "The {attribute} may only contain letters, numbers, dashes and underscores.",
+            "alpha_num": "The {attribute} may only contain letters and numbers.",
+            "array": "The {attribute} must be an array.",
+            "before": "The {attribute} must be a date before {date}.",
+            "before_or_equal": "The {attribute} must be a date before or equal to {date}.",
+            "between": {
+                "numeric": "The {attribute} must be between {min} and {max}.",
+                "file": "The {attribute} must be between {min} and {max} kilobytes.",
+                "string": "The {attribute} must be between {min} and {max} characters.",
+                "array": "The {attribute} must have between {min} and {max} items."
+            },
+            "boolean": "The {attribute} field must be true or false.",
+            "confirmed": "The {attribute} confirmation does not match.",
+            "date": "The {attribute} is not a valid date.",
+            "date_equals": "The {attribute} must be a date equal to {date}.",
+            "date_format": "The {attribute} does not match the format {format}.",
+            "different": "The {attribute} and {other} must be different.",
+            "digits": "The {attribute} must be {digits} digits.",
+            "digits_between": "The {attribute} must be between {min} and {max} digits.",
+            "dimensions": "The {attribute} has invalid image dimensions.",
+            "distinct": "The {attribute} field has a duplicate value.",
+            "email": "The {attribute} must be a valid email address.",
+            "ends_with": "The {attribute} must end with one of the following: {values}",
+            "exists": "The selected {attribute} is invalid.",
+            "file": "The {attribute} must be a file.",
+            "filled": "The {attribute} field must have a value.",
+            "gt": {
+                "numeric": "The {attribute} must be greater than {value}.",
+                "file": "The {attribute} must be greater than {value} kilobytes.",
+                "string": "The {attribute} must be greater than {value} characters.",
+                "array": "The {attribute} must have more than {value} items."
+            },
+            "gte": {
+                "numeric": "The {attribute} must be greater than or equal {value}.",
+                "file": "The {attribute} must be greater than or equal {value} kilobytes.",
+                "string": "The {attribute} must be greater than or equal {value} characters.",
+                "array": "The {attribute} must have {value} items or more."
+            },
+            "image": "The {attribute} must be an image.",
+            "in": "The selected {attribute} is invalid.",
+            "in_array": "The {attribute} field does not exist in {other}.",
+            "integer": "The {attribute} must be an integer.",
+            "ip": "The {attribute} must be a valid IP address.",
+            "ipv4": "The {attribute} must be a valid IPv4 address.",
+            "ipv6": "The {attribute} must be a valid IPv6 address.",
+            "json": "The {attribute} must be a valid JSON string.",
+            "lt": {
+                "numeric": "The {attribute} must be less than {value}.",
+                "file": "The {attribute} must be less than {value} kilobytes.",
+                "string": "The {attribute} must be less than {value} characters.",
+                "array": "The {attribute} must have less than {value} items."
+            },
+            "lte": {
+                "numeric": "The {attribute} must be less than or equal {value}.",
+                "file": "The {attribute} must be less than or equal {value} kilobytes.",
+                "string": "The {attribute} must be less than or equal {value} characters.",
+                "array": "The {attribute} must not have more than {value} items."
+            },
+            "max": {
+                "numeric": "The {attribute} may not be greater than {max}.",
+                "file": "The {attribute} may not be greater than {max} kilobytes.",
+                "string": "The {attribute} may not be greater than {max} characters.",
+                "array": "The {attribute} may not have more than {max} items."
+            },
+            "mimes": "The {attribute} must be a file of type: {values}.",
+            "mimetypes": "The {attribute} must be a file of type: {values}.",
+            "min": {
+                "numeric": "The {attribute} must be at least {min}.",
+                "file": "The {attribute} must be at least {min} kilobytes.",
+                "string": "The {attribute} must be at least {min} characters.",
+                "array": "The {attribute} must have at least {min} items."
+            },
+            "not_in": "The selected {attribute} is invalid.",
+            "not_regex": "The {attribute} format is invalid.",
+            "numeric": "The {attribute} must be a number.",
+            "present": "The {attribute} field must be present.",
+            "regex": "The {attribute} format is invalid.",
+            "required": "The {attribute} field is required.",
+            "required_if": "The {attribute} field is required when {other} is {value}.",
+            "required_unless": "The {attribute} field is required unless {other} is in {values}.",
+            "required_with": "The {attribute} field is required when {values} is present.",
+            "required_with_all": "The {attribute} field is required when {values} are present.",
+            "required_without": "The {attribute} field is required when {values} is not present.",
+            "required_without_all": "The {attribute} field is required when none of {values} are present.",
+            "same": "The {attribute} and {other} must match.",
+            "size": {
+                "numeric": "The {attribute} must be {size}.",
+                "file": "The {attribute} must be {size} kilobytes.",
+                "string": "The {attribute} must be {size} characters.",
+                "array": "The {attribute} must contain {size} items."
+            },
+            "starts_with": "The {attribute} must start with one of the following: {values}",
+            "string": "The {attribute} must be a string.",
+            "timezone": "The {attribute} must be a valid zone.",
+            "unique": "The {attribute} has already been taken.",
+            "uploaded": "The {attribute} failed to upload.",
+            "url": "The {attribute} format is invalid.",
+            "uuid": "The {attribute} must be a valid UUID.",
+            "custom": {
+                "attribute-name": {
+                    "rule-name": "custom-message"
+                }
+            },
+            "attributes": []
+        }
+    }
+}

+ 18 - 2
resources/lang/en/auth.php

@@ -13,7 +13,23 @@ return [
     |
     */
 
-    'failed' => 'These credentials do not match our records.',
-    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+    'sign_out' => 'Sign out',
+    'sign_in' => 'Sign in',
+    'register' => 'Register',
+    'hello' => 'Hi {username} !',
+    'confirm' => [
+        'logout' => 'Are you sure you want to log out?',
+    ],
+    'forms' => [
+        'name' => 'Name',
+        'login' => 'Login',
+        'email' => 'Email',
+        'password' => 'Password',
+        'confirm_password' => 'Confirm password',
+        'dont_have_account_yet' => 'Don\'t have an account yet?',
+        'already_register' => 'Already registered?',
+        'passwords_do_not_match' => 'Passwords do not match',
+    ]
+
 
 ];

+ 18 - 0
resources/lang/en/commons.php

@@ -0,0 +1,18 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'cancel' => 'Cancel',
+
+];

+ 23 - 0
resources/lang/en/errors.php

@@ -0,0 +1,23 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'resource_not_found' => 'Resource not found, please ',
+    'error_occured' => 'An error occured, please ',
+    'refresh' => 'refresh',
+    'response' => [
+        'no_valid_totp' => 'No valid TOTP resource in this QR code',
+    ]
+
+];

+ 54 - 0
resources/lang/en/twofaccounts.php

@@ -0,0 +1,54 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'service' => 'Service',
+    'account' => 'Account',
+    'icon' => 'Icon',
+    'new' => 'New',
+    'no_account_here' => 'No 2FA here!',
+    'add_one' => 'Add one',
+    'manage' => 'Manage',
+    'done' => 'Done',
+    'forms' => [
+        'service' => [
+            'placeholder' => 'example.com',
+        ],
+        'account' => [
+            'placeholder' => 'John DOE',
+        ],
+        'new_account' => 'New account',
+        'edit_account' => 'Edit account',
+        'totp_uri' => 'TOTP Uri',
+        'use_qrcode' => [
+            'val' => 'Use a qrcode',
+            'title' => 'Use a QR code to fill the form magically',
+        ],
+        'unlock' => [
+            'val' => 'Unlock',
+            'title' => 'Unlock it (at your own risk)',
+        ],
+        'lock' => [
+            'val' => 'Lock',
+            'title' => 'Lock it',
+        ],
+        'choose_image' => 'Choose an image…',
+        'create' => 'Create',
+        'save' => 'Save',
+    ],
+    'confirm' => [
+        'delete' => 'Are you sure you want to delete this account?',
+    ],
+
+];

+ 12 - 0
resources/lang/en/validation.php

@@ -132,6 +132,18 @@ return [
         'attribute-name' => [
             'rule-name' => 'custom-message',
         ],
+        'icon' => [
+            'image' => 'Supported format are jpeg, png, bmp, gif, svg, or webp',
+        ],
+        'qrcode' => [
+            'image' => 'Supported format are jpeg, png, bmp, gif, svg, or webp',
+        ],
+        'uri' => [
+            'starts_with' => 'Only valid TOTP uri are supported',
+        ],
+        'email' => [
+            'exists' => 'No account found using this email',
+        ]
     ],
 
     /*

+ 1 - 1
resources/views/landing.blade.php

@@ -14,6 +14,6 @@
     </div>
     <script src="{{ mix('js/bootstrap.js') }}"></script>
     <script src="{{ mix('js/app.js') }}"></script>
-    <script src="{{ asset('js/vue-i18n-locales.generated.js') }}"></script>
+    <script src="{{ mix('js/vue-i18n-locales.generated.js') }}"></script>
 </body>
 </html>