Add user settings and ability to change lang
This commit is contained in:
parent
156c894e07
commit
bf5f35daf3
|
@ -61,6 +61,7 @@ type DisplayUser struct {
|
|||
Id int64 `json:"id"`
|
||||
Email string `json:"email"`
|
||||
RegistrationTime *time.Time `json:"registration_time,omitempty"`
|
||||
Settings happydns.UserSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
func currentUser(u *happydns.User) *DisplayUser {
|
||||
|
@ -68,6 +69,7 @@ func currentUser(u *happydns.User) *DisplayUser {
|
|||
Id: u.Id,
|
||||
Email: u.Email,
|
||||
RegistrationTime: u.RegistrationTime,
|
||||
Settings: u.Settings,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
29
api/users.go
29
api/users.go
|
@ -58,6 +58,8 @@ func init() {
|
|||
router.POST("/api/users", ApiHandler(registerUser))
|
||||
router.PATCH("/api/users", ApiHandler(specialUserOperations))
|
||||
router.GET("/api/users/:uid", apiAuthHandler(sameUserHandler(getUser)))
|
||||
router.GET("/api/users/:uid/settings", apiAuthHandler(sameUserHandler(getUserSettings)))
|
||||
router.POST("/api/users/:uid/settings", apiAuthHandler(sameUserHandler(changeUserSettings)))
|
||||
router.POST("/api/users/:uid/delete", apiAuthHandler(sameUserHandler(deleteUser)))
|
||||
router.POST("/api/users/:uid/email", ApiHandler(userHandler(validateUserAddress)))
|
||||
router.POST("/api/users/:uid/new_password", apiAuthHandler(sameUserHandler(changePassword)))
|
||||
|
@ -254,6 +256,33 @@ func getUser(opts *config.Options, req *RequestResources, _ io.Reader) Response
|
|||
}
|
||||
}
|
||||
|
||||
func getUserSettings(opts *config.Options, req *RequestResources, _ io.Reader) Response {
|
||||
return APIResponse{
|
||||
response: req.User.Settings,
|
||||
}
|
||||
}
|
||||
|
||||
func changeUserSettings(opts *config.Options, req *RequestResources, body io.Reader) Response {
|
||||
var us happydns.UserSettings
|
||||
if err := json.NewDecoder(body).Decode(&us); err != nil {
|
||||
return APIErrorResponse{
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
req.User.Settings = us
|
||||
|
||||
if err := storage.MainStore.UpdateUser(req.User); err != nil {
|
||||
return APIErrorResponse{
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return APIResponse{
|
||||
response: req.User.Settings,
|
||||
}
|
||||
}
|
||||
|
||||
type passwordForm struct {
|
||||
Current string
|
||||
Password string
|
||||
|
|
|
@ -156,6 +156,9 @@ export default {
|
|||
(response) => {
|
||||
sessionStorage.loggedUser = JSON.stringify(response.data)
|
||||
this.loggedUser = response.data
|
||||
if (this.loggedUser.settings && this.loggedUser.settings.language && this.$i18n.locale !== this.loggedUser.settings.language) {
|
||||
this.$i18n.locale = this.loggedUser.settings.language
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
this.loggedUser = null
|
||||
|
|
|
@ -19,5 +19,6 @@ function loadLocaleMessages () {
|
|||
export default new VueI18n({
|
||||
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
|
||||
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
|
||||
messages: loadLocaleMessages()
|
||||
messages: loadLocaleMessages(),
|
||||
silentTranslationWarn: process.env.NODE_ENV === 'production'
|
||||
})
|
||||
|
|
|
@ -157,6 +157,7 @@
|
|||
"registration": "Registration problem",
|
||||
"rr-add": "An error occurs when trying to add RR to the zone:",
|
||||
"rr-delete": "An error occurs when trying to delete RR in the zone:",
|
||||
"settings-change": "Unable to change your settings",
|
||||
"source-delete": "Something went wrong during source deletion",
|
||||
"session": {
|
||||
"title": "Authentication timeout",
|
||||
|
@ -216,6 +217,13 @@
|
|||
"delete": "@:common.delete service",
|
||||
"update": "Update service"
|
||||
},
|
||||
"settings": {
|
||||
"language": "Language",
|
||||
"save": "Save settings",
|
||||
"title": "Settings",
|
||||
"success": "Continue to enjoy happyDNS.",
|
||||
"success-change": "Your settings has been saved."
|
||||
},
|
||||
"source": {
|
||||
"available-types": "Resources Types available",
|
||||
"delete": "@:common.delete this @:source.kind",
|
||||
|
|
|
@ -33,6 +33,26 @@
|
|||
|
||||
<template>
|
||||
<b-container class="my-4">
|
||||
<h2 id="settings">
|
||||
{{ $t('settings.title') }}
|
||||
</h2>
|
||||
<b-row>
|
||||
<b-card v-if="settings" class="offset-md-2 col-8">
|
||||
<b-form @submit.stop.prevent="saveSettings">
|
||||
<b-form-group
|
||||
:label="$t('settings.language')"
|
||||
label-for="language-select"
|
||||
>
|
||||
<b-form-select id="language-select" v-model="settings.language" :options="languages" />
|
||||
</b-form-group>
|
||||
<div class="d-flex justify-content-around">
|
||||
<b-button type="submit" variant="primary">
|
||||
{{ $t('settings.save') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
</b-card>
|
||||
</b-row>
|
||||
<h2 id="password-change">
|
||||
{{ $t('password.change') }}
|
||||
</h2>
|
||||
|
@ -151,6 +171,7 @@ export default {
|
|||
return {
|
||||
deletePassword: '',
|
||||
loggedUser: null,
|
||||
settings: null,
|
||||
signupForm: {
|
||||
current: '',
|
||||
password: '',
|
||||
|
@ -161,7 +182,13 @@ export default {
|
|||
|
||||
computed: {
|
||||
isLoading () {
|
||||
return this.loggedUser != null
|
||||
return this.loggedUser != null || this.settings != null
|
||||
},
|
||||
languages () {
|
||||
return {
|
||||
en: 'English',
|
||||
fr: 'Français'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -170,6 +197,11 @@ export default {
|
|||
.then(
|
||||
(response) => {
|
||||
this.loggedUser = response.data
|
||||
axios.get('/api/users/' + encodeURIComponent(this.loggedUser.id.toString(16)) + '/settings')
|
||||
.then(
|
||||
(response) => {
|
||||
this.settings = response.data
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
|
@ -205,6 +237,31 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
saveSettings () {
|
||||
axios
|
||||
.post('/api/users/' + encodeURIComponent(this.loggedUser.id.toString(16)) + '/settings', this.settings)
|
||||
.then(
|
||||
response => {
|
||||
this.settings = response.data
|
||||
this.$root.$bvToast.toast(this.$t('settings.success'), {
|
||||
title: this.$t('settings.success-change'),
|
||||
autoHideDelay: 5000,
|
||||
variant: 'success',
|
||||
toaster: 'b-toaster-content-right'
|
||||
})
|
||||
},
|
||||
error => {
|
||||
this.$bvToast.toast(
|
||||
error.response.data.errmsg, {
|
||||
title: this.$t('errors.settings-change'),
|
||||
autoHideDelay: 5000,
|
||||
variant: 'danger',
|
||||
toaster: 'b-toaster-content-right'
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
sendChPassword () {
|
||||
axios
|
||||
.post('/api/users/' + encodeURIComponent(this.loggedUser.id.toString(16)) + '/new_password', this.signupForm)
|
||||
|
|
|
@ -62,6 +62,9 @@ type User struct {
|
|||
|
||||
// PasswordRecoveryKey is a string generated when User asks to recover its account.
|
||||
PasswordRecoveryKey []byte `json:",omitempty"`
|
||||
|
||||
// Settings holds the settings for an account.
|
||||
Settings UserSettings `json:settings,omitempty`
|
||||
}
|
||||
|
||||
// Users is a group of User.
|
||||
|
|
39
model/usersettings.go
Normal file
39
model/usersettings.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright or © or Copr. happyDNS (2020)
|
||||
//
|
||||
// contact@happydns.org
|
||||
//
|
||||
// This software is a computer program whose purpose is to provide a modern
|
||||
// interface to interact with DNS systems.
|
||||
//
|
||||
// This software is governed by the CeCILL license under French law and abiding
|
||||
// by the rules of distribution of free software. You can use, modify and/or
|
||||
// redistribute the software under the terms of the CeCILL license as
|
||||
// circulated by CEA, CNRS and INRIA at the following URL
|
||||
// "http://www.cecill.info".
|
||||
//
|
||||
// As a counterpart to the access to the source code and rights to copy, modify
|
||||
// and redistribute granted by the license, users are provided only with a
|
||||
// limited warranty and the software's author, the holder of the economic
|
||||
// rights, and the successive licensors have only limited liability.
|
||||
//
|
||||
// In this respect, the user's attention is drawn to the risks associated with
|
||||
// loading, using, modifying and/or developing or reproducing the software by
|
||||
// the user in light of its specific status of free software, that may mean
|
||||
// that it is complicated to manipulate, and that also therefore means that it
|
||||
// is reserved for developers and experienced professionals having in-depth
|
||||
// computer knowledge. Users are therefore encouraged to load and test the
|
||||
// software's suitability as regards their requirements in conditions enabling
|
||||
// the security of their systems and/or data to be ensured and, more generally,
|
||||
// to use and operate it in the same conditions as regards security.
|
||||
//
|
||||
// The fact that you are presently reading this means that you have had
|
||||
// knowledge of the CeCILL license and that you accept its terms.
|
||||
|
||||
package happydns
|
||||
|
||||
import ()
|
||||
|
||||
// UserSettings represents the settings for an account.
|
||||
type UserSettings struct {
|
||||
Language string `json:"language,omitempty"`
|
||||
}
|
Loading…
Reference in New Issue
Block a user