From 7e8b5710c1030b38179ca6b3b71c788d1ac43d97 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 8 Nov 2020 00:40:45 +0800 Subject: [PATCH] code refactor --- pkg/api/authorizations.go | 32 ++++-------- pkg/api/tokens.go | 1 + pkg/api/users.go | 70 +++++++++++--------------- pkg/models/auth_response.go | 7 ++- pkg/models/token_record.go | 5 +- pkg/models/user.go | 39 ++++++++++++++ src/lib/services.js | 3 +- src/lib/userstate.js | 60 ++++++++++------------ src/views/mobile/Login.vue | 4 +- src/views/mobile/Settings.vue | 5 +- src/views/mobile/Signup.vue | 4 +- src/views/mobile/users/UserProfile.vue | 8 +-- 12 files changed, 127 insertions(+), 111 deletions(-) diff --git a/pkg/api/authorizations.go b/pkg/api/authorizations.go index 92825580..c492ded1 100644 --- a/pkg/api/authorizations.go +++ b/pkg/api/authorizations.go @@ -75,13 +75,7 @@ func (a *AuthorizationsApi) AuthorizeHandler(c *core.Context) (interface{}, *err log.InfofWithRequestId(c, "[authorizations.AuthorizeHandler] user \"uid:%d\" has logined, token type is %d, token will be expired at %d", user.Uid, claims.Type, claims.ExpiresAt) - authResp := &models.AuthResponse{ - Token : token, - Username: user.Username, - Nickname: user.Nickname, - Need2FA: twoFactorEnable, - } - + authResp := a.getAuthResponse(token, twoFactorEnable, user) return authResp, nil } @@ -132,13 +126,7 @@ func (a *AuthorizationsApi) TwoFactorAuthorizeHandler(c *core.Context) (interfac log.InfofWithRequestId(c, "[authorizations.TwoFactorAuthorizeHandler] user \"uid:%d\" has authorized two factor via passcode, token will be expired at %d", user.Uid, claims.ExpiresAt) - authResp := &models.AuthResponse{ - Token : token, - Username: user.Username, - Nickname: user.Nickname, - Need2FA: false, - } - + authResp := a.getAuthResponse(token, false, user) return authResp, nil } @@ -195,12 +183,14 @@ func (a *AuthorizationsApi) TwoFactorAuthorizeByRecoveryCodeHandler(c *core.Cont log.InfofWithRequestId(c, "[authorizations.TwoFactorAuthorizeByRecoveryCodeHandler] user \"uid:%d\" has authorized two factor via recovery code \"%s\", token will be expired at %d", user.Uid, credential.RecoveryCode, claims.ExpiresAt) - authResp := &models.AuthResponse{ - Token : token, - Username: user.Username, - Nickname: user.Nickname, - Need2FA: false, - } - + authResp := a.getAuthResponse(token, false, user) return authResp, nil } + +func (a *AuthorizationsApi) getAuthResponse(token string, need2FA bool, user *models.User) (*models.AuthResponse) { + return &models.AuthResponse{ + Token : token, + Need2FA: need2FA, + User: user.ToUserBasicInfo(), + } +} diff --git a/pkg/api/tokens.go b/pkg/api/tokens.go index 2e1f85fd..11658756 100644 --- a/pkg/api/tokens.go +++ b/pkg/api/tokens.go @@ -160,6 +160,7 @@ func (a *TokensApi) TokenRefreshHandler(c *core.Context) (interface{}, *errs.Err refreshResp := &models.TokenRefreshResponse{ NewToken: token, OldTokenId: a.tokens.GenerateTokenId(oldTokenRecord), + User: user.ToUserBasicInfo(), } return refreshResp, nil diff --git a/pkg/api/users.go b/pkg/api/users.go index 2bcc765a..6f5459fd 100644 --- a/pkg/api/users.go +++ b/pkg/api/users.go @@ -9,7 +9,6 @@ import ( "github.com/mayswind/lab/pkg/log" "github.com/mayswind/lab/pkg/models" "github.com/mayswind/lab/pkg/services" - "github.com/mayswind/lab/pkg/utils" ) type UsersApi struct { @@ -54,24 +53,23 @@ func (a *UsersApi) UserRegisterHandler(c *core.Context) (interface{}, *errs.Erro log.InfofWithRequestId(c, "[users.UserRegisterHandler] user \"%s\" has registered successfully, uid is %d", user.Username, user.Uid) + authResp := &models.AuthResponse{ + Need2FA: false, + User: user.ToUserBasicInfo(), + } + token, claims, err := a.tokens.CreateToken(user, c) if err != nil { log.WarnfWithRequestId(c, "[users.UserRegisterHandler] failed to create token for user \"uid:%d\", because %s", user.Uid, err.Error()) - return true, nil + return authResp, nil } + authResp.Token = token c.SetTokenClaims(claims) log.InfofWithRequestId(c, "[users.UserRegisterHandler] user \"uid:%d\" has logined, token will be expired at %d", user.Uid, claims.ExpiresAt) - authResp := &models.AuthResponse{ - Token : token, - Username: user.Username, - Nickname: user.Nickname, - Need2FA: false, - } - return authResp, nil } @@ -87,18 +85,7 @@ func (a *UsersApi) UserProfileHandler(c *core.Context) (interface{}, *errs.Error return nil, errs.ErrUserNotFound } - userResp := &models.UserProfileResponse{ - Uid : utils.Int64ToString(user.Uid), - Username: user.Username, - Email: user.Email, - Nickname: user.Nickname, - Type: user.Type, - DefaultCurrency: user.DefaultCurrency, - CreatedAt: user.CreatedUnixTime, - UpdatedAt: user.UpdatedUnixTime, - LastLoginAt: user.LastLoginUnixTime, - } - + userResp := user.ToUserProfileResponse() return userResp, nil } @@ -126,11 +113,16 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs userUpdateReq.Nickname = strings.TrimSpace(userUpdateReq.Nickname) anythingUpdate := false + userNew := &models.User{ + Uid: user.Uid, + Salt: user.Salt, + Rands: user.Rands, + } if userUpdateReq.Email != "" && userUpdateReq.Email != user.Email { + user.Email = userUpdateReq.Email + userNew.Email = userUpdateReq.Email anythingUpdate = true - } else { - userUpdateReq.Email = "" } if userUpdateReq.Password != "" { @@ -139,36 +131,28 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs } if !a.users.IsPasswordEqualsUserPassword(userUpdateReq.Password, user) { + userNew.Password = userUpdateReq.Password anythingUpdate = true - } else { - userUpdateReq.Password = "" } - } else { - userUpdateReq.Password = "" } if userUpdateReq.Nickname != "" && userUpdateReq.Nickname != user.Nickname { + user.Nickname = userUpdateReq.Nickname + userNew.Nickname = userUpdateReq.Nickname anythingUpdate = true - } else { - userUpdateReq.Nickname = "" } if userUpdateReq.DefaultCurrency != "" && userUpdateReq.DefaultCurrency != user.DefaultCurrency { + user.DefaultCurrency = userUpdateReq.DefaultCurrency + userNew.DefaultCurrency = userUpdateReq.DefaultCurrency anythingUpdate = true - } else { - userUpdateReq.DefaultCurrency = "" } if !anythingUpdate { return nil, errs.ErrNothingWillBeUpdated } - user.Email = userUpdateReq.Email - user.Password = userUpdateReq.Password - user.Nickname = userUpdateReq.Nickname - user.DefaultCurrency = userUpdateReq.DefaultCurrency - - keyProfileUpdated, err := a.users.UpdateUser(user) + keyProfileUpdated, err := a.users.UpdateUser(userNew) if err != nil { log.ErrorfWithRequestId(c, "[users.UserUpdateProfileHandler] failed to update user \"uid:%d\", because %s", user.Uid, err.Error()) @@ -177,6 +161,10 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs log.InfofWithRequestId(c, "[users.UserUpdateProfileHandler] user \"uid:%d\" has updated successfully", user.Uid) + resp := &models.UserProfileUpdateResponse { + User: user.ToUserBasicInfo(), + } + if keyProfileUpdated { now := time.Now().Unix() err = a.tokens.DeleteTokensBeforeTime(uid, now) @@ -191,14 +179,16 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs if err != nil { log.WarnfWithRequestId(c, "[users.UserUpdateProfileHandler] failed to create token for user \"uid:%d\", because %s", user.Uid, err.Error()) - return true, nil + return resp, nil } + resp.NewToken = token c.SetTokenClaims(claims) log.InfofWithRequestId(c, "[users.UserUpdateProfileHandler] user \"uid:%d\" token refreshed, new token will be expired at %d", user.Uid, claims.ExpiresAt) - return token, nil + + return resp, nil } else { - return true, nil + return resp, nil } } diff --git a/pkg/models/auth_response.go b/pkg/models/auth_response.go index 30bc9517..3b545351 100644 --- a/pkg/models/auth_response.go +++ b/pkg/models/auth_response.go @@ -1,8 +1,7 @@ package models type AuthResponse struct { - Token string `json:"token"` - Username string `json:"username,omitempty"` - Nickname string `json:"nickname,omitempty"` - Need2FA bool `json:"need2FA"` + Token string `json:"token"` + Need2FA bool `json:"need2FA"` + User *UserBasicInfo `json:"user"` } diff --git a/pkg/models/token_record.go b/pkg/models/token_record.go index 3b4f218b..57a91044 100644 --- a/pkg/models/token_record.go +++ b/pkg/models/token_record.go @@ -19,8 +19,9 @@ type TokenRevokeRequest struct { } type TokenRefreshResponse struct { - NewToken string `json:"newToken"` - OldTokenId string `json:"oldTokenId"` + NewToken string `json:"newToken"` + OldTokenId string `json:"oldTokenId"` + User *UserBasicInfo `json:"user"` } type TokenInfoResponse struct { diff --git a/pkg/models/user.go b/pkg/models/user.go index 2871add9..5457b05d 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -1,5 +1,7 @@ package models +import "github.com/mayswind/lab/pkg/utils" + type UserType byte const ( @@ -27,6 +29,14 @@ type User struct { LastLoginUnixTime int64 } +type UserBasicInfo struct { + Uid string `json:"uid"` + Username string `json:"username"` + Email string `json:"email"` + Nickname string `json:"nickname"` + DefaultCurrency string `json:"defaultCurrency"` +} + type UserLoginRequest struct { LoginName string `json:"loginName" binding:"required,notBlank,max=100,validUsername|validEmail"` Password string `json:"password" binding:"required,min=6,max=128"` @@ -48,6 +58,11 @@ type UserProfileUpdateRequest struct { DefaultCurrency string `json:"defaultCurrency" binding:"required,len=3,validCurrency"` } +type UserProfileUpdateResponse struct { + User *UserBasicInfo `json:"user"` + NewToken string `json:"newToken,omitempty"` +} + type UserProfileResponse struct { Uid string `json:"uid"` Username string `json:"username"` @@ -59,3 +74,27 @@ type UserProfileResponse struct { UpdatedAt int64 `json:"updatedAt"` LastLoginAt int64 `json:"lastLoginAt"` } + +func (u User) ToUserBasicInfo() *UserBasicInfo { + return &UserBasicInfo{ + Uid: utils.Int64ToString(u.Uid), + Username: u.Username, + Email: u.Email, + Nickname: u.Nickname, + DefaultCurrency: u.DefaultCurrency, + } +} + +func (u User) ToUserProfileResponse() *UserProfileResponse { + return &UserProfileResponse{ + Uid: utils.Int64ToString(u.Uid), + Username: u.Username, + Email: u.Email, + Nickname: u.Nickname, + Type: u.Type, + DefaultCurrency: u.DefaultCurrency, + CreatedAt: u.CreatedUnixTime, + UpdatedAt: u.UpdatedUnixTime, + LastLoginAt: u.LastLoginUnixTime, + } +} diff --git a/src/lib/services.js b/src/lib/services.js index 420b6eb6..96d77fb3 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -41,7 +41,7 @@ axios.interceptors.response.use(response => { && errorCode <= 202004 // current token type is invalid && errorCode <= 202005 // current token requires two factor authorization && errorCode <= 202006) { // current token does not require two factor authorization - userState.clearToken(); + userState.clearTokenAndUserInfo(); location.reload(); return Promise.reject({ processed: true }); } @@ -100,6 +100,7 @@ export default { if (data && data.success && data.result && data.result.newToken) { userState.updateToken(data.result.newToken); + userState.updateUserInfo(data.result.user); if (data.result.oldTokenId) { axios.post('v1/tokens/revoke.json', { diff --git a/src/lib/userstate.js b/src/lib/userstate.js index 6396009f..0e3d4bb9 100644 --- a/src/lib/userstate.js +++ b/src/lib/userstate.js @@ -1,60 +1,54 @@ const tokenLocalStorageKey = 'lab_user_token'; -const userNameLocalStorageKey = 'lab_user_name'; -const userNickNameLocalStorageKey = 'lab_user_nickname'; +const userInfoLocalStorageKey = 'lab_user_info'; function getToken() { return localStorage.getItem(tokenLocalStorageKey); } -function getUserName() { - return localStorage.getItem(userNameLocalStorageKey); -} - -function getUserNickName() { - return localStorage.getItem(userNickNameLocalStorageKey); +function getUserInfo() { + const data = localStorage.getItem(userInfoLocalStorageKey); + return JSON.parse(data); } function isUserLogined() { return !!getToken(); } -function updateToken(item) { - if (typeof(item) === 'string') { - return localStorage.setItem(tokenLocalStorageKey, item); - } else if (typeof(item) === 'object') { - localStorage.setItem(tokenLocalStorageKey, item.token); - localStorage.setItem(userNameLocalStorageKey, item.username); - localStorage.setItem(userNickNameLocalStorageKey, item.nickname); - - return true; - } else { - return false; +function updateToken(token) { + if (typeof(token) === 'string') { + localStorage.setItem(tokenLocalStorageKey, token); } } -function updateUsername(value) { - localStorage.setItem(userNameLocalStorageKey, value); +function updateUserInfo(user) { + if (typeof(user) === 'object') { + localStorage.setItem(userInfoLocalStorageKey, JSON.stringify(user)); + } } -function updateUserNickname(value) { - localStorage.setItem(userNickNameLocalStorageKey, value); +function updateTokenAndUserInfo(item) { + if (typeof(item) === 'object') { + if (item.token) { + updateToken(item.token); + } + + if (item.user) { + updateUserInfo(item.user); + } + } } -function clearToken() { +function clearTokenAndUserInfo() { localStorage.removeItem(tokenLocalStorageKey); - localStorage.removeItem(userNameLocalStorageKey); - localStorage.removeItem(userNickNameLocalStorageKey); - - return true; + localStorage.removeItem(userInfoLocalStorageKey); } export default { getToken, - getUserName, - getUserNickName, + getUserInfo, isUserLogined, updateToken, - updateUsername, - updateUserNickname, - clearToken + updateUserInfo, + updateTokenAndUserInfo, + clearTokenAndUserInfo }; diff --git a/src/views/mobile/Login.vue b/src/views/mobile/Login.vue index 6496942b..15881561 100644 --- a/src/views/mobile/Login.vue +++ b/src/views/mobile/Login.vue @@ -178,7 +178,7 @@ export default { return; } - self.$user.updateToken(data.result); + self.$user.updateTokenAndUserInfo(data.result); router.navigate('/'); }).catch(error => { self.logining = false; @@ -234,7 +234,7 @@ export default { return; } - self.$user.updateToken(data.result); + self.$user.updateTokenAndUserInfo(data.result); self.show2faSheet = false; router.navigate('/'); }).catch(error => { diff --git a/src/views/mobile/Settings.vue b/src/views/mobile/Settings.vue index 874315ec..35801af6 100644 --- a/src/views/mobile/Settings.vue +++ b/src/views/mobile/Settings.vue @@ -47,7 +47,8 @@ export default { return 'v' + this.$version(); }, userNickName() { - return this.$user.getUserNickName() || this.$user.getUserName() || this.$t('User'); + const userInfo = this.$user.getUserInfo() || {}; + return userInfo.nickname || userInfo.username || this.$t('User'); }, currentLocale: { get: function () { @@ -99,7 +100,7 @@ export default { return; } - self.$user.clearToken(); + self.$user.clearTokenAndUserInfo(); router.navigate('/'); }).catch(error => { self.logouting = false; diff --git a/src/views/mobile/Signup.vue b/src/views/mobile/Signup.vue index 64609b24..50d26a39 100644 --- a/src/views/mobile/Signup.vue +++ b/src/views/mobile/Signup.vue @@ -144,8 +144,8 @@ export default { return; } - if (typeof(data.result) === 'object') { - self.$user.updateToken(data.result); + if (typeof(data.result.token) === 'string') { + self.$user.updateTokenAndUserInfo(data.result); } self.$toast('You have been successfully registered'); diff --git a/src/views/mobile/users/UserProfile.vue b/src/views/mobile/users/UserProfile.vue index 91189875..ae2de689 100644 --- a/src/views/mobile/users/UserProfile.vue +++ b/src/views/mobile/users/UserProfile.vue @@ -220,12 +220,12 @@ export default { return; } - if (self.nickname) { - self.$user.updateUserNickname(self.nickname); + if (typeof(data.result.newToken) === 'string') { + self.$user.updateToken(data.result.newToken); } - if (typeof(data.result) === 'string') { - self.$user.updateToken(data.result); + if (typeof(data.result.user) === 'object') { + self.$user.updateUserInfo(data.result.user); } self.$toast('Your profile has been successfully updated');