diff options
Diffstat (limited to 'src/site')
| -rw-r--r-- | src/site/components/grid/Grid.vue | 2 | ||||
| -rw-r--r-- | src/site/components/sidebar/Sidebar.vue | 2 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/file/_id.vue | 85 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/settings.vue | 50 | ||||
| -rw-r--r-- | src/site/plugins/axios.js | 4 | ||||
| -rw-r--r-- | src/site/store/admin.js | 31 | ||||
| -rw-r--r-- | src/site/store/auth.js | 6 | ||||
| -rw-r--r-- | src/site/store/images.js | 15 |
8 files changed, 105 insertions, 90 deletions
diff --git a/src/site/components/grid/Grid.vue b/src/site/components/grid/Grid.vue index 84c0b11..90c196b 100644 --- a/src/site/components/grid/Grid.vue +++ b/src/site/components/grid/Grid.vue @@ -287,7 +287,7 @@ export default { } catch (e) { this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true }); } - this.showingModalForFile.albums = this.images.filesAlbums[id]; + this.showingModalForFile.albums = this.images.fileAlbumsMap[id]; this.isAlbumsModalActive = true; }, diff --git a/src/site/components/sidebar/Sidebar.vue b/src/site/components/sidebar/Sidebar.vue index 5394fc6..d586122 100644 --- a/src/site/components/sidebar/Sidebar.vue +++ b/src/site/components/sidebar/Sidebar.vue @@ -28,7 +28,7 @@ <b-icon class="is-pulled-right" :icon="props.expanded ? 'menu-down' : 'menu-up'" /> </template> <b-menu-item icon="account" label="Users" tag="nuxt-link" to="/dashboard/admin/users" exact /> - <b-menu-item icon="cog-outline" label="Settings" disabled /> + <b-menu-item icon="cog-outline" label="Settings" tag="nuxt-link" to="/dashboard/admin/settings" exact /> </b-menu-item> <b-menu-item class="item" diff --git a/src/site/pages/dashboard/admin/file/_id.vue b/src/site/pages/dashboard/admin/file/_id.vue index 34fcd01..89afa47 100644 --- a/src/site/pages/dashboard/admin/file/_id.vue +++ b/src/site/pages/dashboard/admin/file/_id.vue @@ -19,99 +19,101 @@ <b-field label="ID" horizontal> - <span>{{ file.id }}</span> + <span>{{ admin.file.id }}</span> </b-field> <b-field label="Name" horizontal> - <span>{{ file.name }}</span> + <span>{{ admin.file.name }}</span> </b-field> <b-field label="Original Name" horizontal> - <span>{{ file.original }}</span> + <span>{{ admin.file.original }}</span> </b-field> <b-field label="IP" horizontal> - <span class="underline">{{ file.ip }}</span> + <span class="underline">{{ admin.file.ip }}</span> </b-field> <b-field label="Link" horizontal> <a - :href="file.url" - target="_blank">{{ file.url }}</a> + :href="admin.file.url" + target="_blank">{{ admin.file.url }}</a> </b-field> <b-field label="Size" horizontal> - <span>{{ formatBytes(file.size) }}</span> + <span>{{ formatBytes(admin.file.size) }}</span> </b-field> <b-field label="Hash" horizontal> - <span>{{ file.hash }}</span> + <span>{{ admin.file.hash }}</span> </b-field> <b-field label="Uploaded" horizontal> - <span><timeago :since="file.createdAt" /></span> + <span><timeago :since="admin.file.createdAt" /></span> </b-field> </div> <div class="column is-6"> <b-field label="User Id" horizontal> - <span>{{ user.id }}</span> + <span>{{ admin.user.id }}</span> </b-field> <b-field label="Username" horizontal> - <span>{{ user.username }}</span> + <span>{{ admin.user.username }}</span> </b-field> <b-field label="Enabled" horizontal> - <span>{{ user.enabled }}</span> + <span>{{ admin.user.enabled }}</span> </b-field> <b-field label="Registered" horizontal> - <span><timeago :since="user.createdAt" /></span> + <span><timeago :since="admin.user.createdAt" /></span> </b-field> <b-field label="Files" horizontal> <span> - <nuxt-link :to="`/dashboard/admin/user/${user.id}`">{{ user.fileCount }}</nuxt-link> + <nuxt-link :to="`/dashboard/admin/user/${admin.user.id}`">{{ admin.user.fileCount }}</nuxt-link> </span> </b-field> </div> </div> <div class="mb2 mt2 text-center"> - <button - class="button is-danger" + <b-button + v-if="admin.user.id !== auth.user.id" + type="is-danger" @click="promptBanIP"> Ban IP - </button> - <button - class="button is-danger" + </b-button> + <b-button + v-if="admin.user.id !== auth.user.id" + type="is-danger" @click="promptDisableUser"> Disable user - </button> + </b-button> </div> </div> </div> @@ -120,35 +122,22 @@ </template> <script> +import { mapState } from 'vuex'; import Sidebar from '~/components/sidebar/Sidebar.vue'; export default { components: { Sidebar, }, - middleware: ['auth', 'admin'], - data() { - return { - options: {}, - file: null, - user: null, - }; - }, - async asyncData({ $axios, route }) { + middleware: ['auth', 'admin', ({ route, store }) => { try { - const response = await $axios.$get(`file/${route.params.id}`); - return { - file: response.file ? response.file : null, - user: response.user ? response.user : null, - }; - } catch (error) { - console.error(error); - return { - file: null, - user: null, - }; + store.dispatch('admin/fetchFile', route.params.id); + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); } - }, + }], + computed: mapState(['admin', 'auth']), methods: { promptDisableUser() { this.$buefy.dialog.confirm({ @@ -157,11 +146,8 @@ export default { onConfirm: () => this.disableUser(), }); }, - async disableUser() { - const response = await this.$axios.$post('admin/users/disable', { - id: this.user.id, - }); - this.$buefy.toast.open(response.message); + disableUser() { + this.$handler.executeAction('admin/disableUser', this.user.id); }, promptBanIP() { this.$buefy.dialog.confirm({ @@ -170,11 +156,8 @@ export default { onConfirm: () => this.banIP(), }); }, - async banIP() { - const response = await this.$axios.$post('admin/ban/ip', { - ip: this.file.ip, - }); - this.$buefy.toast.open(response.message); + banIP() { + this.$handler.executeAction('admin/banIP', this.file.ip); }, formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes'; diff --git a/src/site/pages/dashboard/admin/settings.vue b/src/site/pages/dashboard/admin/settings.vue index 9e63a7c..7f6a0fe 100644 --- a/src/site/pages/dashboard/admin/settings.vue +++ b/src/site/pages/dashboard/admin/settings.vue @@ -16,7 +16,7 @@ message="Please enter the name which this service is gonna be identified as" horizontal> <b-input - v-model="options.serviceName" + v-model="settings.serviceName" expanded /> </b-field> @@ -25,7 +25,7 @@ message="Where to store the files relative to the working directory" horizontal> <b-input - v-model="options.uploadFolder" + v-model="settings.uploadFolder" expanded /> </b-field> @@ -34,7 +34,7 @@ message="Maximum links allowed per album" horizontal> <b-input - v-model="options.linksPerAlbum" + v-model="settings.linksPerAlbum" type="number" expanded /> </b-field> @@ -44,7 +44,7 @@ message="Maximum allowed file size in MB" horizontal> <b-input - v-model="options.maxUploadSize" + v-model="settings.maxUploadSize" expanded /> </b-field> @@ -53,7 +53,7 @@ message="How many characters long should the generated filenames be" horizontal> <b-input - v-model="options.filenameLength" + v-model="settings.filenameLength" expanded /> </b-field> @@ -62,7 +62,7 @@ message="How many characters a link for an album should have" horizontal> <b-input - v-model="options.albumLinkLength" + v-model="settings.albumLinkLength" expanded /> </b-field> @@ -71,7 +71,7 @@ message="Generate thumbnails when uploading a file if possible" horizontal> <b-switch - v-model="options.generateThumbnails" + v-model="settings.generateThumbnails" :true-value="true" :false-value="false" /> </b-field> @@ -81,7 +81,7 @@ message="Allow generating zips to download entire albums" horizontal> <b-switch - v-model="options.generateZips" + v-model="settings.generateZips" :true-value="true" :false-value="false" /> </b-field> @@ -91,7 +91,7 @@ message="Enable anonymous uploades" horizontal> <b-switch - v-model="options.publicMode" + v-model="settings.publicMode" :true-value="true" :false-value="false" /> </b-field> @@ -101,7 +101,7 @@ message="Enable creating new accounts in the platform" horizontal> <b-switch - v-model="options.enableAccounts" + v-model="settings.enableAccounts" :true-value="true" :false-value="false" /> </b-field> @@ -120,38 +120,36 @@ </template> <script> +import { mapState } from 'vuex'; import Sidebar from '~/components/sidebar/Sidebar.vue'; export default { components: { Sidebar, }, - middleware: ['auth', 'admin'], - data() { - return { - options: {}, - }; - }, + middleware: ['auth', 'admin', ({ store }) => { + try { + store.dispatch('admin/fetchSettings'); + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + } + }], metaInfo() { return { title: 'Settings' }; }, - mounted() { - this.getSettings(); - }, + computed: mapState({ + settings: (state) => state.admin.settings, + }), methods: { - async getSettings() { - const response = await this.$axios.$get('service/config'); - this.options = response.config; - }, promptRestartService() { this.$buefy.dialog.confirm({ message: 'Keep in mind that restarting only works if you have PM2 or something similar set up. Continue?', onConfirm: () => this.restartService(), }); }, - async restartService() { - const response = await this.$axios.$post('service/restart'); - this.$buefy.toast.open(response.message); + restartService() { + this.$handler.executeAction('admin/restartService'); }, }, }; diff --git a/src/site/plugins/axios.js b/src/site/plugins/axios.js index 378f922..0308d39 100644 --- a/src/site/plugins/axios.js +++ b/src/site/plugins/axios.js @@ -24,9 +24,9 @@ export default function ({ $axios, store }) { } } - if (error.response?.data?.message.indexOf('Token expired') !== -1) { + /* if (error.response?.data?.message.indexOf('Token expired') !== -1) { store.dispatch('auth/logout'); - } + } */ } }); } diff --git a/src/site/store/admin.js b/src/site/store/admin.js index 2586a18..b31c446 100644 --- a/src/site/store/admin.js +++ b/src/site/store/admin.js @@ -15,6 +15,12 @@ export const state = () => ({ }); export const actions = { + async fetchSettings({ commit }) { + const response = await this.$axios.$get('service/config'); + commit('setSettings', response); + + return response; + }, async fetchUsers({ commit }) { const response = await this.$axios.$get('admin/users'); commit('setUsers', response); @@ -22,11 +28,23 @@ export const actions = { return response; }, async fetchUser({ commit }, id) { - const response = await this.$axios.$get(`/admin/users/${id}`); + const response = await this.$axios.$get(`admin/users/${id}`); + commit('setUserInfo', response); + + return response; + }, + async fetchFile({ commit }, id) { + const response = await this.$axios.$get(`file/${id}`); + commit('setFile', response); commit('setUserInfo', response); return response; }, + async banIP(_, ip) { + const response = await this.$axios.$post('admin/ban/ip', { ip }); + + return response; + }, async enableUser({ commit }, id) { const response = await this.$axios.$post('admin/users/enable', { id }); @@ -60,9 +78,17 @@ export const actions = { return response; }, + async restartService() { + const response = await this.$axios.$post('service/restart'); + + return response; + }, }; export const mutations = { + setSettings(state, { config }) { + state.settings = config; + }, setUsers(state, { users }) { state.users = users; }, @@ -70,6 +96,9 @@ export const mutations = { state.user = { ...state.user, ...user }; state.user.files = files || []; }, + setFile(state, { file }) { + state.file = file || {}; + }, changeUserState(state, { userId, enabled, isAdmin }) { const foundIndex = state.users.findIndex(({ id }) => id === userId); if (foundIndex > -1) { diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 465de7d..96631e2 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -1,6 +1,10 @@ const getDefaultState = () => ({ loggedIn: false, - user: null, + user: { + id: null, + isAdmin: false, + username: null, + }, token: null, }); diff --git a/src/site/store/images.js b/src/site/store/images.js index a7581e0..acac286 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -10,7 +10,8 @@ export const getDefaultState = () => ({ }, name: null, downloadEnabled: false, - filesAlbums: {}, // map of file ids with a list of album objects the file is in + fileAlbumsMap: {}, // map of file ids with a list of album objects the file is in + filesTags: {}, // map of file ids with a list of tag objects for the file }); export const state = getDefaultState; @@ -105,19 +106,19 @@ export const mutations = { } }, setFileAlbums(state, { fileId, albums }) { - Vue.set(state.filesAlbums, fileId, albums); + Vue.set(state.fileAlbumsMap, fileId, albums); }, addAlbumToFile(state, { fileId, album }) { - if (!state.filesAlbums[fileId]) return; + if (!state.fileAlbumsMap[fileId]) return; - state.filesAlbums[fileId].push(album); + state.fileAlbumsMap[fileId].push(album); }, removeAlbumFromFile(state, { fileId, albumId }) { - if (!state.filesAlbums[fileId]) return; + if (!state.fileAlbumsMap[fileId]) return; - const foundIndex = state.filesAlbums[fileId].findIndex(({ id }) => id === albumId); + const foundIndex = state.fileAlbumsMap[fileId].findIndex(({ id }) => id === albumId); if (foundIndex > -1) { - state.filesAlbums[fileId].splice(foundIndex, 1); + state.fileAlbumsMap[fileId].splice(foundIndex, 1); } }, resetState(state) { |