diff --git a/svc/internal/mailer/password_reset.go b/svc/internal/mailer/password_reset.go index a8e6a94..8af1aa4 100644 --- a/svc/internal/mailer/password_reset.go +++ b/svc/internal/mailer/password_reset.go @@ -9,8 +9,9 @@ func (m *GraphMailer) SendPasswordResetMail(toEmail string, resetURL string) err
Merhaba,
Parolanızı sıfırlamak için aşağıdaki bağlantıya tıklayın:
- %s + Parolayı sıfırla
+Bağlantı: %s
Bu bağlantı 30 dakika geçerlidir ve tek kullanımlıktır.
`, resetURL, resetURL) diff --git a/svc/internal/security/password_reset.go b/svc/internal/security/password_reset.go index d364717..481f6fd 100644 --- a/svc/internal/security/password_reset.go +++ b/svc/internal/security/password_reset.go @@ -2,12 +2,28 @@ package security import ( "os" + "strings" ) func BuildResetURL(token string) string { - base := os.Getenv("FRONTEND_URL") + base := os.Getenv("APP_FRONTEND_URL") + if base == "" { + base = os.Getenv("FRONTEND_URL") + } if base == "" { base = "http://localhost:9000" } - return base + "/password-reset/" + token + base = strings.TrimRight(base, "/") + // If base already points to password-reset, just append token if needed. + if strings.Contains(base, "/password-reset") { + if strings.HasSuffix(base, "/password-reset") || strings.HasSuffix(base, "/password-reset/") || + strings.HasSuffix(base, "/#/password-reset") || strings.HasSuffix(base, "/#/password-reset/") { + return strings.TrimRight(base, "/") + "/" + token + } + return base + } + if strings.Contains(base, "#") { + return base + "/password-reset/" + token + } + return base + "/#/password-reset/" + token } diff --git a/svc/routes/password_forgot.go b/svc/routes/password_forgot.go index a04aa9a..d6ec04a 100644 --- a/svc/routes/password_forgot.go +++ b/svc/routes/password_forgot.go @@ -6,9 +6,7 @@ import ( "bssapp-backend/internal/security" "database/sql" "encoding/json" - "fmt" "net/http" - "os" "strings" "time" ) @@ -84,11 +82,7 @@ func ForgotPasswordHandler( // ------------------------------------------------------- // 5️⃣ Reset URL (PLAIN token) // ------------------------------------------------------- - resetURL := fmt.Sprintf( - "%s/password-reset/%s", - os.Getenv("FRONTEND_URL"), - plain, - ) + resetURL := security.BuildResetURL(plain) // ------------------------------------------------------- // 6️⃣ Mail gönder (fail olsa bile enumeration yok) diff --git a/svc/routes/user_detail.go b/svc/routes/user_detail.go index d2ca072..675c64e 100644 --- a/svc/routes/user_detail.go +++ b/svc/routes/user_detail.go @@ -14,7 +14,6 @@ import ( "io" "log" "net/http" - "os" "strconv" "strings" "time" @@ -462,11 +461,7 @@ func SendPasswordResetMailHandler( `, userID, hash, expires) // 🔗 URL → PLAIN - resetURL := fmt.Sprintf( - "%s/password-reset/%s", - os.Getenv("FRONTEND_URL"), - plain, - ) + resetURL := security.BuildResetURL(plain) _ = mailer.SendPasswordResetMail(email, resetURL) diff --git a/ui/src/stores/orderentryStore.js b/ui/src/stores/orderentryStore.js index 5f440a6..7963a5e 100644 --- a/ui/src/stores/orderentryStore.js +++ b/ui/src/stores/orderentryStore.js @@ -2533,6 +2533,50 @@ export const useOrderEntryStore = defineStore('orderentry', { console.log(`🧭 Order mode set edildi → ${mode}`) } , + // Sync only header-related fields from the form before submit. + syncHeaderFromForm(form) { + if (!form || typeof form !== 'object') return + + const keys = [ + 'OrderHeaderID', + 'OrderTypeCode', + 'ProcessCode', + 'OrderNumber', + 'OrderDate', + 'AverageDueDate', + 'Description', + 'InternalDescription', + 'CurrAccTypeCode', + 'CurrAccCode', + 'CurrAccDescription', + 'DocCurrencyCode', + 'LocalCurrencyCode', + 'ExchangeRate', + 'OfficeCode', + 'CreatedUserName', + 'CreatedDate', + 'LastUpdatedUserName', + 'LastUpdatedDate', + 'PaymentTerm', + 'WarehouseCode', + 'StoreCode' + ] + + const patch = {} + for (const k of keys) { + if (Object.prototype.hasOwnProperty.call(form, k)) { + patch[k] = form[k] + } + } + + if (Object.keys(patch).length > 0) { + this.header = { + ...(this.header || {}), + ...patch + } + } + } + , /* =========================================================== 🟦 submitAllReal (v12.1c — FINAL / CLEAN + PRE-VALIDATE) ----------------------------------------------------------- @@ -2553,6 +2597,9 @@ export const useOrderEntryStore = defineStore('orderentry', { // 🔒 Kontrollü submit → route leave guard susar this.isControlledSubmit = true + // ✅ Formdaki header alanlarını store'a taşı + this.syncHeaderFromForm?.(form) + const isNew = this.mode === 'new' const { header, lines } = this.buildFinalOrderJson()