From 6bec93894e1c1196465e59ecbaac4589f7e3e249 Mon Sep 17 00:00:00 2001 From: Dmitrii Kozlov Date: Sat, 3 Jun 2023 11:49:29 +0300 Subject: [PATCH] add token payload for refreshed token --- jwt/service/jwt_token_service.go | 9 +++++++-- model/token_service.go | 2 +- web/api/2fa.go | 4 ++-- web/api/login.go | 6 +++--- web/api/phone_login.go | 2 +- web/api/refresh_token.go | 13 ++++++++++++- 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/jwt/service/jwt_token_service.go b/jwt/service/jwt_token_service.go index 57a44af3..3ce3bc59 100644 --- a/jwt/service/jwt_token_service.go +++ b/jwt/service/jwt_token_service.go @@ -318,7 +318,7 @@ func (ts *JWTokenService) NewRefreshToken(u model.User, scopes []string, app mod } // RefreshAccessToken issues new access token for provided refresh token. -func (ts *JWTokenService) RefreshAccessToken(refreshToken model.Token) (model.Token, error) { +func (ts *JWTokenService) RefreshAccessToken(refreshToken model.Token, tokenPayload map[string]interface{}) (model.Token, error) { rt, ok := refreshToken.(*model.JWToken) if !ok || rt == nil { return nil, model.ErrTokenInvalid @@ -343,7 +343,12 @@ func (ts *JWTokenService) RefreshAccessToken(refreshToken model.Token) (model.To return nil, ErrInvalidUser } - token, err := ts.NewAccessToken(user, strings.Split(claims.Scopes, " "), app, false, nil) + token, err := ts.NewAccessToken( + user, + strings.Split(claims.Scopes, " "), + app, + false, + tokenPayload) if err != nil { return nil, err } diff --git a/model/token_service.go b/model/token_service.go index 0dcbf2a9..58d555d6 100644 --- a/model/token_service.go +++ b/model/token_service.go @@ -9,7 +9,7 @@ const ( type TokenService interface { NewAccessToken(u User, scopes []string, app AppData, requireTFA bool, tokenPayload map[string]interface{}) (Token, error) NewRefreshToken(u User, scopes []string, app AppData) (Token, error) - RefreshAccessToken(token Token) (Token, error) + RefreshAccessToken(token Token, tokenPayload map[string]interface{}) (Token, error) NewInviteToken(email, role, audience string, data map[string]interface{}) (Token, error) NewResetToken(userID string) (Token, error) NewWebCookieToken(u User) (Token, error) diff --git a/web/api/2fa.go b/web/api/2fa.go index 536ecbbe..50db8279 100644 --- a/web/api/2fa.go +++ b/web/api/2fa.go @@ -81,7 +81,7 @@ func (ar *Router) EnableTFA() http.HandlerFunc { return } - tokenPayload, err := ar.getTokenPayloadForApp(app, user) + tokenPayload, err := ar.getTokenPayloadForApp(app, user.ID) if err != nil { ar.Error(w, locale, http.StatusInternalServerError, l.ErrorAPIAPPUnableToTokenPayloadForAPPError, app.ID, err) return @@ -276,7 +276,7 @@ func (ar *Router) FinalizeTFA() http.HandlerFunc { scopes = append(scopes, "offline") } - tokenPayload, err := ar.getTokenPayloadForApp(app, user) + tokenPayload, err := ar.getTokenPayloadForApp(app, user.ID) if err != nil { ar.Error(w, locale, http.StatusInternalServerError, l.ErrorAPIAPPUnableToTokenPayloadForAPPError, app.ID, err) return diff --git a/web/api/login.go b/web/api/login.go index d7694a75..b19fd646 100644 --- a/web/api/login.go +++ b/web/api/login.go @@ -235,7 +235,7 @@ func (ar *Router) GetUser() http.HandlerFunc { } // getTokenPayloadForApp get additional token payload data -func (ar *Router) getTokenPayloadForApp(app model.AppData, user model.User) (map[string]interface{}, error) { +func (ar *Router) getTokenPayloadForApp(app model.AppData, userID string) (map[string]interface{}, error) { if app.TokenPayloadService == model.TokenPayloadServiceNone || app.TokenPayloadService == "" { return nil, nil @@ -246,7 +246,7 @@ func (ar *Router) getTokenPayloadForApp(app model.AppData, user model.User) (map return nil, err } - return ps.TokenPayloadForApp(app.ID, app.Name, user.ID) + return ps.TokenPayloadForApp(app.ID, app.Name, userID) } func (ar *Router) getTokenPayloadService(app model.AppData) (model.TokenPayloadProvider, error) { @@ -346,7 +346,7 @@ func (ar *Router) loginFlow(app model.AppData, user model.User, requestedScopes } offline := contains(scopes, model.OfflineScope) - tokenPayload, err := ar.getTokenPayloadForApp(app, user) + tokenPayload, err := ar.getTokenPayloadForApp(app, user.ID) if err != nil { return AuthResponse{}, err } diff --git a/web/api/phone_login.go b/web/api/phone_login.go index 63f888fd..35f50875 100644 --- a/web/api/phone_login.go +++ b/web/api/phone_login.go @@ -139,7 +139,7 @@ func (ar *Router) PhoneLogin() http.HandlerFunc { scopes = append(scopes, "offline") } - tokenPayload, err := ar.getTokenPayloadForApp(app, user) + tokenPayload, err := ar.getTokenPayloadForApp(app, user.ID) if err != nil { ar.Error(w, locale, http.StatusInternalServerError, l.ErrorAPIAPPUnableToTokenPayloadForAPPError, app.ID, err) return diff --git a/web/api/refresh_token.go b/web/api/refresh_token.go index ffe183bb..ebde6492 100644 --- a/web/api/refresh_token.go +++ b/web/api/refresh_token.go @@ -39,8 +39,19 @@ func (ar *Router) RefreshTokens() http.HandlerFunc { // Get refresh token from context. oldRefreshToken := tokenFromContext(r.Context()) + if err := oldRefreshToken.Validate(); err != nil { + ar.Error(w, locale, http.StatusUnauthorized, l.ErrorTokenInvalidError, err) + return + } + + tokenPayload, err := ar.getTokenPayloadForApp(app, oldRefreshToken.Subject()) + if err != nil { + ar.Error(w, locale, http.StatusBadRequest, l.ErrorAPIAPPUnableToTokenPayloadForAPPError) + return + } + // Issue new access token and stringify it for response. - accessToken, err := ar.server.Services().Token.RefreshAccessToken(oldRefreshToken) + accessToken, err := ar.server.Services().Token.RefreshAccessToken(oldRefreshToken, tokenPayload) if err != nil { ar.Error(w, locale, http.StatusInternalServerError, l.ErrorTokenRefreshAccessToken, err) return