Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop

This commit is contained in:
laodaming 2023-09-05 18:29:52 +08:00
commit 9258d66372
8 changed files with 146 additions and 30 deletions

View File

@ -6,11 +6,16 @@ We have received your request to reset the password for your {{ .CompanyName }}
To proceed with the password reset, please click the button below to open the Reset Password page: To proceed with the password reset, please click the button below to open the Reset Password page:
<a href="{{ .ConfirmationLink }}" target="_blank" style="color: #FFFFFF; text-decoration: none;">Reset Password</a> <div style="margin: 1em 0;">
<a href="{{ .ConfirmationLink }}" target="_blank"
style="background-color: #008CBA; color: #FFFFFF; text-decoration: none; padding: 10px 15px; border-radius: 3px; display:inline-block; font-family: Arial, sans-serif; font-size: 14px; font-weight: bold;">
Reset Password
</a>
</div>
Please note that this password reset confirmation link will expire in 60 minutes. If you have any further questions, feel free to reach out to us. Please note that this password reset confirmation link will expire in 60 minutes. If you have any further questions, feel free to reach out to us.
Regards, Regards,
{{ .SenderName }} {{ .SenderName }}<br>
{{ .SenderTitle }} {{ .SenderTitle }}<br>
{{ .CompanyName }} {{ .CompanyName }}

View File

