Merge pull request #425 from h3poteto/iss-402

closes #402 Validate domain name at login
This commit is contained in:
AkiraFukushima 2018-07-05 00:49:49 +09:00 committed by GitHub
commit 671ced9af5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 126 deletions

View File

@ -1,57 +0,0 @@
<template>
<div id="instance_form">
<el-form ref="instanceForm" label-width="120px" label-position="top" class="instance-form" v-on:submit.prevent="search">
<el-form-item label="Domain name">
<el-input v-model="instanceForm.domain" class="input" ref="domain" autofocus></el-input>
</el-form-item>
<el-form-item class="submit">
<el-button type="primary" @click="search" native-type="submit">Search</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'instance-form',
data () {
return {
instanceForm: {
domain: ''
}
}
},
mounted () {
this.$refs.domain.$el.getElementsByTagName('input')[0].focus()
},
methods: {
search () {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
this.$store.dispatch('Login/searchInstance', this.instanceForm.domain)
.then(() => {
loading.close()
this.$store.commit('Login/changePage', 2)
})
.catch(() => {
loading.close()
this.$message({
message: 'Instance not found',
type: 'error'
})
})
}
}
}
</script>
<style lang="scss" scoped>
.instance-form {
width: 400px;
margin: 0 auto;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<el-form ref="loginForm" label-width="120px" label-position="top" v-on:submit.prevent="confirm" class="login-form">
<el-form-item label="First, let's log in to a Mastodon instance. Please enter an instance domain name.">
<el-input v-model="domainName" placeholder="mastodon.social"></el-input>
<el-form ref="loginForm" label-width="120px" label-position="top" v-on:submit.prevent="confirm('loginForm')" class="login-form" :rules="rules" :model="form">
<el-form-item label="First, let's log in to a Mastodon instance. Please enter an instance domain name." prop="domainName">
<el-input v-model="form.domainName" placeholder="mastodon.social"></el-input>
</el-form-item>
<!-- Dummy form to guard submitting with enter -->
<el-form-item class="hidden">
@ -9,7 +9,7 @@
</el-form-item>
<el-button
type="primary"
@click="confirm"
@click="confirm('loginForm')"
v-if="selectedInstance === null"
v-loading="searching"
element-loading-background="rgba(0, 0, 0, 0.8)">
@ -32,19 +32,32 @@ import { mapState } from 'vuex'
export default {
name: 'login-form',
data () {
return {
form: {
domainName: ''
},
rules: {
domainName: [
{
type: 'string',
required: true,
message: 'Domain name is required'
},
{
pattern: /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/,
trigger: 'change',
message: 'Please write only domain name'
}
]
}
}
},
computed: {
...mapState({
selectedInstance: state => state.Login.selectedInstance,
searching: state => state.Login.searching
}),
domainName: {
get () {
return this.$store.state.Login.domainName
},
set (value) {
this.$store.dispatch('Login/updateDomainName', value)
}
}
})
},
methods: {
login () {
@ -68,20 +81,30 @@ export default {
})
})
},
confirm () {
this.$store.dispatch('Login/confirmInstance', this.domainName)
.then(() => {
confirm (formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$store.dispatch('Login/confirmInstance', this.form.domainName)
.then(() => {
this.$message({
message: `${this.form.domainName} is confirmed, please login`,
type: 'success'
})
})
.catch(() => {
this.$message({
message: `${this.form.domainName} does not exist`,
type: 'error'
})
})
} else {
this.$message({
message: `${this.domainName} is confirmed, please login`,
type: 'success'
})
})
.catch(() => {
this.$message({
message: `${this.domainName} does not exist`,
message: 'Please write only domain name',
type: 'error'
})
})
return false
}
})
}
}
}

View File

@ -5,50 +5,18 @@ const Login = {
namespaced: true,
state: {
instances: [],
domainName: '',
selectedInstance: null,
page: 2,
searching: false
},
mutations: {
updateInstances (state, instances) {
state.instances = instances
},
changeInstance (state, instance) {
state.selectedInstance = instance
},
changePage (state, page) {
// Invalidate page changer until implement instance search form
// state.page = page
},
updateDomainName (state, domain) {
state.domainName = domain
},
changeSearching (state, value) {
state.searching = value
}
},
actions: {
searchInstance ({ commit }, domain) {
return new Promise((resolve, reject) => {
ipcRenderer.send('get-social-token', 'get')
ipcRenderer.once('error-get-social-token', (event, err) => {
ipcRenderer.removeAllListeners('response-get-social-token')
reject(err)
})
ipcRenderer.once('response-get-social-token', (event, token) => {
ipcRenderer.removeAllListeners('error-get-social-token')
axios
.get(`https://instances.social/api/1.0/instances/search?q=${domain}`, {
'headers': { 'Authorization': `Bearer ${token}` }
})
.then((res) => {
commit('updateInstances', res.data.instances)
resolve(res)
})
})
})
},
fetchLogin ({ commit }, instance) {
return new Promise((resolve, reject) => {
ipcRenderer.send('get-auth-url', instance)
@ -62,14 +30,8 @@ const Login = {
})
})
},
changeInstance ({ commit }, instance) {
commit('changeInstance', instance)
},
pageBack ({ commit }) {
commit('changePage', 1)
commit('updateInstances', [])
commit('changeInstance', null)
commit('updateDomainName', '')
},
confirmInstance ({ commit }, domain) {
return new Promise((resolve, reject) => {
@ -77,19 +39,13 @@ const Login = {
axios
.get(`https://${domain}/api/v1/instance`)
.then((res) => {
commit('changeSearching', false)
commit('changeInstance', domain)
resolve(res)
})
.catch((err) => {
.finally(() => {
commit('changeSearching', false)
reject(err)
})
})
},
updateDomainName ({ commit }, domain) {
commit('updateDomainName', domain)
commit('changeInstance', null)
}
}
}