From f55b119eb6b6682066517e827e6bf2f698effc90 Mon Sep 17 00:00:00 2001 From: Campbell Allen Date: Thu, 21 Nov 2019 16:26:05 +0000 Subject: [PATCH 1/6] split makeHTTPRequest to distinct methods isolate the credentialed (user sessions) requests from non-credentialed (API) into distinct methods. This will fix ensure we don't run across CORS errors when using credentialed XMLHTTPRequests for open (wildcard) cors origins and will whitelist allowed cors origins for credentialed resource requests --- src/json-api-client.coffee | 3 ++- src/make-http-request.coffee | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/json-api-client.coffee b/src/json-api-client.coffee index 12e9f11..674d467 100644 --- a/src/json-api-client.coffee +++ b/src/json-api-client.coffee @@ -110,7 +110,8 @@ class JSONAPIClient extends Model @_typesCache[name] module.exports = JSONAPIClient -module.exports.makeHTTPRequest = makeHTTPRequest +module.exports.makeHTTPRequest = makeHTTPRequest.makeHTTPRequest +module.exports.makeCredentialHTTPRequest = makeHTTPRequest.makeCredentialHTTPRequest module.exports.Emitter = Emitter module.exports.Type = Type module.exports.Model = Model diff --git a/src/make-http-request.coffee b/src/make-http-request.coffee index 17ff9c5..fd8007b 100644 --- a/src/make-http-request.coffee +++ b/src/make-http-request.coffee @@ -13,6 +13,14 @@ request.parse ?= {} request.parse[DEFAULT_HEADERS['Accept']] = JSON.parse.bind JSON makeHTTPRequest = (method, url, data, headers = {}, query) -> + makeRequest(request, method, url, data, headers = {}, query) + +makeCredentialHTTPRequest = (method, url, data, headers = {}, query) -> + if request.withCredentials? + request = request.withCredentials() + makeRequest(request, method, url, data, headers = {}, query) + +makeRequest = (request, method, url, data, headers = {}, query) -> originalArguments = Array::slice.call arguments # In case we need to retry method = method.toLowerCase() url = normalizeUrl url @@ -35,9 +43,6 @@ makeHTTPRequest = (method, url, data, headers = {}, query) -> req = req.set headers - if req.withCredentials? - req = req.withCredentials() - req.end (error, response) -> delete getsInProgress[requestID] if error?.status is 408 @@ -54,4 +59,4 @@ makeHTTPRequest = (method, url, data, headers = {}, query) -> promisedRequest -module.exports = makeHTTPRequest +module.exports = { makeHTTPRequest, makeCredentialHTTPRequest } From 137af2ccd828a00fbafa5f7d319119e893189ef6 Mon Sep 17 00:00:00 2001 From: Sarah Allen Date: Thu, 21 Nov 2019 12:36:50 -0600 Subject: [PATCH 2/6] Fix bug with calling makeHTTPRequest due to change in exports --- src/json-api-client.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/json-api-client.coffee b/src/json-api-client.coffee index 674d467..be26f50 100644 --- a/src/json-api-client.coffee +++ b/src/json-api-client.coffee @@ -42,7 +42,7 @@ class JSONAPIClient extends Model else if method in WRITE_OPS @update writes: @writes + 1 - request = makeHTTPRequest method, fullURL, fullPayload, allHeaders, query + request = makeHTTPRequest.makeHTTPRequest method, fullURL, fullPayload, allHeaders, query request .catch => From ee59b7425b8cf81e9625b8cfe8c4cc43b45ef900 Mon Sep 17 00:00:00 2001 From: Campbell Allen Date: Fri, 22 Nov 2019 13:18:51 +0000 Subject: [PATCH 3/6] ensure we pass the header params --- src/make-http-request.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/make-http-request.coffee b/src/make-http-request.coffee index fd8007b..645f474 100644 --- a/src/make-http-request.coffee +++ b/src/make-http-request.coffee @@ -13,14 +13,14 @@ request.parse ?= {} request.parse[DEFAULT_HEADERS['Accept']] = JSON.parse.bind JSON makeHTTPRequest = (method, url, data, headers = {}, query) -> - makeRequest(request, method, url, data, headers = {}, query) + makeRequest(request, method, url, data, headers, query) makeCredentialHTTPRequest = (method, url, data, headers = {}, query) -> if request.withCredentials? request = request.withCredentials() - makeRequest(request, method, url, data, headers = {}, query) + makeRequest(request, method, url, data, headers, query) -makeRequest = (request, method, url, data, headers = {}, query) -> +makeRequest = (request, method, url, data, headers, query) -> originalArguments = Array::slice.call arguments # In case we need to retry method = method.toLowerCase() url = normalizeUrl url From fcc45afd9537bc82041ffc45cd481bb4ce9b833e Mon Sep 17 00:00:00 2001 From: Campbell Allen Date: Fri, 22 Nov 2019 13:23:21 +0000 Subject: [PATCH 4/6] fix indenting --- src/make-http-request.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/make-http-request.coffee b/src/make-http-request.coffee index 645f474..72fa8b5 100644 --- a/src/make-http-request.coffee +++ b/src/make-http-request.coffee @@ -17,7 +17,7 @@ makeHTTPRequest = (method, url, data, headers = {}, query) -> makeCredentialHTTPRequest = (method, url, data, headers = {}, query) -> if request.withCredentials? - request = request.withCredentials() + request = request.withCredentials() makeRequest(request, method, url, data, headers, query) makeRequest = (request, method, url, data, headers, query) -> From 05c66ef3198d87897246034b00c325fdd42466b5 Mon Sep 17 00:00:00 2001 From: Campbell Allen Date: Fri, 22 Nov 2019 15:51:50 +0000 Subject: [PATCH 5/6] use an agent() to isolate credential requests ensure makeHTTPRequest does not use credentials and makeCredentialHTTPRequest does by using an agent() instead of the singleton from the require --- src/make-http-request.coffee | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/make-http-request.coffee b/src/make-http-request.coffee index 72fa8b5..1aec1ac 100644 --- a/src/make-http-request.coffee +++ b/src/make-http-request.coffee @@ -4,21 +4,22 @@ normalizeUrl = require 'normalizeurl' getsInProgress = {} -if request.agent? - request = request.agent() - # Superagent will only auto-parse responses from a Content-Type header it recognizes. # Add the Accept in use by the JSON API spec, which is what will be sent back from the server. request.parse ?= {} request.parse[DEFAULT_HEADERS['Accept']] = JSON.parse.bind JSON +# isolate the credential requests from the superagent singleton +# via the agent() to ensure correct credentials for both request types +# http://visionmedia.github.io/superagent/#agents-for-global-state +if request.agent? && request.withCredentials? + credentialRequest = request.agent().withCredentials() + makeHTTPRequest = (method, url, data, headers = {}, query) -> makeRequest(request, method, url, data, headers, query) makeCredentialHTTPRequest = (method, url, data, headers = {}, query) -> - if request.withCredentials? - request = request.withCredentials() - makeRequest(request, method, url, data, headers, query) + makeRequest(credentialRequest, method, url, data, headers, query) makeRequest = (request, method, url, data, headers, query) -> originalArguments = Array::slice.call arguments # In case we need to retry From ac2a05ce961ad11cfe387c343ccbf83ddd01e67a Mon Sep 17 00:00:00 2001 From: Campbell Allen Date: Fri, 22 Nov 2019 17:27:54 +0000 Subject: [PATCH 6/6] setup credential request correctly --- src/make-http-request.coffee | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/make-http-request.coffee b/src/make-http-request.coffee index 1aec1ac..449a427 100644 --- a/src/make-http-request.coffee +++ b/src/make-http-request.coffee @@ -12,8 +12,14 @@ request.parse[DEFAULT_HEADERS['Accept']] = JSON.parse.bind JSON # isolate the credential requests from the superagent singleton # via the agent() to ensure correct credentials for both request types # http://visionmedia.github.io/superagent/#agents-for-global-state -if request.agent? && request.withCredentials? - credentialRequest = request.agent().withCredentials() +if request.agent? + credentialRequest = request.agent() + if credentialRequest.withCredentials? + credentialRequest = credentialRequest.withCredentials() +else + # ensure the credentialRequest is set, though it would use the + # singleton superagent and fail to correctly send credential requests + credentialRequest = request makeHTTPRequest = (method, url, data, headers = {}, query) -> makeRequest(request, method, url, data, headers, query)