♻️ Replace i18n services with nexus one
This commit is contained in:
parent
ec0048042a
commit
eaa8fb5225
14
.idea/workspace.xml
generated
14
.idea/workspace.xml
generated
@ -4,9 +4,17 @@
|
||||
<option name="autoReloadType" value="ALL" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":sparkles: Register with preferred language">
|
||||
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":necktie: Limit max auth steps to 2 for normal users">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/internal/gap/server.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/internal/gap/server.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/internal/services/factors.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/internal/services/factors.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/internal/services/i18n.go" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/internal/services/reports.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/internal/services/reports.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/internal/services/ticket.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/internal/services/ticket.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/internal/services/tokens.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/internal/services/tokens.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pkg/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/main.go" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -159,7 +167,6 @@
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<MESSAGE value=":boom: Passing relationship api arguments in body instead of querystring" />
|
||||
<MESSAGE value=":sparkles: Better check in experience random algorithm" />
|
||||
<MESSAGE value=":sparkles: Better relationships stauts query" />
|
||||
<MESSAGE value=":truck: Move make friendship api" />
|
||||
@ -184,7 +191,8 @@
|
||||
<MESSAGE value=":bug: Bug fixes on localization" />
|
||||
<MESSAGE value=":bug: Fix email html rendering" />
|
||||
<MESSAGE value=":sparkles: Register with preferred language" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value=":sparkles: Register with preferred language" />
|
||||
<MESSAGE value=":necktie: Limit max auth steps to 2 for normal users" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value=":necktie: Limit max auth steps to 2 for normal users" />
|
||||
<option name="GROUP_MULTIFILE_MERGE_BY_DIRECTORY" value="true" />
|
||||
</component>
|
||||
<component name="VgoProject">
|
||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module git.solsynth.dev/hypernet/passport
|
||||
go 1.23.2
|
||||
|
||||
require (
|
||||
git.solsynth.dev/hypernet/nexus v0.0.0-20241123050605-25ab1371739b
|
||||
git.solsynth.dev/hypernet/nexus v0.0.0-20250202054714-6de240179f9c
|
||||
git.solsynth.dev/hypernet/pusher v0.0.0-20241228030233-50ff8304e465
|
||||
git.solsynth.dev/hypernet/wallet v0.0.0-20250129150034-87b94cdb5488
|
||||
github.com/dgraph-io/ristretto v0.2.0
|
||||
|
2
go.sum
2
go.sum
@ -35,6 +35,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
git.solsynth.dev/hypernet/nexus v0.0.0-20241123050605-25ab1371739b h1:8yB9kMwEMY/nIbmDDxrhH5sTypgmK5PIIiIfP5QXx4s=
|
||||
git.solsynth.dev/hypernet/nexus v0.0.0-20241123050605-25ab1371739b/go.mod h1:PhLCv2lsNoscPVJbkWnxwQnJ141lc4RIEkVffrHwl4s=
|
||||
git.solsynth.dev/hypernet/nexus v0.0.0-20250202054714-6de240179f9c h1:z0//UGRwyZq1TIvn5/fGK5GCXr837KLFD3K0AkaKDyY=
|
||||
git.solsynth.dev/hypernet/nexus v0.0.0-20250202054714-6de240179f9c/go.mod h1:v+rpf1ZDRi8moaThTAkj5DMQU+rw96YTHcN8/7n/p2Y=
|
||||
git.solsynth.dev/hypernet/pusher v0.0.0-20241228030233-50ff8304e465 h1:KFtv9lF0JMUGsq1uHwQvop8PTyqdiLuUQuRrd5WmzPk=
|
||||
git.solsynth.dev/hypernet/pusher v0.0.0-20241228030233-50ff8304e465/go.mod h1:XHTqFU/vBe4JiuAjl87GUcL8+w/IizSNoqH6n3WkQFc=
|
||||
git.solsynth.dev/hypernet/wallet v0.0.0-20250129150034-87b94cdb5488 h1:/9Ol+PfDQFAYtHo0kk6sxqiEsZ6epb6yUEsZJxy14Mk=
|
||||
|
@ -3,6 +3,7 @@ package gap
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -81,3 +82,7 @@ func InitializeToNexus() error {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func LoadLocalization() error {
|
||||
return localize.LoadLocalization(viper.GetString("locales_path"), viper.GetString("templates_path"))
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -76,8 +77,8 @@ func GetFactorCode(factor models.AuthFactor, ip string) (bool, error) {
|
||||
|
||||
err = PushNotification(models.Notification{
|
||||
Topic: "passport.security.otp",
|
||||
Title: GetLocalizedString("subjectLoginOneTimePassword", user.Language),
|
||||
Body: fmt.Sprintf(GetLocalizedString("shortBodyLoginOneTimePassword", user.Language), secret),
|
||||
Title: localize.L.GetLocalizedString("subjectLoginOneTimePassword", user.Language),
|
||||
Body: fmt.Sprintf(localize.L.GetLocalizedString("shortBodyLoginOneTimePassword", user.Language), secret),
|
||||
Account: user,
|
||||
AccountID: user.ID,
|
||||
Metadata: map[string]any{"secret": secret},
|
||||
@ -105,9 +106,9 @@ func GetFactorCode(factor models.AuthFactor, ip string) (bool, error) {
|
||||
log.Info().Uint("factor", factor.ID).Str("secret", secret).Msg("Published one-time-password to JetStream...")
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectLoginOneTimePassword", user.Language))
|
||||
subject := fmt.Sprintf("[%s] %s", viper.GetString("name"), localize.L.GetLocalizedString("subjectLoginOneTimePassword", user.Language))
|
||||
|
||||
content := RenderLocalizedTemplateHTML("email-otp.tmpl", user.Language, map[string]any{
|
||||
content := localize.L.RenderLocalizedTemplateHTML("email-otp.tmpl", user.Language, map[string]any{
|
||||
"Code": secret,
|
||||
"User": user,
|
||||
"IP": ip,
|
||||
|
@ -1,100 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/text/language"
|
||||
htmpl "html/template"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const FallbackLanguage = "en-US"
|
||||
|
||||
var LocaleBundle *i18n.Bundle
|
||||
|
||||
func LoadLocalization() error {
|
||||
LocaleBundle = i18n.NewBundle(language.AmericanEnglish)
|
||||
LocaleBundle.RegisterUnmarshalFunc("json", json.Unmarshal)
|
||||
|
||||
var count int
|
||||
|
||||
basePath := viper.GetString("locales_dir")
|
||||
if entries, err := os.ReadDir(basePath); err != nil {
|
||||
return fmt.Errorf("unable to read locales directory: %v", err)
|
||||
} else {
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
if _, err := LocaleBundle.LoadMessageFile(filepath.Join(basePath, entry.Name())); err != nil {
|
||||
return fmt.Errorf("unable to load localization file %s: %v", entry.Name(), err)
|
||||
} else {
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Int("locales", count).Msg("Loaded localization files...")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetLocalizer(lang string) *i18n.Localizer {
|
||||
return i18n.NewLocalizer(LocaleBundle, lang)
|
||||
}
|
||||
|
||||
func GetLocalizedString(name string, lang string) string {
|
||||
localizer := GetLocalizer(lang)
|
||||
msg, err := localizer.LocalizeMessage(&i18n.Message{
|
||||
ID: name,
|
||||
})
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to localize string...")
|
||||
return name
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func GetLocalizedTemplatePath(name string, lang string) string {
|
||||
basePath := viper.GetString("templates_dir")
|
||||
filePath := filepath.Join(basePath, lang, name)
|
||||
|
||||
if _, err := os.Stat(filePath); errors.Is(err, os.ErrNotExist) {
|
||||
// Fallback to English
|
||||
filePath = filepath.Join(basePath, FallbackLanguage, name)
|
||||
return filePath
|
||||
}
|
||||
|
||||
return filePath
|
||||
}
|
||||
|
||||
func GetLocalizedTemplateHTML(name string, lang string) *htmpl.Template {
|
||||
path := GetLocalizedTemplatePath(name, lang)
|
||||
tmpl, err := htmpl.ParseFiles(path)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to load localized template...")
|
||||
return nil
|
||||
}
|
||||
|
||||
return tmpl
|
||||
}
|
||||
|
||||
func RenderLocalizedTemplateHTML(name string, lang string, data any) string {
|
||||
tmpl := GetLocalizedTemplateHTML(name, lang)
|
||||
if tmpl == nil {
|
||||
return ""
|
||||
}
|
||||
buf := new(strings.Builder)
|
||||
err := tmpl.Execute(buf, data)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to render localized template...")
|
||||
return ""
|
||||
}
|
||||
return buf.String()
|
||||
}
|
@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||
)
|
||||
@ -42,8 +43,8 @@ func UpdateAbuseReportStatus(id uint, status, message string) error {
|
||||
|
||||
_ = NewNotification(models.Notification{
|
||||
Topic: "reports.feedback",
|
||||
Title: GetLocalizedString("subjectAbuseReportUpdated", account.Language),
|
||||
Body: fmt.Sprintf(GetLocalizedString("shortBodyAbuseReportUpdated", account.Language), id, status, message),
|
||||
Title: localize.L.GetLocalizedString("subjectAbuseReportUpdated", account.Language),
|
||||
Body: fmt.Sprintf(localize.L.GetLocalizedString("shortBodyAbuseReportUpdated", account.Language), id, status, message),
|
||||
Account: account,
|
||||
AccountID: account.ID,
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||
"time"
|
||||
|
||||
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||
@ -137,8 +138,8 @@ func ActiveTicket(ticket models.AuthTicket) (models.AuthTicket, error) {
|
||||
|
||||
_ = NewNotification(models.Notification{
|
||||
Topic: "passport.security.alert",
|
||||
Title: GetLocalizedString("subjectLoginAlert", account.Language),
|
||||
Body: fmt.Sprintf(GetLocalizedString("shortBodyLoginAlert", account.Language), ticket.IpAddress),
|
||||
Title: localize.L.GetLocalizedString("subjectLoginAlert", account.Language),
|
||||
Body: fmt.Sprintf(localize.L.GetLocalizedString("shortBodyLoginAlert", account.Language), ticket.IpAddress),
|
||||
Metadata: datatypes.JSONMap{
|
||||
"ip_address": ticket.IpAddress,
|
||||
"created_at": ticket.CreatedAt,
|
||||
|
@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -62,22 +63,22 @@ func NotifyMagicToken(token models.MagicToken) error {
|
||||
switch token.Type {
|
||||
case models.ConfirmMagicToken:
|
||||
link := fmt.Sprintf("%s/flow/accounts/confirm?code=%s", viper.GetString("frontend_app"), token.Code)
|
||||
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectConfirmRegistration", user.Language))
|
||||
content = RenderLocalizedTemplateHTML("register-confirm.tmpl", user.Language, map[string]any{
|
||||
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), localize.L.GetLocalizedString("subjectConfirmRegistration", user.Language))
|
||||
content = localize.L.RenderLocalizedTemplateHTML("register-confirm.tmpl", user.Language, map[string]any{
|
||||
"User": user,
|
||||
"Link": link,
|
||||
})
|
||||
case models.ResetPasswordMagicToken:
|
||||
link := fmt.Sprintf("%s/flow/accounts/password-reset?code=%s", viper.GetString("frontend_app"), token.Code)
|
||||
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectResetPassword", user.Language))
|
||||
content = RenderLocalizedTemplateHTML("reset-password.tmpl", user.Language, map[string]any{
|
||||
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), localize.L.GetLocalizedString("subjectResetPassword", user.Language))
|
||||
content = localize.L.RenderLocalizedTemplateHTML("reset-password.tmpl", user.Language, map[string]any{
|
||||
"User": user,
|
||||
"Link": link,
|
||||
})
|
||||
case models.DeleteAccountMagicToken:
|
||||
link := fmt.Sprintf("%s/flow/accounts/deletion?code=%s", viper.GetString("frontend_app"), token.Code)
|
||||
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), GetLocalizedString("subjectDeleteAccount", user.Language))
|
||||
content = RenderLocalizedTemplateHTML("confirm-deletion.tmpl", user.Language, map[string]any{
|
||||
subject = fmt.Sprintf("[%s] %s", viper.GetString("name"), localize.L.GetLocalizedString("subjectDeleteAccount", user.Language))
|
||||
content = localize.L.RenderLocalizedTemplateHTML("confirm-deletion.tmpl", user.Language, map[string]any{
|
||||
"User": user,
|
||||
"Link": link,
|
||||
})
|
||||
|
@ -72,7 +72,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Load localization
|
||||
if err := services.LoadLocalization(); err != nil {
|
||||
if err := gap.LoadLocalization(); err != nil {
|
||||
log.Fatal().Err(err).Msg("An error occurred when loading localization.")
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user