Compare commits

..

1 Commits

Author SHA1 Message Date
Alf Sebastian Houge
d9a99d432c Make emails case insensitive 2022-03-07 00:17:35 +01:00
5 changed files with 63 additions and 68 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"strings"
"github.com/akhilrex/hammond/common" "github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db" "github.com/akhilrex/hammond/db"
@@ -91,7 +92,7 @@ func userLogin(c *gin.Context) {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err)) c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return return
} }
user, err := db.FindOneUser(&db.User{Email: loginRequest.Email}) user, err := db.FindOneUser(&db.User{Email: strings.ToLower(loginRequest.Email)})
if err != nil { if err != nil {
c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Not Registered email or invalid password"))) c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Not Registered email or invalid password")))

View File

@@ -18,6 +18,10 @@ var migrations = []localMigration{
Name: "2021_06_24_04_42_SetUserDisabledFalse", Name: "2021_06_24_04_42_SetUserDisabledFalse",
Query: "update users set is_disabled=0", Query: "update users set is_disabled=0",
}, },
{
Name: "2021_02_07_00_09_LowerCaseEmails",
Query: "update users set email=lower(email)",
},
} }
func RunMigrations() { func RunMigrations() {

View File

@@ -1,6 +1,8 @@
package service package service
import ( import (
"strings"
"github.com/akhilrex/hammond/db" "github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models" "github.com/akhilrex/hammond/models"
) )
@@ -8,7 +10,7 @@ import (
func CreateUser(userModel *models.RegisterRequest, role db.Role) error { func CreateUser(userModel *models.RegisterRequest, role db.Role) error {
setting := db.GetOrCreateSetting() setting := db.GetOrCreateSetting()
toCreate := db.User{ toCreate := db.User{
Email: userModel.Email, Email: strings.ToLower(userModel.Email),
Name: userModel.Name, Name: userModel.Name,
Role: role, Role: role,
Currency: setting.Currency, Currency: setting.Currency,

View File

@@ -21,27 +21,13 @@ export default {
email: '', email: '',
password: '', password: '',
distanceUnit: 1, distanceUnit: 1,
currency: '', currency: 'INR',
}, },
} }
}, },
computed: { computed: {
...mapGetters('auth', ['isInitialized']), ...mapGetters('auth', ['isInitialized']),
...mapState('vehicles', ['currencyMasters', 'distanceUnitMasters']), ...mapState('vehicles', ['currencyMasters', 'distanceUnitMasters']),
filteredCurrencyMasters() {
return this.currencyMasters.filter((option) => {
return (
option.namePlural
.toString()
.toLowerCase()
.indexOf(this.registerModel.currency.toLowerCase()) >= 0 ||
option.code
.toString()
.toLowerCase()
.indexOf(this.registerModel.currency.toLowerCase()) >= 0
)
})
},
}, },
mounted() { mounted() {
store.dispatch('vehicles/fetchMasters').then((data) => {}) store.dispatch('vehicles/fetchMasters').then((data) => {})
@@ -153,9 +139,6 @@ export default {
}) })
.finally(() => (this.isWorking = false)) .finally(() => (this.isWorking = false))
}, },
formatCurrency(option) {
return `${option.namePlural} (${option.code})`
},
}, },
} }
</script> </script>
@@ -165,10 +148,15 @@ export default {
<div v-if="!migrationMode" class="box"> <div v-if="!migrationMode" class="box">
<h1 class="title">Migrate from Clarkson</h1> <h1 class="title">Migrate from Clarkson</h1>
<p> <p>
If you have an existing Clarkson deployment and you want to migrate your data from that, press the following button. If you have an existing Clarkson deployment and you want to migrate your data from that,
press the following button.
</p> </p>
<br /> <br />
<b-field> <b-button type="is-primary" @click="migrationMode = 'clarkson'">Migrate from Clarkson</b-button></b-field> <b-field>
<b-button type="is-primary" @click="migrationMode = 'clarkson'"
>Migrate from Clarkson</b-button
></b-field
>
</div> </div>
<div v-if="!migrationMode" class="box"> <div v-if="!migrationMode" class="box">
<h1 class="title">Fresh Install</h1> <h1 class="title">Fresh Install</h1>
@@ -182,12 +170,21 @@ export default {
</div> </div>
<div v-if="migrationMode === 'clarkson'" class="box content"> <div v-if="migrationMode === 'clarkson'" class="box content">
<h1 class="title">Migrate from Clarkson</h1> <h1 class="title">Migrate from Clarkson</h1>
<p>You need to make sure that this deployment of Hammond can access the MySQL database used by Clarkson.</p>
<p>If that is not directly possible, you can make a copy of that database somewhere accessible from this instance.</p>
<p>Once that is done, enter the connection string to the MySQL instance in the following format.</p>
<p <p
>All the users imported from Clarkson will have their username as their email in Clarkson database and pasword set to >You need to make sure that this deployment of Hammond can access the MySQL database used by
<span class="" style="font-weight:bold">hammond</span></p Clarkson.</p
>
<p
>If that is not directly possible, you can make a copy of that database somewhere accessible
from this instance.</p
>
<p
>Once that is done, enter the connection string to the MySQL instance in the following
format.</p
>
<p
>All the users imported from Clarkson will have their username as their email in Clarkson
database and pasword set to <span class="" style="font-weight:bold">hammond</span></p
> >
<code> <code>
user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
@@ -203,8 +200,15 @@ export default {
</b-field> </b-field>
<div class="buttons"> <div class="buttons">
<b-button v-if="!testSuccess" type="is-primary" :disabled="isWorking" @click="testConnection">Test Connection</b-button <b-button
><b-button v-if="testSuccess" type="is-success" :disabled="isWorking" @click="migrate">Migrate</b-button> v-if="!testSuccess"
type="is-primary"
:disabled="isWorking"
@click="testConnection"
>Test Connection</b-button
><b-button v-if="testSuccess" type="is-success" :disabled="isWorking" @click="migrate"
>Migrate</b-button
>
<b-button type="is-danger is-light" @click="resetMigrationMode">Cancel</b-button> <b-button type="is-danger is-light" @click="resetMigrationMode">Cancel</b-button>
</div> </div>
</div> </div>
@@ -218,22 +222,28 @@ export default {
<b-input v-model="registerModel.email" type="email" required></b-input> <b-input v-model="registerModel.email" type="email" required></b-input>
</b-field> </b-field>
<b-field label="Your Password"> <b-field label="Your Password">
<b-input v-model="registerModel.password" type="password" required minlength="8" password-reveal></b-input> <b-input
v-model="registerModel.password"
type="password"
required
minlength="8"
password-reveal
></b-input>
</b-field> </b-field>
<b-field label="Currency"> <b-field label="Currency">
<b-autocomplete <b-select v-model="registerModel.currency" placeholder="Currency" required expanded>
v-model="registerModel.currency" <option v-for="option in currencyMasters" :key="option.code" :value="option.code">
:custom-formatter="formatCurrency" {{ `${option.namePlural} (${option.code})` }}
placeholder="Currency" </option>
:data="filteredCurrencyMasters" </b-select>
:keep-first="true"
:open-on-focus="true"
required
@select="(option) => (selected = option)"
></b-autocomplete>
</b-field> </b-field>
<b-field label="Distance Unit"> <b-field label="Distance Unit">
<b-select v-model.number="registerModel.distanceUnit" placeholder="Distance Unit" required expanded> <b-select
v-model.number="registerModel.distanceUnit"
placeholder="Distance Unit"
required
expanded
>
<option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key"> <option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key">
{{ `${option.long} (${option.short})` }} {{ `${option.long} (${option.short})` }}
</option> </option>

View File

@@ -44,20 +44,6 @@ export default {
return this.changePassModel.new === this.changePassModel.renew return this.changePassModel.new === this.changePassModel.renew
}, },
filteredCurrencyMasters() {
return this.currencyMasters.filter((option) => {
return (
option.namePlural
.toString()
.toLowerCase()
.indexOf(this.settingsModel.currency.toLowerCase()) >= 0 ||
option.code
.toString()
.toLowerCase()
.indexOf(this.settingsModel.currency.toLowerCase()) >= 0
)
})
},
}, },
methods: { methods: {
changePassword() { changePassword() {
@@ -123,9 +109,6 @@ export default {
this.tryingToSave = false this.tryingToSave = false
}) })
}, },
formatCurrency(option) {
return `${option.namePlural} (${option.code})`
},
}, },
} }
</script> </script>
@@ -140,16 +123,11 @@ export default {
These will be used as default values whenever you create a new fillup or expense. These will be used as default values whenever you create a new fillup or expense.
</h1> </h1>
<b-field label="Currency"> <b-field label="Currency">
<b-autocomplete <b-select v-model="settingsModel.currency" placeholder="Currency" required expanded>
v-model="settingsModel.currency" <option v-for="option in currencyMasters" :key="option.code" :value="option.code">
:custom-formatter="formatCurrency" {{ `${option.namePlural} (${option.code})` }}
placeholder="Currency" </option>
:data="filteredCurrencyMasters" </b-select>
:keep-first="true"
:open-on-focus="true"
required
@select="(option) => (selected = option)"
></b-autocomplete>
</b-field> </b-field>
<b-field label="Distance Unit"> <b-field label="Distance Unit">
<b-select v-model.number="settingsModel.distanceUnit" placeholder="Distance Unit" required expanded> <b-select v-model.number="settingsModel.distanceUnit" placeholder="Distance Unit" required expanded>