@ -117,11 +117,6 @@ button:hover {
</form> </form>
</div> </div>
<div id="messageContainer">
<p id="successMessage" class="message success"></p>
<p id="errorMessage" class="message error"></p>
</div>
<script> <script>
function resetPassword() { function resetPassword() {
const new_password = document.getElementById("new_password").value; const new_password = document.getElementById("new_password").value;
@ -145,20 +140,14 @@ function resetPassword() {
}, },
body: JSON.stringify(data) body: JSON.stringify(data)
}) })
.then(response => { .then(response => response.json())
.then(data => {
if (response.ok && response.data.code == 200) { if (data.code == 200 ) {
console.log('Password reset successful'); alert(data.msg);
// 在这里执行其他成功处理逻辑 window.location.href = "{{.HomePage}}";
// 显示成功消息或进行其他操作
document.getElementById('successMessage').innerText = response.data;
} else { } else {
console.error('Password reset failed'); alert(data.msg);
// 在这里执行其他失败处理逻辑
// 显示失败消息或进行其他操作
document.getElementById('errorMessage').innerText = 'Password reset failed. Please try again.';
} }
}) })
.catch(error => { .catch(error => {
console.error('Error:', error); console.error('Error:', error);

View File

@ -5,10 +5,10 @@ import (
"fmt" "fmt"
"fusenapi/utils/check" "fusenapi/utils/check"
"fusenapi/utils/fstpl" "fusenapi/utils/fstpl"
"html/template"
"log" "log"
"net/smtp" "net/smtp"
"sync" "sync"
"text/template"
"time" "time"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"

View File

@ -67,7 +67,9 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
} }
func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error { func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error {
tp := requests.Post(fmt.Sprintf("%s/api/websocket/common_notify", WebsocketAddr))
reqWebsocketAddr := fmt.Sprintf("%s/api/websocket/common_notify", WebsocketAddr)
tp := requests.Post(reqWebsocketAddr)
tp.SetBodyJson(requests.M{ tp.SetBodyJson(requests.M{
"wid": wid, "wid": wid,
"data": event, "data": event,
@ -80,9 +82,13 @@ func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error
} }
result := wresp.Json() result := wresp.Json()
if !result.Get("code").Exists() {
return fmt.Errorf("send %s is error", reqWebsocketAddr)
}
if result.Get("code").Int() != 200 { if result.Get("code").Int() != 200 {
// logx.Error(result.Get("message")) return fmt.Errorf("%s", result.String())
return fmt.Errorf("%s", result.Get("message").Str)
} }
return nil return nil

View File

@ -50,9 +50,11 @@ func (l *UserResetPasswordHtmlLogic) UserResetPasswordHtml(req *types.RequestUse
func (l *UserResetPasswordHtmlLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { func (l *UserResetPasswordHtmlLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
err := tpls.ExecuteTemplate(w, "reset_confirm.tpl", map[string]string{ err := tpls.ExecuteTemplate(w, "reset_confirm.tpl", map[string]string{
"HomePage": "http://www.fusen.3718.cn",
"ResetToken": l.ResetToken, "ResetToken": l.ResetToken,
"ResetPasswordLink": l.svcCtx.Config.MainAddress + "/api/auth/reset/password", "ResetPasswordLink": l.svcCtx.Config.MainAddress + "/api/auth/reset/password",
}) })
if err != nil { if err != nil {
httpx.OkJsonCtx(l.ctx, w, resp.SetStatusWithMessage(basic.CodeTemplateErr, err.Error())) httpx.OkJsonCtx(l.ctx, w, resp.SetStatusWithMessage(basic.CodeTemplateErr, err.Error()))
} else { } else {

View File

@ -56,27 +56,33 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error { err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error {
user := &gmodel.FsUser{} user := &gmodel.FsUser{}
err := tx.Model(user).Where("id = ?", rt.UserId).Take(user).Error err := tx.Where("id = ?", rt.UserId).Take(user).Error
if err != nil { if err != nil {
logx.Error(err) logx.Error(err)
return err return err
} }
if *user.PasswordHash != rt.OldPassword { if *user.PasswordHash != rt.OldPassword {
return fmt.Errorf("password had been reset") return fmt.Errorf("password had been reset")
} }
return tx.Update("PasswordHash", rt.NewPassword).Error
if *user.PasswordHash == req.NewPassword {
return fmt.Errorf("the password is the same as the old one. It needs to be changed")
}
return tx.Where("id = ?", rt.UserId).Update("PasswordHash", req.NewPassword).Error
}) })
if err != nil { if err != nil {
logx.Error(err) logx.Error(err)
return resp.SetStatus(basic.CodeDbSqlErr, err.Error()) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error())
} }
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId) event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
err = CommonNotify(l.svcCtx.Config.MainAddress, rt.Wid, event) err = CommonNotify(l.svcCtx.Config.WebsocketAddr, rt.Wid, event)
if err != nil { if err != nil {
logx.Error(err, rt.TraceId) logx.Error(err, rt.TraceId)
return resp.SetStatus(basic.CodeResetPasswordErr, err.Error()) return resp.SetStatusWithMessage(basic.CodeResetPasswordErr, err.Error())
} }
// token := &auth.ResetToken{ // token := &auth.ResetToken{

View File

@ -7,6 +7,7 @@ import (
"io" "io"
"log" "log"
"net/http" "net/http"
"net/smtp"
"testing" "testing"
"github.com/474420502/requests" "github.com/474420502/requests"
@ -16,6 +17,113 @@ import (
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
func TestEmailSend(t *testing.T) {
// 设置发件人和收件人信息
from := "support@fusenpack.com"
to := []string{"474420502@qq.com"}
// 设置smtp服务器地址,端口和认证信息
smtpServer := "smtp.gmail.com"
auth := smtp.PlainAuth("", "support@fusenpack.com", "wfbjpdgvaozjvwah", smtpServer)
body := `<div>
<br>
</div>
<div>
<br>
</div>
<div>
<sign signid="1" nreadytime="1693908994426">
<hr align="left" style="margin: 0 0 10px 0;border: 0;border-bottom:1px solid #E4E5E6;height:0;line-height:0;font-size:0;padding: 20px 0 0 0;width: 50px;">
<div style="font-size:14px;font-family:Verdana;color:#000;">
<a class="xm_write_card" id="in_alias" style="white-space: normal; display: inline-block; text-decoration: none !important;font-family: -apple-system,BlinkMacSystemFont,PingFang SC,Microsoft YaHei;" href="https://wx.mail.qq.com/home/index?t=readmail_businesscard_midpage&amp;nocheck=true&amp;name=3e&amp;icon=http%3A%2F%2Fthirdqq.qlogo.cn%2Fg%3Fb%3Doidb%26k%3DeXzYkarOrzZhXZpDqM83lA%26kti%3DZOJARgAAAAI%26s%3D140%26t%3D1556039949&amp;mail=474420502%40qq.com&amp;code=WmPZN_MDFxAnvpYZtHjQqsJv-zHkDdwEwftrVq-KClPFKtdQ71RDiVxIOZ7rrthFIT9ubnRFwkPjfKb3swLDIQ" target="_blank">
<table style="white-space: normal;table-layout: fixed; padding-right: 20px;" contenteditable="false" cellpadding="0" cellspacing="0">
<tbody>
<tr valign="top">
<td style="width: 40px;min-width: 40px; padding-top:10px">
<div style="width: 38px; height: 38px; border: 1px #FFF solid; border-radius:50%; margin: 0;vertical-align: top;box-shadow: 0 0 10px 0 rgba(127,152,178,0.14);">
<img src="http://thirdqq.qlogo.cn/g?b=oidb&amp;k=eXzYkarOrzZhXZpDqM83lA&amp;kti=ZOJARgAAAAI&amp;s=140&amp;t=1556039949" style="width:100%;height:100%;border-radius:50%;pointer-events: none;">
</div>
</td>
<td style="padding: 10px 0 8px 10px;">
<div class="businessCard_name" style="font-size: 14px;color: #33312E;line-height: 20px; padding-bottom: 2px; margin:0;font-weight: 500;">
3e
</div>
<div class="businessCard_mail" style="font-size: 12px;color: #999896;line-height: 18px; margin:0;">
474420502@qq.com
</div>
</td>
</tr>
</tbody>
</table>
</a>
</div>
</sign>
</div>
<div>
&nbsp;
</div>
<div style="position: relative;">
<includetail>
<div>
<br>
</div>
<div>
<br>
</div>
<div style="font-size: 12px;font-family: Arial Narrow;padding:2px 0 2px 0;">
------------------&nbsp;原始邮件&nbsp;------------------
</div>
<div style="font-size: 12px;background:#efefef;padding:8px;">
<div>
<b>
发件人:
</b>
"support" &lt;support@fusenpack.com&gt;;
</div>
<div>
<b>
发送时间:
</b>
&nbsp;2023年9月5日(星期二) 晚上6:16
</div>
<div>
<b>
收件人:
</b>
&nbsp;"3e"&lt;474420502@qq.com&gt;;
<wbr>
</div>
<div>
</div>
<div>
<b>
主题:
</b>
&nbsp;Simple Mail
</div>
</div>
<div>
<br>
</div>
</includetail>
</div>`
// 构建邮件内容
message := []byte("To: " + to[0] + "\r\n" +
"Subject: Simple Mail\r\n" +
"\r\n" +
body)
// 发送邮件
err := smtp.SendMail(smtpServer+":587", auth, from, to, message)
if err != nil {
log.Fatal(err)
}
}
func TestPost(t *testing.T) { func TestPost(t *testing.T) {
r := mux.NewRouter() r := mux.NewRouter()

View File

@ -1,11 +1,11 @@
package fstpl package fstpl
import ( import (
"html/template"
"log" "log"
"os" "os"
"runtime" "runtime"
"strings" "strings"
"text/template"
) )
func AutoParseTplFiles() *template.Template { func AutoParseTplFiles() *template.Template {