fix(02-03): capture OAuth code from JSON redirect URLs
Consent returns the callback URL in JSON, so replay can fill {{oauth:code}} from $.data.redirect_to before the token request.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -79,6 +79,26 @@ func TestCaptureAndPlaceholderResolution(t *testing.T) {
|
|||||||
if !strings.Contains(string(escaped.Response.Body), "{{oauth:redirect}}") {
|
if !strings.Contains(string(escaped.Response.Body), "{{oauth:redirect}}") {
|
||||||
t.Fatalf("php-escaped redirect not placeholder: %s", escaped.Response.Body)
|
t.Fatalf("php-escaped redirect not placeholder: %s", escaped.Response.Body)
|
||||||
}
|
}
|
||||||
|
codeStep := Step{
|
||||||
|
ID: "consent-code",
|
||||||
|
Response: Response{
|
||||||
|
Body: Body(`{"data":{"redirect_to":"http://127.0.0.1:8424/oauth/callback?code=oauthCodeFromJSON"}}`),
|
||||||
|
},
|
||||||
|
Capture: []CaptureRule{{
|
||||||
|
From: "response.json.query",
|
||||||
|
Path: "$.data.redirect_to",
|
||||||
|
Name: "code",
|
||||||
|
As: "oauth:code",
|
||||||
|
Category: "oauth_code",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
if err := CaptureStep(store, &codeStep); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
gotCode, ok := store.Get("oauth:code")
|
||||||
|
if !ok || gotCode != "oauthCodeFromJSON" {
|
||||||
|
t.Fatalf("json.query code: ok=%v val=%q", ok, gotCode)
|
||||||
|
}
|
||||||
|
|
||||||
step2 := Step{
|
step2 := Step{
|
||||||
ID: "pkce",
|
ID: "pkce",
|
||||||
|
|||||||
@@ -249,6 +249,21 @@ func extractCapture(rule CaptureRule, req Request, resp Response) (string, error
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return scalarString(v), nil
|
return scalarString(v), nil
|
||||||
|
case "response.json.query":
|
||||||
|
v, err := jsonPathValue([]byte(resp.Body), rule.Path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
raw := scalarString(v)
|
||||||
|
u, err := url.Parse(raw)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
q := u.Query().Get(rule.Name)
|
||||||
|
if q == "" {
|
||||||
|
return "", fmt.Errorf("missing JSON URL query %s", rule.Name)
|
||||||
|
}
|
||||||
|
return q, nil
|
||||||
case "response.header":
|
case "response.header":
|
||||||
v := headerValue(resp.Headers, rule.Name)
|
v := headerValue(resp.Headers, rule.Name)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user