Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - renew jwt if expired #7

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,23 @@ func GenerateJWT(scope string, keyID string, secret string) (string, error) {

return token.SignedString([]byte(secret))
}

// isJWTExpired will check whether Smooch JWT is expired or not.
func isJWTExpired(jwtToken string, secret string) (bool, error) {
_, err := jwt.ParseWithClaims(jwtToken, jwt.MapClaims{}, func(t *jwt.Token) (interface{}, error) {
return []byte(secret), nil
})

if err == nil {
return false, nil
}

switch err.(type) {
case *jwt.ValidationError:
vErr := err.(*jwt.ValidationError)
if vErr.Errors == jwt.ValidationErrorExpired {
return true, nil
}
}
return false, err
}
37 changes: 37 additions & 0 deletions smooch.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ import (
"os"
"path"
"strings"
"sync"
)

var (
ErrUserIDEmpty = errors.New("user id is empty")
ErrKeyIDEmpty = errors.New("key id is empty")
ErrSecretEmpty = errors.New("secret is empty")
ErrMessageNil = errors.New("message is nil")
ErrMessageRoleEmpty = errors.New("message.Role is empty")
ErrMessageTypeEmpty = errors.New("message.Type is empty")
Expand Down Expand Up @@ -52,6 +55,8 @@ type WebhookEventHandler func(payload *Payload)

type Client interface {
Handler() http.Handler
IsJWTExpired() (bool, error)
RenewToken() (string, error)
AddWebhookEventHandler(handler WebhookEventHandler)
Send(userID string, message *Message) (*ResponsePayload, error)
VerifyRequest(r *http.Request) bool
Expand All @@ -63,15 +68,26 @@ type Client interface {
type smoochClient struct {
mux *http.ServeMux
appID string
keyID string
secret string
jwtToken string
verifySecret string
logger Logger
region string
webhookEventHandlers []WebhookEventHandler
httpClient *http.Client
mtx sync.Mutex
}

func New(o Options) (*smoochClient, error) {
if o.KeyID == "" {
return nil, ErrKeyIDEmpty
}

if o.Secret == "" {
return nil, ErrSecretEmpty
}

if o.VerifySecret == "" {
return nil, ErrVerifySecretEmpty
}
Expand Down Expand Up @@ -109,6 +125,8 @@ func New(o Options) (*smoochClient, error) {
sc := &smoochClient{
mux: o.Mux,
appID: o.AppID,
keyID: o.KeyID,
secret: o.Secret,
verifySecret: o.VerifySecret,
logger: o.Logger,
region: region,
Expand All @@ -124,6 +142,25 @@ func (sc *smoochClient) Handler() http.Handler {
return sc.mux
}

// IsJWTExpired will check whether Smooch JWT is expired or not.
func (sc *smoochClient) IsJWTExpired() (bool, error) {
return isJWTExpired(sc.jwtToken, sc.secret)
}

// RenewToken will generate new Smooch JWT token.
func (sc *smoochClient) RenewToken() (string, error) {
sc.mtx.Lock()
defer sc.mtx.Unlock()

jwtToken, err := GenerateJWT("app", sc.keyID, sc.secret)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before generating new token - a check is needed, to verify that it wasn't generated previously.

if err != nil {
return "", err
}

sc.jwtToken = jwtToken
return jwtToken, nil
}

func (sc *smoochClient) AddWebhookEventHandler(handler WebhookEventHandler) {
sc.webhookEventHandlers = append(sc.webhookEventHandlers, handler)
}
Expand Down