working better

Former-commit-id: 682c7d56814a3c9a35fcf55b540e470b5c66d890 [formerly a603a591938ec8edbe3f703772f86ba978ff92de] [formerly 6d1a11fdeb5d3a00c202e125a0873b263a3787cf [formerly 12c466d2aa]]
Former-commit-id: 4f43bbf0b4f91a9528cdf881f4abbdfc098b82cd [formerly 7fc1e010ac54107ff03762ad729ed54beccca02c]
Former-commit-id: 4d464034e98aefbdce39d142a30bf34aa3fd2d2e
pull/726/head
Henrique Dias 2017-07-03 15:19:17 +01:00
parent bae3c341f6
commit 067051ea09
20 changed files with 292 additions and 250 deletions

View File

@ -69,8 +69,7 @@
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import Item from './ListingItem' import Item from './ListingItem'
import webdav from '@/utils/webdav' import api from '@/utils/api'
import page from '@/utils/page'
export default { export default {
name: 'listing', name: 'listing',
@ -138,12 +137,12 @@ export default {
let promises = [] let promises = []
for (let file of files) { for (let file of files) {
promises.push(webdav.put(window.location.pathname + base + file.name, file)) promises.push(api.put(this.$route.path + base + file.name, file))
} }
Promise.all(promises) Promise.all(promises)
.then(() => { .then(() => {
page.reload() // page.reload()
// buttons.setDone('upload') // buttons.setDone('upload')
}) })
.catch(e => { .catch(e => {

View File

@ -28,8 +28,7 @@
import { mapMutations, mapGetters, mapState } from 'vuex' import { mapMutations, mapGetters, mapState } from 'vuex'
import filesize from 'filesize' import filesize from 'filesize'
import moment from 'moment' import moment from 'moment'
import webdav from '@/utils/webdav.js' import api from '@/utils/api'
import page from '@/utils/page.js'
export default { export default {
name: 'item', name: 'item',
@ -87,11 +86,13 @@ export default {
let url = this.req.items[i].url let url = this.req.items[i].url
let name = this.req.items[i].name let name = this.req.items[i].name
promises.push(webdav.move(url, this.url + encodeURIComponent(name))) promises.push(api.move(url, this.url + encodeURIComponent(name)))
} }
Promise.all(promises) Promise.all(promises)
.then(() => page.reload()) .then(() => {
// page.reload()
})
.catch(error => console.log(error)) .catch(error => console.log(error))
}, },
click: function (event) { click: function (event) {

View File

@ -6,15 +6,15 @@
<search></search> <search></search>
</div> </div>
<div> <div>
<rename-button v-show="showRenameButton()"></rename-button> <rename-button v-show="!loading && showRenameButton()"></rename-button>
<move-button v-show="showMoveButton()"></move-button> <move-button v-show="!loading && showMoveButton()"></move-button>
<delete-button v-show="showDeleteButton()"></delete-button> <delete-button v-show="!loading && showDeleteButton()"></delete-button>
<switch-button v-show="req.kind !== 'editor'"></switch-button> <switch-button v-show="!loading && req.kind !== 'editor'"></switch-button>
<download-button></download-button> <download-button></download-button>
<upload-button v-show="showUpload()"></upload-button> <upload-button v-show="!loading && showUpload()"></upload-button>
<info-button></info-button> <info-button></info-button>
<button v-show="req.kind === 'listing'" @click="$store.commit('multiple', true)" aria-label="Select multiple" class="action"> <button v-show="isListing" @click="$store.commit('multiple', true)" aria-label="Select multiple" class="action">
<i class="material-icons">check_circle</i> <i class="material-icons">check_circle</i>
<span>Select</span> <span>Select</span>
</button> </button>
@ -22,10 +22,10 @@
</header> </header>
<nav> <nav>
<a class="action" :href="baseURL + '/'"> <router-link class="action" to="/files/">
<i class="material-icons">folder</i> <i class="material-icons">folder</i>
<span>My Files</span> <span>My Files</span>
</a> </router-link>
<div v-if="user.allowNew"> <div v-if="user.allowNew">
<button @click="$store.commit('showNewDir', true)" aria-label="New directory" title="New directory" class="action"> <button @click="$store.commit('showNewDir', true)" aria-label="New directory" title="New directory" class="action">
@ -45,16 +45,16 @@
</button> </button>
</div> </div>
<button @click="logout" class="action" id="logout" tabindex="0" role="button" aria-label="Log out"> <button @click="logout" class="action" id="logout" aria-label="Log out">
<i class="material-icons" title="Logout">exit_to_app</i> <i class="material-icons" title="Logout">exit_to_app</i>
<span>Logout</span> <span>Logout</span>
</button> </button>
</nav> </nav>
<main> <main>
<editor v-if="req.kind === 'editor'"></editor> <editor v-if="isEditor"></editor>
<listing v-if="req.kind === 'listing'"></listing> <listing v-if="isListing"></listing>
<preview v-if="req.kind === 'preview'"></preview> <preview v-if="isPreview"></preview>
</main> </main>
<download-prompt v-if="showDownload" :class="{ active: showDownload }"></download-prompt> <download-prompt v-if="showDownload" :class="{ active: showDownload }"></download-prompt>
@ -65,7 +65,7 @@
<info-prompt v-if="showInfo" :class="{ active: showInfo }"></info-prompt> <info-prompt v-if="showInfo" :class="{ active: showInfo }"></info-prompt>
<move-prompt v-if="showMove" :class="{ active: showMove }"></move-prompt> <move-prompt v-if="showMove" :class="{ active: showMove }"></move-prompt>
<help v-show="showHelp" :class="{ active: showHelp }"></help> <help v-show="showHelp" :class="{ active: showHelp }"></help>
<div v-show="$store.getters.showOverlay" @click="resetPrompts" class="overlay" :class="{ active: $store.getters.showOverlay }"></div> <div v-show="showOverlay" @click="resetPrompts" class="overlay" :class="{ active: showOverlay }"></div>
<footer>Served with <a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.</footer> <footer>Served with <a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.</footer>
</div> </div>
@ -129,7 +129,10 @@ export default {
NewDirPrompt NewDirPrompt
}, },
computed: { computed: {
...mapGetters(['selectedCount']), ...mapGetters([
'selectedCount',
'showOverlay'
]),
...mapState([ ...mapState([
'req', 'req',
'user', 'user',
@ -143,37 +146,28 @@ export default {
'showNewFile', 'showNewFile',
'showNewDir', 'showNewDir',
'showDownload' 'showDownload'
]) ]),
isListing () {
return this.req.kind === 'listing' && !this.loading
},
isPreview () {
return this.req.kind === 'preview' && !this.loading
},
isEditor () {
return this.req.kind === 'editor' && !this.loading
}
}, },
data: function () { data: function () {
return { return {
plugins: [] plugins: [],
loading: true
} }
}, },
beforeRouteEnter (to, from, next) { created () {
api.fetch(to.params[0]) this.fetchData()
.then(() => {
next()
})
.catch(error => {
// TODO: 404, 403 and 500!
console.log(error)
window.alert('Something went wrong. Please reload.')
})
}, },
beforeRouteUpdate (to, from, next) { watch: {
this.$store.commit('resetSelected') '$route': 'fetchData'
this.$store.commit('multiple', false)
api.fetch(to.params[0])
.then(() => {
next()
})
.catch(error => {
// TODO: 404, 403 and 500!
console.log(error)
window.alert('Something went wrong. Please reload.')
})
}, },
mounted () { mounted () {
updateColumnSizes() updateColumnSizes()
@ -183,38 +177,6 @@ export default {
this.plugins = window.plugins this.plugins = window.plugins
} }
document.title = this.req.name
window.history.replaceState({
url: window.location.pathname,
name: document.title
}, document.title, window.location.pathname)
/* window.addEventListener('popstate', (event) => {
event.preventDefault()
event.stopPropagation()
this.$store.commit('multiple', false)
this.$store.commit('resetSelected')
this.$store.commit('resetPrompts')
let request = new window.XMLHttpRequest()
request.open('GET', event.state.url, true)
request.setRequestHeader('Accept', 'application/json')
request.onload = () => {
if (request.status === 200) {
let req = JSON.parse(request.responseText)
this.$store.commit('updateRequest', req)
document.title = event.state.name
} else {
console.log(request.responseText)
}
}
request.onerror = (error) => { console.log(error) }
request.send()
}) */
window.addEventListener('keydown', (event) => { window.addEventListener('keydown', (event) => {
// Esc! // Esc!
if (event.keyCode === 27) { if (event.keyCode === 27) {
@ -270,6 +232,33 @@ export default {
}) })
}, },
methods: { methods: {
fetchData () {
this.loading = true
// Reset selected items and multiple selection.
this.$store.commit('resetSelected')
this.$store.commit('multiple', false)
let url = this.$route.path
if (url === '') url = '/'
if (url[0] !== '/') url = '/' + url
console.log('Going to ' + url)
api.fetch(url)
.then((trueURL) => {
if (!url.endsWith('/') && trueURL.endsWith('/')) {
window.history.replaceState(window.history.state, document.title, window.location.pathname + '/')
}
this.loading = false
})
.catch(error => {
// TODO: 404, 403 and 500!
console.log(error)
this.loading = false
})
},
showUpload: function () { showUpload: function () {
if (this.req.kind === 'editor') return false if (this.req.kind === 'editor') return false
return this.user.allowNew return this.user.allowNew

View File

@ -16,11 +16,11 @@
<audio v-else-if="req.type == 'audio'" :src="raw()" controls></audio> <audio v-else-if="req.type == 'audio'" :src="raw()" controls></audio>
<video v-else-if="req.type == 'video'" :src="raw()" controls> <video v-else-if="req.type == 'video'" :src="raw()" controls>
Sorry, your browser doesn't support embedded videos, Sorry, your browser doesn't support embedded videos,
but don't worry, you can <a href="?download=true">download it</a> but don't worry, you can <a :href="download()">download it</a>
and watch it with your favorite video player! and watch it with your favorite video player!
</video> </video>
<object v-else-if="req.extension == '.pdf'" class="pdf" :data="raw()"></object> <object v-else-if="req.extension == '.pdf'" class="pdf" :data="raw()"></object>
<a v-else-if="req.type == 'blob'" href="?download=true"> <a v-else-if="req.type == 'blob'" :href="download()">
<h2 class="message">Download <i class="material-icons">file_download</i></h2> <h2 class="message">Download <i class="material-icons">file_download</i></h2>
</a> </a>
<pre v-else >{{ req.content }}</pre> <pre v-else >{{ req.content }}</pre>
@ -30,7 +30,7 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import page from '../utils/page' import url from '@/utils/url'
import InfoButton from './buttons/InfoButton' import InfoButton from './buttons/InfoButton'
import DeleteButton from './buttons/DeleteButton' import DeleteButton from './buttons/DeleteButton'
import RenameButton from './buttons/RenameButton' import RenameButton from './buttons/RenameButton'
@ -46,12 +46,19 @@ export default {
}, },
computed: mapState(['req']), computed: mapState(['req']),
methods: { methods: {
download: function () {
let url = `${this.$store.state.baseURL}/api/download/`
url += this.req.url.slice(6)
url += `?token=${this.$store.state.jwt}`
return url
},
raw: function () { raw: function () {
return this.req.url + '?raw=true' return `${this.download()}&inline=true`
}, },
back: function (event) { back: function (event) {
let url = page.removeLastDir(window.location.pathname) + '/' let uri = url.removeLastDir(this.$route.path) + '/'
page.open(url) this.$router.push({ path: uri })
}, },
allowEdit: function (event) { allowEdit: function (event) {
return this.$store.state.user.allowEdit return this.$store.state.user.allowEdit

View File

@ -26,7 +26,7 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import page from '../utils/page' import url from '@/utils/url'
export default { export default {
name: 'search', name: 'search',
@ -92,7 +92,7 @@ export default {
let uri = window.location.host + window.location.pathname let uri = window.location.host + window.location.pathname
if (this.$store.state.req.kind !== 'listing') { if (this.$store.state.req.kind !== 'listing') {
uri = page.removeLastDir(uri) + '/' uri = url.removeLastDir(uri) + '/'
} }
uri = `${(this.$store.state.ssl ? 'wss:' : 'ws:')}//${uri}` uri = `${(this.$store.state.ssl ? 'wss:' : 'ws:')}//${uri}`
@ -110,7 +110,7 @@ export default {
conn.onclose = (event) => { conn.onclose = (event) => {
this.ongoing = false this.ongoing = false
this.scrollable.scrollTop = this.scrollable.scrollHeight this.scrollable.scrollTop = this.scrollable.scrollHeight
page.reload() // page.reload()
} }
return return

View File

@ -18,7 +18,10 @@ export default {
methods: { methods: {
download: function (event) { download: function (event) {
if (this.req.kind !== 'listing') { if (this.req.kind !== 'listing') {
window.open(`${window.location.pathname}?download=true`) let url = this.$route.params[0]
url = this.$store.state.baseURL + '/api/download/' + url
url += '?token=' + this.$store.state.jwt
window.open(url)
return return
} }

View File

@ -12,8 +12,8 @@
<script> <script>
import {mapGetters, mapMutations, mapState} from 'vuex' import {mapGetters, mapMutations, mapState} from 'vuex'
import webdav from '@/utils/webdav' import api from '@/utils/api'
import page from '@/utils/page' import url from '@/utils/url'
export default { export default {
name: 'delete-prompt', name: 'delete-prompt',
@ -28,10 +28,10 @@ export default {
// buttons.setLoading('delete') // buttons.setLoading('delete')
if (this.req.kind !== 'listing') { if (this.req.kind !== 'listing') {
webdav.trash(window.location.pathname) api.delete(this.$route.path)
.then(() => { .then(() => {
// buttons.setDone('delete') // buttons.setDone('delete')
page.open(page.removeLastDir(window.location.pathname) + '/') this.$router.push({path: url.removeLastDir(this.$route.path) + '/'})
}) })
.catch(error => { .catch(error => {
// buttons.setDone('delete', false) // buttons.setDone('delete', false)
@ -49,17 +49,17 @@ export default {
let promises = [] let promises = []
for (let index of this.selected) { for (let index of this.selected) {
promises.push(webdav.trash(this.req.items[index].url)) promises.push(api.delete(this.req.items[index].url))
} }
Promise.all(promises) Promise.all(promises)
.then(() => { .then(() => {
page.reload() // page.reload()
// buttons.setDone('delete') // buttons.setDone('delete')
}) })
.catch(error => { .catch(error => {
console.log(error) console.log(error)
page.reload() // page.reload()
// buttons.setDone('delete', false) // buttons.setDone('delete', false)
}) })
} }

View File

@ -21,7 +21,10 @@ export default {
}, },
methods: { methods: {
download: function (format) { download: function (format) {
let uri = `${window.location.pathname}?download=${format}` let uri = this.$route.params[0]
uri = this.$store.state.baseURL + '/api/download/' + uri
uri += `?token=${this.$store.state.jwt}`
uri += `&format=${format}`
if (this.selectedCount > 0) { if (this.selectedCount > 0) {
let files = '' let files = ''

View File

@ -30,6 +30,7 @@
import {mapState, mapGetters} from 'vuex' import {mapState, mapGetters} from 'vuex'
import filesize from 'filesize' import filesize from 'filesize'
import moment from 'moment' import moment from 'moment'
import api from '@/utils/api'
export default { export default {
name: 'info-prompt', name: 'info-prompt',
@ -80,28 +81,21 @@ export default {
checksum: function (event, hash) { checksum: function (event, hash) {
event.preventDefault() event.preventDefault()
let request = new window.XMLHttpRequest()
let link let link
if (this.selectedCount) { if (this.selectedCount) {
link = this.req.items[this.selected[0]].url link = this.req.items[this.selected[0]].url
} else { } else {
link = window.location.pathname link = this.$route.path
} }
request.open('GET', `${link}?checksum=${hash}`, true) api.checksum(link, hash)
.then((hash) => {
request.onload = () => { event.target.innerHTML = hash
if (request.status >= 300) { })
console.log(request.statusText) .catch(error => {
return console.log(error)
} })
event.target.innerHTML = request.responseText
}
request.onerror = (e) => console.log(e)
request.send()
} }
} }
} }

View File

@ -18,8 +18,8 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import page from '@/utils/page' import url from '@/utils/url'
import webdav from '@/utils/webdav' import api from '@/utils/api'
export default { export default {
name: 'move-prompt', name: 'move-prompt',
@ -31,10 +31,10 @@ export default {
}, },
computed: mapState(['req', 'selected', 'baseURL']), computed: mapState(['req', 'selected', 'baseURL']),
mounted: function () { mounted: function () {
if (window.location.pathname !== this.baseURL + '/') { if (this.$route.path !== '/files/') {
this.items.push({ this.items.push({
name: '..', name: '..',
url: page.removeLastDir(window.location.pathname) + '/' url: url.removeLastDir(this.$route.path) + '/'
}) })
} }
@ -70,7 +70,7 @@ export default {
let to = dest + '/' + encodeURIComponent(this.req.items[item].name) let to = dest + '/' + encodeURIComponent(this.req.items[item].name)
to = to.replace('//', '/') to = to.replace('//', '/')
promises.push(webdav.move(from, to)) promises.push(api.move(from, to))
} }
this.$store.commit('showMove', false) this.$store.commit('showMove', false)
@ -78,7 +78,7 @@ export default {
Promise.all(promises) Promise.all(promises)
.then(() => { .then(() => {
// buttons.setDone('move') // buttons.setDone('move')
page.open(dest) this.$router.push({page: dest})
}) })
.catch(e => { .catch(e => {
// buttons.setDone('move', false) // buttons.setDone('move', false)
@ -86,16 +86,16 @@ export default {
}) })
}, },
next: function (event) { next: function (event) {
let url = event.currentTarget.dataset.url let uri = event.currentTarget.dataset.url
this.json(url) this.json(uri)
.then((data) => { .then((data) => {
this.current = url this.current = uri
this.items = [] this.items = []
if (url !== this.baseURL + '/') { if (uri !== this.baseURL + '/') {
this.items.push({ this.items.push({
name: '..', name: '..',
url: page.removeLastDir(url) + '/' url: url.removeLastDir(uri) + '/'
}) })
} }
@ -105,7 +105,7 @@ export default {
this.items.push({ this.items.push({
name: item.name, name: item.name,
url: item.url url: item.uri
}) })
} }
}) })

View File

@ -11,8 +11,8 @@
</template> </template>
<script> <script>
import page from '@/utils/page' import url from '@/utils/url'
import webdav from '@/utils/webdav' import api from '@/utils/api'
export default { export default {
name: 'new-dir-prompt', name: 'new-dir-prompt',
@ -26,23 +26,23 @@ export default {
event.preventDefault() event.preventDefault()
if (this.new === '') return if (this.new === '') return
let url = window.location.pathname let uri = window.location.pathname
if (this.$store.state.req.kind !== 'listing') { if (this.$store.state.req.kind !== 'listing') {
url = page.removeLastDir(url) + '/' uri = url.removeLastDir(uri) + '/'
} }
url += this.name + '/' uri += this.name + '/'
url = url.replace('//', '/') uri = uri.replace('//', '/')
// buttons.setLoading('newDir') // buttons.setLoading('newDir')
webdav.create(url) api.put(uri)
.then(() => { .then(() => {
// buttons.setDone('newDir') // buttons.setDone('newDir')
page.open(url) this.$router.push({ path: uri })
}) })
.catch(e => { .catch(error => {
// buttons.setDone('newDir', false) // buttons.setDone('newDir', false)
console.log(e) console.log(error)
}) })
this.$store.commit('showNewDir', false) this.$store.commit('showNewDir', false)

View File

@ -11,8 +11,8 @@
</template> </template>
<script> <script>
import page from '@/utils/page' import url from '@/utils/url'
import webdav from '@/utils/webdav' import api from '@/utils/api'
export default { export default {
name: 'new-file-prompt', name: 'new-file-prompt',
@ -26,23 +26,23 @@ export default {
event.preventDefault() event.preventDefault()
if (this.new === '') return if (this.new === '') return
let url = window.location.pathname let uri = window.location.pathname
if (this.$store.state.req.kind !== 'listing') { if (this.$store.state.req.kind !== 'listing') {
url = page.removeLastDir(url) + '/' uri = url.removeLastDir(uri) + '/'
} }
url += this.name uri += this.name
url = url.replace('//', '/') uri = uri.replace('//', '/')
// buttons.setLoading('newFile') // buttons.setLoading('newFile')
webdav.create(url) api.put(uri)
.then(() => { .then(() => {
// buttons.setDone('newFile') // buttons.setDone('newFile')
page.open(url) this.$router.push({ path: uri })
}) })
.catch(e => { .catch(error => {
// buttons.setDone('newFile', false) // buttons.setDone('newFile', false)
console.log(e) console.log(error)
}) })
this.$store.commit('showNewFile', false) this.$store.commit('showNewFile', false)

View File

@ -12,8 +12,8 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import page from '@/utils/page' import url from '@/utils/url'
import webdav from '@/utils/webdav' import api from '@/utils/api'
export default { export default {
name: 'rename-prompt', name: 'rename-prompt',
@ -50,19 +50,21 @@ export default {
} }
this.name = encodeURIComponent(this.name) this.name = encodeURIComponent(this.name)
newLink = page.removeLastDir(oldLink) + '/' + this.name newLink = url.removeLastDir(oldLink) + '/' + this.name
// buttons.setLoading('rename') // buttons.setLoading('rename')
webdav.move(oldLink, newLink) api.move(oldLink, newLink)
.then(() => { .then(() => {
if (this.req.kind !== 'listing') { if (this.req.kind !== 'listing') {
page.open(newLink) this.$router.push({ path: newLink })
return return
} }
// TODO: keep selected after reload? // TODO: keep selected after reload?
page.reload() // page.reload()
// buttons.setDone('rename') // buttons.setDone('rename')
console.log('reload')
this.$router.go({ path: this.$route.path })
}).catch(error => { }).catch(error => {
// buttons.setDone('rename', false) // buttons.setDone('rename', false)
console.log(error) console.log(error)

View File

@ -25,6 +25,12 @@ const router = new Router({
}) })
} }
}, },
{
path: '/',
redirect: {
path: '/files/'
}
},
{ {
path: '/*', path: '/*',
component: Main, component: Main,
@ -33,7 +39,7 @@ const router = new Router({
}, },
children: [ children: [
{ {
path: '/files*', path: '/files/*',
name: 'Files' name: 'Files'
}, },
{ {

View File

@ -1,26 +1,126 @@
import store from '../store/store' import store from '../store/store'
function removePrefix (url) {
if (url.startsWith('/files')) {
return url.slice(6)
}
return url
}
function fetch (url) { function fetch (url) {
url = removePrefix(url)
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest() let request = new window.XMLHttpRequest()
request.open('GET', `${store.state.baseURL}/api/resource${url}`, true) request.open('GET', `${store.state.baseURL}/api/resource${url}`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`) request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.onload = () => { request.onload = () => {
if (request.status === 200) { switch (request.status) {
let req = JSON.parse(request.responseText) case 200:
store.commit('updateRequest', req) let req = JSON.parse(request.responseText)
document.title = req.name store.commit('updateRequest', req)
resolve() document.title = req.name
} else { resolve(req.url)
reject() break
default:
reject(request.status)
break
} }
} }
request.onerror = () => reject() request.onerror = (error) => reject(error)
request.send()
})
}
function rm (url) {
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open('DELETE', `${store.state.baseURL}/api/resource${url}`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.onload = () => {
if (request.status === 200) {
resolve(request.responseText)
} else {
reject(request.responseText)
}
}
request.onerror = (error) => reject(error)
request.send()
})
}
function put (url) {
url = removePrefix(url)
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open('PUT', `${store.state.baseURL}/api/resource${url}`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.onload = () => {
if (request.status === 200) {
resolve(request.responseText)
} else {
reject(request.responseText)
}
}
request.onerror = (error) => reject(error)
request.send()
})
}
function move (oldLink, newLink) {
oldLink = removePrefix(oldLink)
newLink = removePrefix(newLink)
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open('POST', `${store.state.baseURL}/api/resource${oldLink}`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.setRequestHeader('Destination', newLink)
request.onload = () => {
if (request.status === 200) {
resolve(request.responseText)
} else {
reject(request.responseText)
}
}
request.onerror = (error) => reject(error)
request.send()
})
}
function checksum (url, algo) {
url = removePrefix(url)
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open('GET', `${store.state.baseURL}/api/checksum${url}?algo=${algo}`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.onload = () => {
if (request.status === 200) {
resolve(request.responseText)
} else {
reject(request.responseText)
}
}
request.onerror = (error) => reject(error)
request.send() request.send()
}) })
} }
export default { export default {
fetch delete: rm,
fetch,
checksum,
move,
put
} }

View File

@ -1,87 +0,0 @@
import store from '../store/store'
function convertURL (url) {
return window.location.origin + url.replace(store.state.baseURL + '/', store.state.webDavURL + '/')
}
function move (oldLink, newLink) {
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
oldLink = convertURL(oldLink)
newLink = newLink.replace(store.state.baseURL + '/', store.state.webDavURL + '/')
newLink = window.location.origin + newLink.substring(store.state.baseURL.length)
request.open('MOVE', oldLink, true)
request.setRequestHeader('Destination', newLink)
request.onload = () => {
if (request.status === 201 || request.status === 204) {
resolve()
} else {
reject(request.statusText)
}
}
request.onerror = () => reject(request.statusText)
request.send()
})
}
function put (link, body, headers = {}) {
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open('PUT', convertURL(link), true)
for (let key in headers) {
request.setRequestHeader(key, headers[key])
}
request.onload = () => {
if (request.status === 201) {
resolve()
} else {
reject(request.statusText)
}
}
request.onerror = () => reject(request.statusText)
request.send(body)
})
}
function trash (link) {
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open('DELETE', convertURL(link), true)
request.onload = () => {
if (request.status === 204) {
resolve()
} else {
reject(request.statusText)
}
}
request.onerror = () => reject(request.statusText)
request.send()
})
}
function create (link) {
return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest()
request.open((link.endsWith('/') ? 'MKCOL' : 'PUT'), convertURL(link), true)
request.onload = () => {
if (request.status === 201) {
resolve()
} else {
reject(request.statusText)
}
}
request.onerror = () => reject(request.statusText)
request.send()
})
}
export default {
create: create,
trash: trash,
put: put,
move: move
}

19
auth.go
View File

@ -86,16 +86,31 @@ func renewAuthHandler(c *requestContext, w http.ResponseWriter, r *http.Request)
return 0, nil return 0, nil
} }
type extractor []string
func (e extractor) ExtractToken(r *http.Request) (string, error) {
token, _ := request.AuthorizationHeaderExtractor.ExtractToken(r)
if token != "" {
return token, nil
}
token, _ = request.ArgumentExtractor{"token"}.ExtractToken(r)
if token != "" {
return token, nil
}
return "", request.ErrNoTokenInRequest
}
// validateAuth is used to validate the authentication and returns the // validateAuth is used to validate the authentication and returns the
// User if it is valid. // User if it is valid.
func validateAuth(c *requestContext, r *http.Request) (bool, *User) { func validateAuth(c *requestContext, r *http.Request) (bool, *User) {
keyFunc := func(token *jwt.Token) (interface{}, error) { keyFunc := func(token *jwt.Token) (interface{}, error) {
return c.fm.key, nil return c.fm.key, nil
} }
var claims claims var claims claims
token, err := request.ParseFromRequestWithClaims(r, token, err := request.ParseFromRequestWithClaims(r,
request.AuthorizationHeaderExtractor, extractor{},
&claims, &claims,
keyFunc, keyFunc,
) )

View File

@ -18,7 +18,12 @@ func downloadHandler(c *requestContext, w http.ResponseWriter, r *http.Request)
query := r.URL.Query().Get("format") query := r.URL.Query().Get("format")
if !c.fi.IsDir { if !c.fi.IsDir {
w.Header().Set("Content-Disposition", "attachment; filename="+c.fi.Name) if r.URL.Query().Get("inline") == "true" {
w.Header().Set("Content-Disposition", "inline")
} else {
w.Header().Set("Content-Disposition", "attachment; filename="+c.fi.Name)
}
http.ServeFile(w, r, c.fi.Path) http.ServeFile(w, r, c.fi.Path)
return 0, nil return 0, nil
} }

View File

@ -99,6 +99,11 @@ func getInfo(url *url.URL, c *FileManager, u *User) (*file, error) {
i.IsDir = info.IsDir() i.IsDir = info.IsDir()
i.Size = info.Size() i.Size = info.Size()
i.Extension = filepath.Ext(i.Name) i.Extension = filepath.Ext(i.Name)
if i.IsDir && !strings.HasSuffix(i.URL, "/") {
i.URL += "/"
}
return i, nil return i, nil
} }