diff options
| -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  |