From 11c7ff20a6e7ccda70346d37ec228a52a63273aa Mon Sep 17 00:00:00 2001 From: Bubka <858858+Bubka@users.noreply.github.com> Date: Sun, 12 Jan 2020 19:55:17 +0100 Subject: [PATCH] All hardcoded strings replaced by i18n translation --- app/Http/Controllers/IconController.php | 20 +- app/Http/Controllers/QrCodeController.php | 9 +- .../Controllers/TwoFAccountController.php | 11 +- app/Http/Controllers/UserController.php | 7 +- resources/js/views/Accounts.vue | 22 +- resources/js/views/Create.vue | 28 +-- resources/js/views/Edit.vue | 18 +- resources/js/views/Error.vue | 4 +- resources/js/views/Login.vue | 14 +- resources/js/views/Register.vue | 16 +- resources/js/vue-i18n-locales.generated.js | 192 ++++++++++++++++++ resources/lang/en/auth.php | 20 +- resources/lang/en/commons.php | 18 ++ resources/lang/en/errors.php | 23 +++ resources/lang/en/twofaccounts.php | 54 +++++ resources/lang/en/validation.php | 12 ++ resources/views/landing.blade.php | 2 +- 17 files changed, 380 insertions(+), 90 deletions(-) create mode 100644 resources/js/vue-i18n-locales.generated.js create mode 100644 resources/lang/en/commons.php create mode 100644 resources/lang/en/errors.php create mode 100644 resources/lang/en/twofaccounts.php diff --git a/app/Http/Controllers/IconController.php b/app/Http/Controllers/IconController.php index 498ac6b0..9bdd1a1f 100644 --- a/app/Http/Controllers/IconController.php +++ b/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); } diff --git a/app/Http/Controllers/QrCodeController.php b/app/Http/Controllers/QrCodeController.php index 4abb2d89..99683594 100644 --- a/app/Http/Controllers/QrCodeController.php +++ b/app/Http/Controllers/QrCodeController.php @@ -23,19 +23,14 @@ public function decode(Request $request) { // 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 @@ public function decode(Request $request) return response()->json([ 'error' => [ - 'qrcode' => 'No valid TOTP resource in this QR code' + 'qrcode' => __('errors.response.no_valid_totp') ] ], 400); diff --git a/app/Http/Controllers/TwoFAccountController.php b/app/Http/Controllers/TwoFAccountController.php index b0a0ed96..2331b76a 100644 --- a/app/Http/Controllers/TwoFAccountController.php +++ b/app/Http/Controllers/TwoFAccountController.php @@ -33,14 +33,11 @@ public function store(Request $request) // 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 @@ public function show($id) $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 @@ public function update(Request $request, $id) ]); if ($validator->fails()) { - return response()->json(['error' => $validator->errors()], 400); + return response()->json( ['error' => $validator->errors() ], 400); } @@ -117,7 +114,7 @@ public function update(Request $request, $id) } catch (\Exception $e) { - return response()->json(['error'=>'not found'], 404); + return response()->json( ['error' => 'not found' ] , 404); } } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 8c408dbe..701b7a61 100644 --- a/app/Http/Controllers/UserController.php +++ b/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); diff --git a/resources/js/views/Accounts.vue b/resources/js/views/Accounts.vue index 210ff884..8538ac93 100644 --- a/resources/js/views/Accounts.vue +++ b/resources/js/views/Accounts.vue @@ -5,7 +5,7 @@
- + @@ -35,9 +35,9 @@

- No 2FA here! + {{ $t('twofaccounts.no_account_here') }}

- Add one + {{ $t('twofaccounts.add_one') }}

- New + {{ $t('twofaccounts.new') }}

- Manage + {{ $t('twofaccounts.manage') }} - Done + {{ $t('twofaccounts.done') }} @@ -74,14 +74,14 @@

- Hi {{username}} ! Sign out + {{ $t('auth.hello', {username: username}) }} {{ $t('auth.sign_out') }} - Sign in + {{ $t('auth.sign_in') }} - Register + {{ $t('auth.register') }}
@@ -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'); diff --git a/resources/js/views/Create.vue b/resources/js/views/Create.vue index 40407531..f50a6d39 100644 --- a/resources/js/views/Create.vue +++ b/resources/js/views/Create.vue @@ -2,52 +2,52 @@
-

New account

+

{{ $t('twofaccounts.forms.new_account') }}

-

{{ errors.qrcode.toString() }}

- +
- +

{{ errors.service.toString() }}

- +
- +

{{ errors.account.toString() }}

- +

{{ errors.uri.toString() }}

- +
@@ -76,10 +76,10 @@

{{ errors.icon.toString() }}

- +
- +
diff --git a/resources/js/views/Edit.vue b/resources/js/views/Edit.vue index 704025a1..672908be 100644 --- a/resources/js/views/Edit.vue +++ b/resources/js/views/Edit.vue @@ -2,24 +2,24 @@
-

Edit account

+

{{ $t('twofaccounts.forms.edit_account') }}

- +
- +

{{ errors.service.toString() }}

- +
- +

{{ errors.account.toString() }}

- +
@@ -39,10 +39,10 @@

{{ errors.icon.toString() }}

- +
- +
diff --git a/resources/js/views/Error.vue b/resources/js/views/Error.vue index d2d24a48..020929a6 100644 --- a/resources/js/views/Error.vue +++ b/resources/js/views/Error.vue @@ -3,11 +3,11 @@

-

Resource not found, please refresh

+

{{ $t('errors.resource_not_found') }}{{ $t('errors.refresh') }}

-

An error occured, please refresh

+

{{ $t('errors.error_occured') }}{{ $t('errors.refresh') }}

diff --git a/resources/js/views/Login.vue b/resources/js/views/Login.vue index 623ecc2b..108dde0c 100644 --- a/resources/js/views/Login.vue +++ b/resources/js/views/Login.vue @@ -2,17 +2,17 @@

-

Login

+

{{ $t('auth.forms.login') }}

- +

{{ errors.email.toString() }}

- +
@@ -20,7 +20,7 @@
- +
@@ -28,8 +28,8 @@
- Don't have an account yet? - Register + {{ $t('auth.forms.dont_have_account_yet') }}  + {{ $t('auth.register') }}
@@ -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') ] } }); } diff --git a/resources/js/views/Register.vue b/resources/js/views/Register.vue index 853ab749..0fcc1f9a 100644 --- a/resources/js/views/Register.vue +++ b/resources/js/views/Register.vue @@ -2,31 +2,31 @@
-

Register

+

{{ $t('auth.register') }}

- +

{{ errors.name.toString() }}

- +

{{ errors.email.toString() }}

- +

{{ errors.password.toString() }}

- +
@@ -34,7 +34,7 @@
- +
@@ -42,8 +42,8 @@
- Already registered? - Sign in + {{ $t('auth.forms.already_register') }}  + {{ $t('auth.sign_in') }}
diff --git a/resources/js/vue-i18n-locales.generated.js b/resources/js/vue-i18n-locales.generated.js new file mode 100644 index 00000000..c0288f0e --- /dev/null +++ b/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": "« Previous", + "next": "Next »" + }, + "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": [] + } + } +} diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php index e5506df2..44bff63c 100644 --- a/resources/lang/en/auth.php +++ b/resources/lang/en/auth.php @@ -13,7 +13,23 @@ | */ - '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', + ] + ]; diff --git a/resources/lang/en/commons.php b/resources/lang/en/commons.php new file mode 100644 index 00000000..88af8a4b --- /dev/null +++ b/resources/lang/en/commons.php @@ -0,0 +1,18 @@ + 'Cancel', + +]; \ No newline at end of file diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php new file mode 100644 index 00000000..43eb2279 --- /dev/null +++ b/resources/lang/en/errors.php @@ -0,0 +1,23 @@ + 'Resource not found, please ', + 'error_occured' => 'An error occured, please ', + 'refresh' => 'refresh', + 'response' => [ + 'no_valid_totp' => 'No valid TOTP resource in this QR code', + ] + +]; \ No newline at end of file diff --git a/resources/lang/en/twofaccounts.php b/resources/lang/en/twofaccounts.php new file mode 100644 index 00000000..7a4a73f7 --- /dev/null +++ b/resources/lang/en/twofaccounts.php @@ -0,0 +1,54 @@ + '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?', + ], + +]; \ No newline at end of file diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index e1d879f3..ae4ecdc1 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -132,6 +132,18 @@ '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', + ] ], /* diff --git a/resources/views/landing.blade.php b/resources/views/landing.blade.php index 6f90b35f..3c7c96c1 100644 --- a/resources/views/landing.blade.php +++ b/resources/views/landing.blade.php @@ -14,6 +14,6 @@
- + \ No newline at end of file