use i18n resource item to replace ambiguous configuration item
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
[global]
|
||||
# Application instance name
|
||||
app_name = ezBookkeeping
|
||||
|
||||
# Either "production", "development"
|
||||
mode = production
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
||||
)
|
||||
|
||||
const mcpServerName = "ezBookkeeping-mcp"
|
||||
const mcpServerName = core.ApplicationName + "-mcp"
|
||||
|
||||
// ModelContextProtocolAPI represents model context protocol api
|
||||
type ModelContextProtocolAPI struct {
|
||||
@@ -102,7 +102,7 @@ func (a *ModelContextProtocolAPI) InitializeHandler(c *core.WebContext, jsonRPCR
|
||||
},
|
||||
ServerInfo: &mcp.MCPImplementation{
|
||||
Name: mcpServerName,
|
||||
Title: a.CurrentConfig().AppName,
|
||||
Title: core.ApplicationName,
|
||||
Version: settings.Version,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func (a *TwoFactorAuthorizationsApi) TwoFactorEnableRequestHandler(c *core.WebCo
|
||||
return nil, errs.ErrNotPermittedToPerformThisAction
|
||||
}
|
||||
|
||||
key, err := a.twoFactorAuthorizations.GenerateTwoFactorSecret(c, user)
|
||||
key, err := a.twoFactorAuthorizations.GenerateTwoFactorSecret(c, user, c.GetClientLocale())
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[twofactor_authorizations.TwoFactorEnableRequestHandler] failed to generate two-factor secret, because %s", err.Error())
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package core
|
||||
|
||||
// ApplicationName represents the application name
|
||||
const ApplicationName = "ezBookkeeping"
|
||||
@@ -27,7 +27,7 @@ func (p *OpenRouterChatCompletionsAPIProvider) BuildChatCompletionsHttpRequest(c
|
||||
|
||||
req.Header.Set("Authorization", "Bearer "+p.OpenRouterAPIKey)
|
||||
req.Header.Set("HTTP-Referer", "https://ezbookkeeping.mayswind.net/")
|
||||
req.Header.Set("X-Title", "ezBookkeeping")
|
||||
req.Header.Set("X-Title", core.ApplicationName)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
@@ -6,12 +6,18 @@ import (
|
||||
|
||||
// LocaleTextItems represents all text items need to be translated
|
||||
type LocaleTextItems struct {
|
||||
GlobalTextItems *GlobalTextItems
|
||||
DefaultTypes *DefaultTypes
|
||||
DataConverterTextItems *DataConverterTextItems
|
||||
VerifyEmailTextItems *VerifyEmailTextItems
|
||||
ForgetPasswordMailTextItems *ForgetPasswordMailTextItems
|
||||
}
|
||||
|
||||
// GlobalTextItems represents global text items need to be translated
|
||||
type GlobalTextItems struct {
|
||||
AppName string
|
||||
}
|
||||
|
||||
// DefaultTypes represents default types for the language
|
||||
type DefaultTypes struct {
|
||||
DecimalSeparator core.DecimalSeparator
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var de = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var en = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var es = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var fr = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var it = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var ja = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var kn = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var ko = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var nl = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var ptBR = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var ru = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var th = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var tr = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var uk = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var vi = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var zhHans = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
)
|
||||
|
||||
var zhHant = &LocaleTextItems{
|
||||
GlobalTextItems: &GlobalTextItems{
|
||||
AppName: "ezBookkeeping",
|
||||
},
|
||||
DefaultTypes: &DefaultTypes{
|
||||
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
|
||||
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
|
||||
|
||||
@@ -59,7 +59,7 @@ func (s *ForgetPasswordService) SendPasswordResetEmail(c core.Context, user *mod
|
||||
}
|
||||
|
||||
templateParams := map[string]any{
|
||||
"AppName": s.CurrentConfig().AppName,
|
||||
"AppName": localeTextItems.GlobalTextItems.AppName,
|
||||
"ForgetPasswordMail": map[string]any{
|
||||
"Title": forgetPasswordTextItems.Title,
|
||||
"Salutation": fmt.Sprintf(forgetPasswordTextItems.SalutationFormat, user.Nickname),
|
||||
|
||||
@@ -21,13 +21,13 @@ import (
|
||||
)
|
||||
|
||||
// TokenUserAgentCreatedViaCli is the user agent of token created via cli
|
||||
const TokenUserAgentCreatedViaCli = "ezbookkeeping Cli"
|
||||
const TokenUserAgentCreatedViaCli = core.ApplicationName + " Cli"
|
||||
|
||||
// TokenUserAgentForAPI is the user agent for API token
|
||||
const TokenUserAgentForAPI = "ezbookkeeping API"
|
||||
const TokenUserAgentForAPI = core.ApplicationName + " API"
|
||||
|
||||
// TokenUserAgentForMCP is the user agent for MCP token
|
||||
const TokenUserAgentForMCP = "ezbookkeeping MCP"
|
||||
const TokenUserAgentForMCP = core.ApplicationName + " MCP"
|
||||
|
||||
const tokenMaxExpiredAtUnixTime = int64(253402300799) // 9999-12-31 23:59:59 UTC
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/datastore"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/locales"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
||||
@@ -70,13 +71,21 @@ func (s *TwoFactorAuthorizationService) GetUserTwoFactorSettingByUid(c core.Cont
|
||||
}
|
||||
|
||||
// GenerateTwoFactorSecret generates a new 2fa secret
|
||||
func (s *TwoFactorAuthorizationService) GenerateTwoFactorSecret(c core.Context, user *models.User) (*otp.Key, error) {
|
||||
func (s *TwoFactorAuthorizationService) GenerateTwoFactorSecret(c core.Context, user *models.User, backupLocale string) (*otp.Key, error) {
|
||||
if user == nil {
|
||||
return nil, errs.ErrUserNotFound
|
||||
}
|
||||
|
||||
locale := user.Language
|
||||
|
||||
if locale == "" {
|
||||
locale = backupLocale
|
||||
}
|
||||
|
||||
localeTextItems := locales.GetLocaleTextItems(locale)
|
||||
|
||||
key, err := totp.Generate(totp.GenerateOpts{
|
||||
Issuer: s.CurrentConfig().AppName,
|
||||
Issuer: localeTextItems.GlobalTextItems.AppName,
|
||||
AccountName: user.Username,
|
||||
Period: twoFactorPeriod,
|
||||
SecretSize: twoFactorSecretSize,
|
||||
|
||||
@@ -684,14 +684,14 @@ func (s *UserService) SendVerifyEmail(user *models.User, verifyEmailToken string
|
||||
}
|
||||
|
||||
templateParams := map[string]any{
|
||||
"AppName": s.CurrentConfig().AppName,
|
||||
"AppName": localeTextItems.GlobalTextItems.AppName,
|
||||
"VerifyEmail": map[string]any{
|
||||
"Title": verifyEmailTextItems.Title,
|
||||
"Salutation": fmt.Sprintf(verifyEmailTextItems.SalutationFormat, user.Nickname),
|
||||
"DescriptionAboveBtn": verifyEmailTextItems.DescriptionAboveBtn,
|
||||
"VerifyEmailUrl": verifyEmailUrl,
|
||||
"VerifyEmail": verifyEmailTextItems.VerifyEmail,
|
||||
"DescriptionBelowBtn": fmt.Sprintf(verifyEmailTextItems.DescriptionBelowBtnFormat, s.CurrentConfig().AppName, expireTimeInMinutes),
|
||||
"DescriptionBelowBtn": fmt.Sprintf(verifyEmailTextItems.DescriptionBelowBtnFormat, localeTextItems.GlobalTextItems.AppName, expireTimeInMinutes),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -145,8 +145,6 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultAppName string = "ezBookkeeping"
|
||||
|
||||
defaultHttpAddr string = "0.0.0.0"
|
||||
defaultHttpPort uint16 = 8080
|
||||
defaultDomain string = "localhost"
|
||||
@@ -267,7 +265,6 @@ type MultiLanguageContentConfig struct {
|
||||
// Config represents the global setting config
|
||||
type Config struct {
|
||||
// Global
|
||||
AppName string
|
||||
Mode SystemMode
|
||||
WorkingPath string
|
||||
|
||||
@@ -595,8 +592,6 @@ func GetDefaultConfigFilePath() (string, error) {
|
||||
}
|
||||
|
||||
func loadGlobalConfiguration(config *Config, configFile *ini.File, sectionName string) error {
|
||||
config.AppName = getConfigItemStringValue(configFile, sectionName, "app_name", defaultAppName)
|
||||
|
||||
if getConfigItemStringValue(configFile, sectionName, "mode") == "production" {
|
||||
config.Mode = MODE_PRODUCTION
|
||||
} else if getConfigItemStringValue(configFile, sectionName, "mode") == "development" {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package settings
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
)
|
||||
|
||||
// ConfigContainer contains the current setting config
|
||||
type ConfigContainer struct {
|
||||
@@ -27,8 +31,8 @@ func (c *ConfigContainer) GetCurrentConfig() *Config {
|
||||
|
||||
func GetUserAgent() string {
|
||||
if Version == "" {
|
||||
return "ezBookkeeping"
|
||||
return core.ApplicationName
|
||||
}
|
||||
|
||||
return fmt.Sprintf("ezBookkeeping/%s", Version)
|
||||
return fmt.Sprintf("%s/%s", core.ApplicationName, Version)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
expectedObject := &settings.Config{
|
||||
AppName: "ezbookkeeping",
|
||||
Mode: settings.MODE_PRODUCTION,
|
||||
DatabaseConfig: &settings.DatabaseConfig{
|
||||
DatabaseType: settings.MySqlDbType,
|
||||
|
||||
Reference in New Issue
Block a user