Skip to content

Commit

Permalink
feat(webui): claim server from login screen
Browse files Browse the repository at this point in the history
closes #207
  • Loading branch information
gotson committed Jul 5, 2020
1 parent 47dd2f6 commit d4810bd
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 6 deletions.
1 change: 1 addition & 0 deletions komga-webui/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-fallthrough': 'off',
'comma-dangle': ['error', 'always-multiline'],
},
parserOptions: {
Expand Down
2 changes: 2 additions & 0 deletions komga-webui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import App from './App.vue'
import actuator from './plugins/actuator.plugin'
import httpPlugin from './plugins/http.plugin'
import komgaBooks from './plugins/komga-books.plugin'
import komgaClaim from './plugins/komga-claim.plugin'
import komgaCollections from './plugins/komga-collections.plugin'
import komgaFileSystem from './plugins/komga-filesystem.plugin'
import komgaLibraries from './plugins/komga-libraries.plugin'
Expand All @@ -31,6 +32,7 @@ Vue.use(komgaSeries, { http: Vue.prototype.$http })
Vue.use(komgaCollections, { http: Vue.prototype.$http })
Vue.use(komgaBooks, { http: Vue.prototype.$http })
Vue.use(komgaReferential, { http: Vue.prototype.$http })
Vue.use(komgaClaim, { http: Vue.prototype.$http })
Vue.use(komgaUsers, { store: store, http: Vue.prototype.$http })
Vue.use(komgaLibraries, { store: store, http: Vue.prototype.$http })
Vue.use(actuator, { http: Vue.prototype.$http })
Expand Down
17 changes: 17 additions & 0 deletions komga-webui/src/plugins/komga-claim.plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import KomgaClaimService from '@/services/komga-claim.service'
import { AxiosInstance } from 'axios'
import _Vue from 'vue'

export default {
install (
Vue: typeof _Vue,
{ http }: { http: AxiosInstance }) {
Vue.prototype.$komgaClaim = new KomgaClaimService(http)
},
}

declare module 'vue/types/vue' {
interface Vue {
$komgaClaim: KomgaClaimService;
}
}
40 changes: 40 additions & 0 deletions komga-webui/src/services/komga-claim.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { AxiosInstance } from 'axios'

const API_CLAIM = '/api/v1/claim'

export default class KomgaClaimService {
private http: AxiosInstance

constructor (http: AxiosInstance) {
this.http = http
}

async getClaimStatus (): Promise<ClaimStatus> {
try {
return (await this.http.get(API_CLAIM)).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve claim status'
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
throw new Error(msg)
}
}

async claimServer (user: ClaimAdmin): Promise<UserDto> {
try {
return (await this.http.post(API_CLAIM, {}, {
headers: {
'X-Komga-Email': user.email,
'X-Komga-Password': user.password,
},
})).data
} catch (e) {
let msg = 'An error occurred while trying to claim server'
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
throw new Error(msg)
}
}
}
8 changes: 8 additions & 0 deletions komga-webui/src/types/komga-claim.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface ClaimStatus {
isClaimed: boolean
}

interface ClaimAdmin {
email: string,
password: string
}
55 changes: 49 additions & 6 deletions komga-webui/src/views/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,25 @@
</v-row>

<form novalidate @submit.prevent="performLogin">
<v-row justify="center" v-if="unclaimed">
<v-col
cols="12" sm="8" md="6" lg="4" xl="2"
class="body-1 mt-2"
>
<v-alert type="info"
icon="mdi-account-plus"
prominent
text
>This Komga server is not yet active, you need to create a user account to be able to access it.<br/><br/>Choose
an <strong>email</strong> and <strong>password</strong> and click on <strong>Create user account</strong>.
</v-alert>
</v-col>
</v-row>

<v-row justify="center">
<v-col cols="12" sm="8" md="6" lg="4" xl="2">
<v-text-field v-model="form.login"
label="Login"
label="Email"
autocomplete="username"
autofocus
/>
Expand All @@ -31,8 +46,15 @@
<v-col cols="12" sm="8" md="6" lg="4" xl="2">
<v-btn color="primary"
type="submit"
:disabled="unclaimed"
>Login
</v-btn>
<v-btn v-if="unclaimed"
class="ml-4"
color="primary"
@click="claim"
>Create user account
</v-btn>
</v-col>
</v-row>
</form>
Expand Down Expand Up @@ -65,23 +87,32 @@ export default Vue.extend({
},
snackbar: false,
snackText: '',
unclaimed: false,
}),
computed: {
logoWidth (): number {
let l = 100
switch (this.$vuetify.breakpoint.name) {
case 'xs':
return 100
l = 100
case 'sm':
case 'md':
return 200
l = 200
case 'lg':
case 'xl':
default:
return 400
l = 300
}
return l / (this.unclaimed ? 2 : 1)
},
},
mounted () {
this.getClaimStatus()
},
methods: {
async getClaimStatus () {
this.unclaimed = !(await this.$komgaClaim.getClaimStatus()).isClaimed
},
async performLogin () {
try {
await this.$store.dispatch(
Expand All @@ -94,9 +125,9 @@ export default Vue.extend({
await this.$store.dispatch('getLibraries')
if (this.$route.query.redirect) {
this.$router.push({ path: this.$route.query.redirect.toString() })
await this.$router.push({ path: this.$route.query.redirect.toString() })
} else {
this.$router.push({ name: 'home' })
await this.$router.push({ name: 'home' })
}
} catch (e) {
this.showSnack(e.message)
Expand All @@ -106,6 +137,18 @@ export default Vue.extend({
this.snackText = message
this.snackbar = true
},
async claim () {
try {
await this.$komgaClaim.claimServer({
email: this.form.login,
password: this.form.password,
} as ClaimAdmin)
await this.performLogin()
} catch (e) {
this.showSnack(e.message)
}
},
},
})
</script>
Expand Down

0 comments on commit d4810bd

Please sign in to comment.