mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-04-01 11:46:53 +02:00
216 lines
7.5 KiB
Vue
216 lines
7.5 KiB
Vue
<template>
|
|
<div class="w-full h-screen bg-bg">
|
|
<div class="w-full flex h-full items-center justify-center">
|
|
<div v-if="criticalError" class="w-full max-w-md rounded border border-error border-opacity-25 bg-error bg-opacity-10 p-4">
|
|
<p class="text-center text-lg font-semibold">{{ $strings.MessageServerCouldNotBeReached }}</p>
|
|
</div>
|
|
<div v-else-if="showInitScreen" class="w-full max-w-lg px-4 md:px-8 pb-8 pt-4">
|
|
<p class="text-3xl text-white text-center mb-4">Initial Server Setup</p>
|
|
<div class="w-full h-px bg-white bg-opacity-10 my-4" />
|
|
|
|
<form @submit.prevent="submitServerSetup">
|
|
<p class="text-lg font-semibold mb-2 pl-1 text-center">Create Root User</p>
|
|
<ui-text-input-with-label v-model="newRoot.username" label="Username" :disabled="processing" class="w-full mb-3 text-sm" />
|
|
<ui-text-input-with-label v-model="newRoot.password" label="Password" type="password" :disabled="processing" class="w-full mb-3 text-sm" />
|
|
<ui-text-input-with-label v-model="confirmPassword" label="Confirm Password" type="password" :disabled="processing" class="w-full mb-3 text-sm" />
|
|
|
|
<p class="text-lg font-semibold mt-6 mb-2 pl-1 text-center">Directory Paths</p>
|
|
<ui-text-input-with-label v-model="ConfigPath" label="Config Path" disabled class="w-full mb-3 text-sm" />
|
|
<ui-text-input-with-label v-model="MetadataPath" label="Metadata Path" disabled class="w-full mb-3 text-sm" />
|
|
|
|
<div class="w-full flex justify-end py-3">
|
|
<ui-btn type="submit" :disabled="processing" color="primary" class="leading-none">{{ processing ? 'Initializing...' : $strings.ButtonSubmit }}</ui-btn>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div v-else-if="isInit" class="w-full max-w-md px-8 pb-8 pt-4 -mt-40">
|
|
<p class="text-3xl text-white text-center mb-4">{{ $strings.HeaderLogin }}</p>
|
|
<div class="w-full h-px bg-white bg-opacity-10 my-4" />
|
|
<p v-if="error" class="text-error text-center py-2">{{ error }}</p>
|
|
<form @submit.prevent="submitForm">
|
|
<label class="text-xs text-gray-300 uppercase">{{ $strings.LabelUsername }}</label>
|
|
<ui-text-input v-model="username" :disabled="processing" class="mb-3 w-full" />
|
|
|
|
<label class="text-xs text-gray-300 uppercase">{{ $strings.LabelPassword }}</label>
|
|
<ui-text-input v-model="password" type="password" :disabled="processing" class="w-full mb-3" />
|
|
<div class="w-full flex justify-end py-3">
|
|
<ui-btn type="submit" :disabled="processing" color="primary" class="leading-none">{{ processing ? 'Checking...' : $strings.ButtonSubmit }}</ui-btn>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
layout: 'blank',
|
|
data() {
|
|
return {
|
|
error: null,
|
|
criticalError: null,
|
|
processing: false,
|
|
username: '',
|
|
password: null,
|
|
showInitScreen: false,
|
|
isInit: false,
|
|
newRoot: {
|
|
username: 'root',
|
|
password: ''
|
|
},
|
|
confirmPassword: '',
|
|
ConfigPath: '',
|
|
MetadataPath: ''
|
|
}
|
|
},
|
|
watch: {
|
|
user(newVal) {
|
|
if (newVal) {
|
|
if (!this.$store.state.libraries.currentLibraryId) {
|
|
// No libraries available to this user
|
|
if (this.$store.getters['user/getIsRoot']) {
|
|
// If root user go to config/libraries
|
|
this.$router.replace('/config/libraries')
|
|
} else {
|
|
this.$router.replace('/oops?message=No libraries available')
|
|
}
|
|
} else if (this.$route.query.redirect) {
|
|
this.$router.replace(this.$route.query.redirect)
|
|
} else {
|
|
this.$router.replace(`/library/${this.$store.state.libraries.currentLibraryId}`)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
user() {
|
|
return this.$store.state.user.user
|
|
}
|
|
},
|
|
methods: {
|
|
async submitServerSetup() {
|
|
if (!this.newRoot.username || !this.newRoot.username.trim()) {
|
|
this.$toast.error('Must enter a root username')
|
|
return
|
|
}
|
|
if (this.newRoot.password !== this.confirmPassword) {
|
|
this.$toast.error('Password mismatch')
|
|
return
|
|
}
|
|
if (!this.newRoot.password) {
|
|
if (!confirm('Are you sure you want to create the root user with no password?')) {
|
|
return
|
|
}
|
|
}
|
|
this.processing = true
|
|
|
|
const payload = {
|
|
newRoot: { ...this.newRoot }
|
|
}
|
|
const success = await this.$axios
|
|
.$post('/init', payload)
|
|
.then(() => true)
|
|
.catch((error) => {
|
|
console.error('Failed', error.response)
|
|
const errorMsg = error.response ? error.response.data || 'Unknown Error' : 'Unknown Error'
|
|
this.$toast.error(errorMsg)
|
|
return false
|
|
})
|
|
|
|
if (!success) {
|
|
this.processing = false
|
|
return
|
|
}
|
|
|
|
location.reload()
|
|
},
|
|
setUser({ user, userDefaultLibraryId, serverSettings, Source, ereaderDevices }) {
|
|
this.$store.commit('setServerSettings', serverSettings)
|
|
this.$store.commit('setSource', Source)
|
|
this.$store.commit('libraries/setEReaderDevices', ereaderDevices)
|
|
this.$setServerLanguageCode(serverSettings.language)
|
|
|
|
if (serverSettings.chromecastEnabled) {
|
|
console.log('Chromecast enabled import script')
|
|
require('@/plugins/chromecast.js').default(this)
|
|
}
|
|
|
|
this.$store.commit('libraries/setCurrentLibrary', userDefaultLibraryId)
|
|
this.$store.commit('user/setUser', user)
|
|
|
|
this.$store.dispatch('user/loadUserSettings')
|
|
},
|
|
async submitForm() {
|
|
this.error = null
|
|
this.processing = true
|
|
|
|
var payload = {
|
|
username: this.username,
|
|
password: this.password || ''
|
|
}
|
|
var authRes = await this.$axios.$post('/login', payload).catch((error) => {
|
|
console.error('Failed', error.response)
|
|
if (error.response) this.error = error.response.data
|
|
else this.error = 'Unknown Error'
|
|
return false
|
|
})
|
|
if (authRes && authRes.error) {
|
|
this.error = authRes.error
|
|
} else if (authRes) {
|
|
this.setUser(authRes)
|
|
}
|
|
this.processing = false
|
|
},
|
|
checkAuth() {
|
|
var token = localStorage.getItem('token')
|
|
if (!token) return false
|
|
|
|
this.processing = true
|
|
|
|
return this.$axios
|
|
.$post('/api/authorize', null, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`
|
|
}
|
|
})
|
|
.then((res) => {
|
|
this.setUser(res)
|
|
this.processing = false
|
|
return true
|
|
})
|
|
.catch((error) => {
|
|
console.error('Authorize error', error)
|
|
this.processing = false
|
|
return false
|
|
})
|
|
},
|
|
checkStatus() {
|
|
this.processing = true
|
|
this.$axios
|
|
.$get('/status')
|
|
.then((res) => {
|
|
this.processing = false
|
|
this.isInit = res.isInit
|
|
this.showInitScreen = !res.isInit
|
|
this.$setServerLanguageCode(res.language)
|
|
if (this.showInitScreen) {
|
|
this.ConfigPath = res.ConfigPath || ''
|
|
this.MetadataPath = res.MetadataPath || ''
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error('Status check failed', error)
|
|
this.processing = false
|
|
this.criticalError = 'Status check failed'
|
|
})
|
|
}
|
|
},
|
|
async mounted() {
|
|
if (localStorage.getItem('token')) {
|
|
var userfound = await this.checkAuth()
|
|
if (userfound) return // if valid user no need to check status
|
|
}
|
|
this.checkStatus()
|
|
}
|
|
}
|
|
</script> |