diff --git a/server/handlers/app.go b/server/handlers/app.go index 6c5d541..9b30977 100644 --- a/server/handlers/app.go +++ b/server/handlers/app.go @@ -76,7 +76,7 @@ func AppHandler() gin.HandlerFunc { "data": map[string]interface{}{ "authorizerURL": hostname, "redirectURL": redirectURI, - "scope": scope, + "scope": strings.Join(scope, " "), "state": state, "organizationName": orgName, "organizationLogo": orgLogo, diff --git a/server/handlers/authorize.go b/server/handlers/authorize.go index 1ebe2f6..adb9d53 100644 --- a/server/handlers/authorize.go +++ b/server/handlers/authorize.go @@ -284,7 +284,7 @@ func AuthorizeHandler() gin.HandlerFunc { "access_token": authToken.AccessToken.Token, "id_token": authToken.IDToken.Token, "state": state, - "scope": scope, + "scope": strings.Join(scope, " "), "token_type": "Bearer", "expires_in": authToken.AccessToken.ExpiresAt, } diff --git a/server/handlers/token.go b/server/handlers/token.go index 9a2ca6f..8249d6f 100644 --- a/server/handlers/token.go +++ b/server/handlers/token.go @@ -259,7 +259,7 @@ func TokenHandler() gin.HandlerFunc { res := map[string]interface{}{ "access_token": authToken.AccessToken.Token, "id_token": authToken.IDToken.Token, - "scope": scope, + "scope": strings.Join(scope, " "), "roles": roles, "expires_in": expiresIn, } diff --git a/server/token/auth_token.go b/server/token/auth_token.go index d2eb454..370f9dc 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -137,7 +137,7 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc "iat": time.Now().Unix(), "token_type": constants.TokenTypeRefreshToken, "roles": roles, - "scope": strings.Join(scopes, " "), + "scope": scopes, "nonce": nonce, "login_method": loginMethod, "allowed_roles": strings.Split(user.Roles, ","), @@ -162,9 +162,7 @@ func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce if err != nil { expiryBound = time.Minute * 30 } - expiresAt := time.Now().Add(expiryBound).Unix() - clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) if err != nil { return "", 0, err @@ -177,12 +175,46 @@ func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce "exp": expiresAt, "iat": time.Now().Unix(), "token_type": constants.TokenTypeAccessToken, - "scope": strings.Join(scopes, " "), + "scope": scopes, "roles": roles, "login_method": loginMethod, "allowed_roles": strings.Split(user.Roles, ","), } + // check for the extra access token script + accessTokenScript, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyCustomAccessTokenScript) + if err != nil { + log.Debug("Failed to get custom access token script: ", err) + accessTokenScript = "" + } + if accessTokenScript != "" { + resUser := user.AsAPIUser() + userBytes, _ := json.Marshal(&resUser) + var userMap map[string]interface{} + json.Unmarshal(userBytes, &userMap) + vm := otto.New() + claimBytes, _ := json.Marshal(customClaims) + vm.Run(fmt.Sprintf(` + var user = %s; + var tokenPayload = %s; + var customFunction = %s; + var functionRes = JSON.stringify(customFunction(user, tokenPayload)); + `, string(userBytes), string(claimBytes), accessTokenScript)) + val, err := vm.Get("functionRes") + if err != nil { + log.Debug("error getting custom access token script: ", err) + } else { + extraPayload := make(map[string]interface{}) + err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload) + if err != nil { + log.Debug("error converting accessTokenScript response to map: ", err) + } else { + for k, v := range extraPayload { + customClaims[k] = v + } + } + } + } token, err := SignJWTToken(customClaims) if err != nil { return "", 0, err @@ -345,14 +377,11 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cH if err != nil { expiryBound = time.Minute * 30 } - expiresAt := time.Now().Add(expiryBound).Unix() - resUser := user.AsAPIUser() userBytes, _ := json.Marshal(&resUser) var userMap map[string]interface{} json.Unmarshal(userBytes, &userMap) - claimKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim) if err != nil { claimKey = "roles" @@ -376,7 +405,6 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cH } // split nonce to see if its authorization code grant method - if cHash != "" { customClaims["at_hash"] = atHash customClaims["c_hash"] = cHash @@ -384,13 +412,11 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cH customClaims["nonce"] = nonce customClaims["at_hash"] = atHash } - for k, v := range userMap { if k != "roles" { customClaims[k] = v } } - // check for the extra access token script accessTokenScript, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyCustomAccessTokenScript) if err != nil { @@ -399,7 +425,6 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cH } if accessTokenScript != "" { vm := otto.New() - claimBytes, _ := json.Marshal(customClaims) vm.Run(fmt.Sprintf(` var user = %s;