Skip to content

Commit 0fa58a1

Browse files
committed
separate ajax proxy as middleware for reuse in other project
1 parent e17f6b8 commit 0fa58a1

File tree

6 files changed

+139
-74
lines changed

6 files changed

+139
-74
lines changed

Procfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
web: node proxy.js
1+
web: node lib/app.js

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ $ npm install
2121
Run proxy server :
2222

2323
```
24-
$ node proxy.js
24+
$ npm start
2525
```
2626

2727
When you use JSforce in your JavaScript app, set `proxyUrl` when creating `Connection` instance.
@@ -38,6 +38,25 @@ conn.query('SELECT Id, Name FROM Account', function(err, res) {
3838
});
3939
```
4040

41+
## Using as Middleware
42+
43+
Ajax proxy works as connect middleware. For example you can include the proxy functionality in your express.js app :
44+
45+
```javascript
46+
var express = require('express');
47+
var jsforceAjaxProxy = require('./proxy');
48+
var app = express();
49+
50+
app.all('/proxy/?*', jsforceAjaxProxy());
51+
```
52+
53+
If you want to accept http request from other origin, set `enableCORS` option to true.
54+
55+
```javascript
56+
app.all('/proxy/?*', jsforceAjaxProxy({ enableCORS: true });
57+
```
58+
59+
4160
## Note
4261
4362
You don't have to use this app when you are building a JSforce app in Visualforce,

lib/proxy.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
var request = require('request');
2+
var debug = require('debug')('jsforce-ajax-proxy');
3+
4+
/**
5+
* Allowed request headers
6+
*/
7+
var ALLOWED_HEADERS = [
8+
'Authorization',
9+
'Content-Type',
10+
'Salesforceproxy-Endpoint',
11+
'X-Authorization',
12+
'X-SFDC-Session',
13+
'SOAPAction',
14+
'SForce-Auto-Assign',
15+
'If-Modified-Since',
16+
'X-User-Agent'
17+
];
18+
19+
/**
20+
* Endpoint URL validation
21+
*/
22+
var SF_ENDPOINT_REGEXP =
23+
/^https:\/\/[a-zA-Z0-9\.\-]+\.(force|salesforce|cloudforce|database)\.com\//;
24+
25+
/**
26+
* Create middleware to proxy request to salesforce server
27+
*/
28+
module.exports = function(options) {
29+
30+
options = options || {}
31+
var proxyCounter = 0;
32+
33+
return function(req, res) {
34+
if (options.enableCORS) {
35+
res.header('Access-Control-Allow-Origin', options.allowedOrigin || '*');
36+
res.header('Access-Control-Allow-Methods', 'GET,POST,PATCH,PUT,DELETE');
37+
res.header('Access-Control-Allow-Headers', ALLOWED_HEADERS.join(','));
38+
res.header('Access-Control-Expose-Headers', 'SForce-Limit-Info');
39+
if (req.method === 'OPTIONS') {
40+
res.end();
41+
return;
42+
}
43+
}
44+
var sfEndpoint = req.headers["salesforceproxy-endpoint"];
45+
if (!SF_ENDPOINT_REGEXP.test(sfEndpoint)) {
46+
res.send(400, "Proxying endpoint is not allowed.");
47+
return;
48+
}
49+
var headers = {};
50+
ALLOWED_HEADERS.forEach(function(header) {
51+
header = header.toLowerCase();
52+
var value = req.headers[header]
53+
if (value) {
54+
var name = header === 'x-authorization' ? 'authorization' : header;
55+
headers[name] = req.headers[header];
56+
}
57+
});
58+
var params = {
59+
url: sfEndpoint || "https://login.salesforce.com//services/oauth2/token",
60+
method: req.method,
61+
headers: headers
62+
};
63+
proxyCounter++;
64+
debug("(++req++) " + new Array(proxyCounter+1).join('*'));
65+
debug("method=" + params.method + ", url=" + params.url);
66+
req.pipe(request(params))
67+
.on('response', function() {
68+
proxyCounter--;
69+
debug("(--res--) " + new Array(proxyCounter+1).join('*'));
70+
})
71+
.on('error', function() {
72+
proxyCounter--;
73+
debug("(--err--) " + new Array(proxyCounter+1).join('*'));
74+
})
75+
.pipe(res);
76+
}
77+
};

lib/server.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*global process */
2+
var http = require('http');
3+
var express = require('express');
4+
var jsforceAjaxProxy = require('./proxy');
5+
6+
var app = express();
7+
8+
app.configure(function () {
9+
app.set('port', process.env.PORT || 3123);
10+
});
11+
12+
app.configure('development', function () {
13+
app.use(express.errorHandler());
14+
});
15+
16+
app.all('/proxy/?*', jsforceAjaxProxy({ enableCORS: true }));
17+
18+
app.get('/', function(req, res) {
19+
res.send('JSforce AJAX Proxy');
20+
});
21+
22+
http.createServer(app).listen(app.get('port'), function () {
23+
console.log("Express server listening on port " + app.get('port'));
24+
});

package.json

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
{
2-
"name": "node-salesforce-proxy",
3-
"private": true,
2+
"name": "jsforce-ajax-proxy",
3+
"description": "Ajax proxy server to access Salesforce APIs from browser JavaScript resides in outer domain.",
4+
"version": "1.0.0",
5+
"main": "lib/proxy.js",
6+
"scripts": {
7+
"start": "node lib/server.js"
8+
},
9+
"files": [
10+
"lib",
11+
"LICENSE",
12+
"Procfile",
13+
"README.md",
14+
"package.json"
15+
],
416
"dependencies": {
5-
"express": "3.12.x",
6-
"request": "2.36.x"
17+
"debug": "^2.1.2",
18+
"express": "^3.12.1",
19+
"request": "^2.36.0"
720
}
821
}

proxy.js

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)