support set gravatar as user avatar provider
This commit is contained in:
@@ -106,6 +106,11 @@ request_id_header = true
|
||||
# Set to true to allow users to register account by themselves
|
||||
enable_register = true
|
||||
|
||||
# User avatar provider, supports the following types:
|
||||
# "gravatar": https://gravatar.com
|
||||
# Leave blank if you want to disable user avatar
|
||||
avatar_provider =
|
||||
|
||||
[data]
|
||||
# Set to true to allow users to export their data
|
||||
enable_export = true
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -77,6 +78,7 @@ type UserBasicInfo struct {
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Nickname string `json:"nickname"`
|
||||
AvatarUrl string `json:"avatar"`
|
||||
DefaultAccountId int64 `json:"defaultAccountId,string"`
|
||||
TransactionEditScope TransactionEditScope `json:"transactionEditScope"`
|
||||
Language string `json:"language"`
|
||||
@@ -133,6 +135,7 @@ type UserProfileResponse struct {
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Nickname string `json:"nickname"`
|
||||
AvatarUrl string `json:"avatar"`
|
||||
DefaultAccountId int64 `json:"defaultAccountId,string"`
|
||||
TransactionEditScope TransactionEditScope `json:"transactionEditScope"`
|
||||
Language string `json:"language"`
|
||||
@@ -193,6 +196,7 @@ func (u *User) ToUserBasicInfo() *UserBasicInfo {
|
||||
Username: u.Username,
|
||||
Email: u.Email,
|
||||
Nickname: u.Nickname,
|
||||
AvatarUrl: u.getAvatarUrl(),
|
||||
DefaultAccountId: u.DefaultAccountId,
|
||||
TransactionEditScope: u.TransactionEditScope,
|
||||
Language: u.Language,
|
||||
@@ -211,6 +215,7 @@ func (u *User) ToUserProfileResponse() *UserProfileResponse {
|
||||
Username: u.Username,
|
||||
Email: u.Email,
|
||||
Nickname: u.Nickname,
|
||||
AvatarUrl: u.getAvatarUrl(),
|
||||
DefaultAccountId: u.DefaultAccountId,
|
||||
TransactionEditScope: u.TransactionEditScope,
|
||||
Language: u.Language,
|
||||
@@ -223,3 +228,13 @@ func (u *User) ToUserProfileResponse() *UserProfileResponse {
|
||||
LastLoginAt: u.LastLoginUnixTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *User) getAvatarUrl() string {
|
||||
avatarProvider := settings.Container.Current.AvatarProvider
|
||||
|
||||
if avatarProvider == settings.GravatarProvider {
|
||||
return utils.GetGravatarUrl(u.Email)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -62,6 +62,11 @@ const (
|
||||
InternalUuidGeneratorType string = "internal"
|
||||
)
|
||||
|
||||
// User avatar provider types
|
||||
const (
|
||||
GravatarProvider string = "gravatar"
|
||||
)
|
||||
|
||||
// Map provider types
|
||||
const (
|
||||
OpenStreetMapProvider string = "openstreetmap"
|
||||
@@ -185,6 +190,7 @@ type Config struct {
|
||||
|
||||
// User
|
||||
EnableUserRegister bool
|
||||
AvatarProvider string
|
||||
|
||||
// Data
|
||||
EnableDataExport bool
|
||||
@@ -444,6 +450,12 @@ func loadSecurityConfiguration(config *Config, configFile *ini.File, sectionName
|
||||
func loadUserConfiguration(config *Config, configFile *ini.File, sectionName string) error {
|
||||
config.EnableUserRegister = getConfigItemBoolValue(configFile, sectionName, "enable_register", false)
|
||||
|
||||
if getConfigItemStringValue(configFile, sectionName, "avatar_provider") == "" {
|
||||
config.AvatarProvider = ""
|
||||
} else if getConfigItemStringValue(configFile, sectionName, "avatar_provider") == GravatarProvider {
|
||||
config.AvatarProvider = GravatarProvider
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
const gravatarUrlFormat = "https://www.gravatar.com/avatar/%s"
|
||||
|
||||
// GetGravatarUrl returns the Gravatar url according to the specified user email address
|
||||
func GetGravatarUrl(email string) string {
|
||||
emailMd5 := MD5EncodeToString([]byte(email))
|
||||
return fmt.Sprintf(gravatarUrlFormat, emailMd5)
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
@@ -133,6 +134,12 @@ func MD5Encode(data []byte) []byte {
|
||||
return m.Sum(nil)
|
||||
}
|
||||
|
||||
// MD5EncodeToString returns a hashed string by md5
|
||||
func MD5EncodeToString(data []byte) string {
|
||||
hash := MD5Encode(data)
|
||||
return hex.EncodeToString(hash)
|
||||
}
|
||||
|
||||
// AESGCMEncrypt returns a encrypted string by aes-gcm
|
||||
func AESGCMEncrypt(key []byte, plainText []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
|
||||
@@ -16,6 +16,10 @@ export const useUserStore = defineStore('user', {
|
||||
const userInfo = state.currentUserInfo || {};
|
||||
return userInfo.nickname || userInfo.username || null;
|
||||
},
|
||||
currentUserAvatar(state) {
|
||||
const userInfo = state.currentUserInfo || {};
|
||||
return userInfo.avatar || null;
|
||||
},
|
||||
currentUserDefaultAccountId(state) {
|
||||
const userInfo = state.currentUserInfo || {};
|
||||
return userInfo.defaultAccountId || '';
|
||||
|
||||
@@ -113,14 +113,16 @@
|
||||
<v-icon :icon="(theme === 'light' ? icons.themeLight : (theme === 'dark' ? icons.themeDark : icons.themeAuto))" size="24" />
|
||||
</v-btn>
|
||||
<v-avatar class="cursor-pointer" color="primary" variant="tonal">
|
||||
<v-icon :icon="icons.user"/>
|
||||
<v-img :src="currentUserAvatar" v-if="currentUserAvatar"/>
|
||||
<v-icon :icon="icons.user" v-else-if="!currentUserAvatar"/>
|
||||
<v-menu activator="parent" width="230" location="bottom end" offset="14px">
|
||||
<v-list>
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-list-item-action start>
|
||||
<v-avatar color="primary" variant="tonal">
|
||||
<v-icon :icon="icons.user"/>
|
||||
<v-img :src="currentUserAvatar" v-if="currentUserAvatar"/>
|
||||
<v-icon :icon="icons.user" v-else-if="!currentUserAvatar"/>
|
||||
</v-avatar>
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
@@ -264,6 +266,9 @@ export default {
|
||||
currentNickName() {
|
||||
return this.userStore.currentUserNickname || this.$t('User');
|
||||
},
|
||||
currentUserAvatar() {
|
||||
return this.userStore.currentUserAvatar;
|
||||
},
|
||||
theme: {
|
||||
get: function () {
|
||||
return this.settingsStore.appSettings.theme;
|
||||
|
||||
Reference in New Issue
Block a user