diff options
author | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-10 17:29:30 +0530 |
---|---|---|
committer | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-10 17:29:30 +0530 |
commit | b0f5cefba592f6bc7166cdd5d83899dc2bbcb355 (patch) | |
tree | a14584ac41b4d9915813db7c63c95248cf8c3dab | |
parent | 19c79de205674b0932b13162e779b311ac93444b (diff) |
added refresh token versioningv0.12.0
-rw-r--r-- | auth/auth.go | 6 | ||||
-rw-r--r-- | auth/controller.go | 29 | ||||
-rw-r--r-- | main.go | 2 | ||||
-rw-r--r-- | user/user.go | 3 |
4 files changed, 33 insertions, 7 deletions
diff --git a/auth/auth.go b/auth/auth.go index 7116a2c..4ac6445 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -26,6 +26,12 @@ type AuthClaims struct { UserID uint `json:"userid"` } +type RefreshClaims struct { + jwt.RegisteredClaims + UserID uint `json:"userid"` + Version uint `json:"version"` +} + type LoginReq struct { AccountName string Method string diff --git a/auth/controller.go b/auth/controller.go index 7e3346e..05cdd9d 100644 --- a/auth/controller.go +++ b/auth/controller.go @@ -103,12 +103,13 @@ func handleSignIn (ctx *gin.Context) { } refreshToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, - AuthClaims { + RefreshClaims { jwt.RegisteredClaims { IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 6)), }, u.ID, + u.TokenVersion, }, ).SignedString(REFRESH_KEY) if err != nil { @@ -137,13 +138,34 @@ func handleRefresh (ctx *gin.Context) { return []byte(REFRESH_KEY), nil }) - claims, ok := tk.Claims.(*AuthClaims) + claims, ok := tk.Claims.(*RefreshClaims) if !ok { ctx.Error(errors.ErrUnauthorized) ctx.Abort() return } + // check token version + var u user.User + err := user.GetUser(&u, claims.UserID) + if err != nil { + if err == errors.ErrNotFound { + ctx.Error(errors.ErrUnauthorized) + ctx.Abort() + return + } else { + ctx.Error(err) + ctx.Abort() + return + } + } + if (u.TokenVersion != claims.Version) { + ctx.Error(errors.ErrSessionExpired) + ctx.Abort() + return + } + + if !tk.Valid { eat := claims.ExpiresAt.Unix() if eat != 0 && eat < time.Now().Unix() { @@ -156,8 +178,6 @@ func handleRefresh (ctx *gin.Context) { return } - // TODO: if token is valid, check if user even exists before generating authToken - authToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, AuthClaims { jwt.RegisteredClaims { @@ -177,6 +197,5 @@ func handleRefresh (ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{ "auth_token": authToken, "message": "success", - //"data": u, }) } @@ -38,7 +38,7 @@ import ( "log" ) -const OPENBILLS_VERSION = "v0.11.1" +const OPENBILLS_VERSION = "v0.12.0" func init() { if !viper.GetBool("debug_mode") { diff --git a/user/user.go b/user/user.go index b130ab9..dbcbad0 100644 --- a/user/user.go +++ b/user/user.go @@ -40,6 +40,7 @@ func init() { type User struct { gorm.Model u.Address + TokenVersion uint // this can be incremented to disable existing refresh token(s) FullName string FirmName string Gstin string @@ -50,9 +51,9 @@ type User struct { Password string LogoFile string SignatureFile string + IsVerified bool // this should be removed and tokens should be issued upon verification // will be printed with address on the invoice Details string - IsVerified bool // a note is printed on every invoice. // This is the default that gets automatically set DefaultInvoiceNote string |