From da6d64f9ee1b00dd9cbefb8d684254424bc324c7 Mon Sep 17 00:00:00 2001 From: Bubka <858858+Bubka@users.noreply.github.com> Date: Wed, 8 Jan 2020 23:22:51 +0100 Subject: [PATCH] Refactore and fix for icon management --- app/Http/Controllers/IconController.php | 8 +-- .../Controllers/TwoFAccountController.php | 2 +- app/TwoFAccount.php | 2 +- resources/js/components/TwofaccountShow.vue | 2 +- resources/js/views/Accounts.vue | 4 +- resources/js/views/Create.vue | 57 +++++++++------ resources/js/views/Edit.vue | 70 +++++++++++++------ 7 files changed, 94 insertions(+), 51 deletions(-) diff --git a/app/Http/Controllers/IconController.php b/app/Http/Controllers/IconController.php index 9e726218..bde6a8aa 100644 --- a/app/Http/Controllers/IconController.php +++ b/app/Http/Controllers/IconController.php @@ -21,9 +21,9 @@ public function upload(Request $request) if($request->hasFile('icon')){ - $path = $request->file('icon')->storePublicly('public'); + $path = $request->file('icon')->storePublicly('public/icons'); - return response()->json('storage/' . pathinfo($path)['basename'], 201); + return response()->json(pathinfo($path)['basename'], 201); } else { @@ -41,9 +41,9 @@ public function upload(Request $request) public function delete($icon) { - if( Storage::exists('public/' . $icon) ) { + if( Storage::exists('public/icons/' . $icon) ) { - Storage::delete('public/' . $icon); + Storage::delete('public/icons/' . $icon); } return response()->json(null, 204); diff --git a/app/Http/Controllers/TwoFAccountController.php b/app/Http/Controllers/TwoFAccountController.php index 4c59a6cf..1e6890a4 100644 --- a/app/Http/Controllers/TwoFAccountController.php +++ b/app/Http/Controllers/TwoFAccountController.php @@ -108,7 +108,7 @@ public function update(Request $request, TwoFAccount $twofaccount) public function destroy(TwoFAccount $twofaccount) { // delete icon - $storedIcon = 'public/' . pathinfo($twofaccount->icon)['basename']; + $storedIcon = 'public/icons/' . $twofaccount->icon; if( Storage::exists($storedIcon) ) { Storage::delete($storedIcon); diff --git a/app/TwoFAccount.php b/app/TwoFAccount.php index fd95b110..bf1205ae 100644 --- a/app/TwoFAccount.php +++ b/app/TwoFAccount.php @@ -28,7 +28,7 @@ class TwoFAccount extends Model public function getIconAttribute($value) { - if( !Storage::exists('public/' . pathinfo($value)['basename']) ) { + if( !Storage::exists('public/icons/' . pathinfo($value)['basename']) ) { return ''; } diff --git a/resources/js/components/TwofaccountShow.vue b/resources/js/components/TwofaccountShow.vue index 9445ded3..32d062dd 100644 --- a/resources/js/components/TwofaccountShow.vue +++ b/resources/js/components/TwofaccountShow.vue @@ -1,7 +1,7 @@ <template> <div> <figure class="image is-64x64" style="display: inline-block" v-if="icon"> - <img :src="icon"> + <img :src="'storage/icons/' + icon"> </figure> <p class="is-size-4 has-text-grey-light">{{ service }}</p> <p class="is-size-6 has-text-grey">{{ account }}</p> diff --git a/resources/js/views/Accounts.vue b/resources/js/views/Accounts.vue index fe86d9c2..d089f2e3 100644 --- a/resources/js/views/Accounts.vue +++ b/resources/js/views/Accounts.vue @@ -4,7 +4,7 @@ <div class="buttons are-large is-centered"> <span v-for="account in accounts" class="button is-black twofaccount" > <span @click.stop="getAccount(account.id)"> - <img :src="account.icon" v-if="account.icon"> + <img :src="'storage/icons/' + account.icon" v-if="account.icon"> {{ account.service }} <span class="is-family-primary is-size-7 has-text-grey">{{ account.account }}</span> </span> @@ -21,7 +21,7 @@ </div> <div class="container has-text-centered" v-show="this.showNoAccount"> <p> - <img class="bg" src="storage/bg.png"> + <img class="bg" src="storage/img/bg.png"> </p> <p class="subtitle is-5"> No 2FA here! diff --git a/resources/js/views/Create.vue b/resources/js/views/Create.vue index a80c44a2..bdb6e6ac 100644 --- a/resources/js/views/Create.vue +++ b/resources/js/views/Create.vue @@ -63,8 +63,8 @@ <span class="file-label">Choose an image…</span> </span> </label> - <span class="tag is-black is-large" v-if="twofaccount.icon.length > 0"> - <img class="icon-preview" :src="twofaccount.icon" > + <span class="tag is-black is-large" v-if="tempIcon"> + <img class="icon-preview" :src="'storage/icons/' + tempIcon" > <button class="delete is-small" @click.prevent="deleteIcon"></button> </span> </div> @@ -74,7 +74,7 @@ <button type="submit" class="button is-link">Create</button> </div> <div class="control"> - <router-link :to="{ name: 'accounts', params: { InitialEditMode: false } }" class="button is-text">Cancel</router-link> + <button class="button is-text" @click="cancelCreation">Cancel</button> </div> </div> </form> @@ -93,13 +93,18 @@ 'uri' : '', 'icon' : '' }, - uriIsLocked: true + uriIsLocked: true, + tempIcon: '' } }, methods: { createAccount: function() { + // set current temp icon as account icon + this.twofaccount.icon = this.tempIcon + + // store the account let token = localStorage.getItem('jwt') axios.defaults.headers.common['Content-Type'] = 'application/json' @@ -110,6 +115,15 @@ }) }, + cancelCreation: function() { + // clean possible uploaded temp icon + if( this.tempIcon ) { + this.deleteIcon() + } + + this.$router.push({name: 'accounts', params: { InitialEditMode: false }}); + }, + uploadQrcode(event) { let token = localStorage.getItem('jwt') @@ -117,15 +131,15 @@ axios.defaults.headers.common['Content-Type'] = 'application/json' axios.defaults.headers.common['Authorization'] = 'Bearer ' + token - let files = this.$refs.qrcodeInput.files + let files = this.$refs.qrcodeInput.files - if (!files.length) { - console.log('no files'); - return false; - } - else { + if (!files.length) { + console.log('no files'); + return false; + } + else { console.log(files.length + ' file(s) found'); - } + } let imgdata = new FormData(); @@ -151,16 +165,16 @@ axios.defaults.headers.common['Content-Type'] = 'application/json' axios.defaults.headers.common['Authorization'] = 'Bearer ' + token - let files = this.$refs.iconInput.files + let files = this.$refs.iconInput.files - if (!files.length) { - return false; - } + if (!files.length) { + return false; + } - // clean possible already uploaded icon - if( this.twofaccount.icon ) { + // clean possible already uploaded temp icon + if( this.tempIcon ) { this.deleteIcon() - } + } let imgdata = new FormData(); @@ -174,7 +188,7 @@ axios.post('/api/icon/upload', imgdata, config).then(response => { console.log('icon path > ', response); - this.twofaccount.icon = response.data; + this.tempIcon = response.data; } ) }, @@ -186,11 +200,10 @@ axios.defaults.headers.common['Content-Type'] = 'application/json' axios.defaults.headers.common['Authorization'] = 'Bearer ' + token - axios.delete('/api/icon/delete/' + this.twofaccount.icon.replace('storage/', '')).then(response => { - this.twofaccount.icon = '' + axios.delete('/api/icon/delete/' + this.tempIcon).then(response => { + this.tempIcon = '' } ) - } }, diff --git a/resources/js/views/Edit.vue b/resources/js/views/Edit.vue index df825e36..fb23ca50 100644 --- a/resources/js/views/Edit.vue +++ b/resources/js/views/Edit.vue @@ -28,8 +28,8 @@ <span class="file-label">Choose an image…</span> </span> </label> - <span class="tag is-black is-large" v-if="twofaccount.icon"> - <img class="icon-preview" :src="'../' + twofaccount.icon" > + <span class="tag is-black is-large" v-if="tempIcon"> + <img class="icon-preview" :src="'../storage/icons/' + tempIcon" > <button class="delete is-small" @click.prevent="deleteIcon"></button> </span> </div> @@ -39,7 +39,7 @@ <button type="submit" class="button is-link">Save</button> </div> <div class="control"> - <router-link :to="{ name: 'accounts', params: { InitialEditMode: true } }" class="button is-text">Cancel</router-link> + <button class="button is-text" @click.prevent="cancelCreation">Cancel</button> </div> </div> </form> @@ -57,7 +57,8 @@ 'account' : '', 'uri' : '', 'icon' : '' - } + }, + tempIcon: '' } }, @@ -74,10 +75,26 @@ axios.get('/api/twofaccounts/' + this.$route.params.twofaccountId).then(response => { this.twofaccount = response.data + + // set account icon as temp icon + this.tempIcon = this.twofaccount.icon }) }, updateAccount: function() { + + // Set new icon and delete old one + if( this.tempIcon !== this.twofaccount.icon ) { + let oldIcon = '' + + oldIcon = this.twofaccount.icon + + this.twofaccount.icon = this.tempIcon + this.tempIcon = oldIcon + this.deleteIcon() + } + + // store the account let token = localStorage.getItem('jwt') axios.defaults.headers.common['Content-Type'] = 'application/json' @@ -88,6 +105,15 @@ }) }, + cancelCreation: function() { + // clean new temp icon + if( this.tempIcon ) { + this.deleteIcon() + } + + this.$router.push({name: 'accounts', params: { InitialEditMode: true }}); + }, + uploadIcon(event) { let token = localStorage.getItem('jwt') @@ -95,16 +121,16 @@ axios.defaults.headers.common['Content-Type'] = 'application/json' axios.defaults.headers.common['Authorization'] = 'Bearer ' + token - let files = this.$refs.iconInput.files + let files = this.$refs.iconInput.files - if (!files.length) { - return false; - } + if (!files.length) { + return false; + } - // clean possible already uploaded icon - if( this.twofaccount.icon ) { + // clean possible tempIcon but keep original one + if( this.tempIcon && this.tempIcon !== this.twofaccount.icon ) { this.deleteIcon() - } + } let imgdata = new FormData(); @@ -118,23 +144,27 @@ axios.post('/api/icon/upload', imgdata, config).then(response => { console.log('icon path > ', response); - this.twofaccount.icon = response.data; + this.tempIcon = response.data; } ) }, deleteIcon(event) { - let token = localStorage.getItem('jwt') + if( this.tempIcon !== this.twofaccount.icon ) { + let token = localStorage.getItem('jwt') - axios.defaults.headers.common['Content-Type'] = 'application/json' - axios.defaults.headers.common['Authorization'] = 'Bearer ' + token + axios.defaults.headers.common['Content-Type'] = 'application/json' + axios.defaults.headers.common['Authorization'] = 'Bearer ' + token - axios.delete('/api/icon/delete/' + this.twofaccount.icon.replace('storage/', '')).then(response => { - this.twofaccount.icon = '' - } - ) - } + axios.delete('/api/icon/delete/' + this.tempIcon).then(response => { + this.tempIcon = '' + } + ) + } + + this.tempIcon = '' + }, },