Rewrite cookie paths when using grunt-connect-proxy - cookies

During development I use grunt-connect-proxy to make some remote APIs locally available. This works just fine, except that the rewrite rules that I use are not applied to cookies:
proxies: [{
context: '/publicPath',
host: 'localhost',
port: 8080,
rewrite: {
'^/publicPath': '/privatePath'
}
}]
If the remote API sets a cookie with path /privatePath it must be rewritten to /publicPath.
E.g. When using Apache httpd I'd use the ProxyPassReverseCookiePath-Directive. How do I do it with grunt-connect-proxy?

Thanks to this answer in "Rewrite response headers with node-http-proxy" I managed to figure it out. I created the following middleware:
function rewriteSetCookie(req, res, next) {
var isProxyRequest = req.url.lastIndexOf('/publicPath', 0) === 0;
if (isProxyRequest) {
// we intercept the writeHead function, so that we can exchange headers just before they are written
var oldWriteHead = res.writeHead;
res.writeHead = function () {
var cookie = res.getHeader('Set-Cookie');
if (cookie) {
res.setHeader('Set-Cookie', cookie.map(function(item) {
// Replace paths in all cookies. The simple string/replace approach might be too naive in some cases, so check before you copy&paste before thinking
return item.replace(/\/privatePath/, '/publicPath');
}));
}
oldWriteHead.apply(res, arguments);
};
}
next();
}
Just for reference here is the full configuration so that you can see how to use the middleware:
connect: {
server: {
options: {
hostname: 'localhost',
base: 'myBaseDir',
open: true,
middleware: function (connect, options) {
if (!Array.isArray(options.base)) {
options.base = [options.base];
}
// Setup the proxy
var middlewares = [rewriteSetCookie, proxySnippet];
// ^^^^^^^^^^^^^^^^- Here is is used!
// Serve static files.
options.base.forEach(function(base) {
middlewares.push(connect.static(base));
});
// Make directory browse-able.
var directory = options.directory || options.base[options.base.length - 1];
middlewares.push(connect.directory(directory));
return middlewares;
}
},
proxies: [{
context: '/publicPath',
host: 'localhost',
port: 8080,
rewrite: {
'^/publicPath': '/privatePath'
}
}]
}
}

Related

when i update to webpack5, there is a error: configuration has an unknown property 'before'

when I update webpack 4 to 5, the error exits.
I have a webpackDevServer.js which include the error message 'error'
// webpackDevServer.js
module.exports = function(proxy, allowedHost) {
return {
before(app, server) {
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
}
// This lets us fetch source contents from webpack for the error overlay
app.use(evalSourceMapMiddleware(server));
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware());
},
};
};
I use the above file in a start.js file, when I run the project, I type node scripts/start.js
// start.js
...
const createDevServerConfig = require('../config/webpackDevServer.config');
...
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
then it throws an error
configuration has an unknown property 'before'. These properties are valid:
object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, injectClient?, injectHot?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, overlay?, port?, proxy?, public?, setupExitSignals?, static?, stdin?, transportMode?, useLocalIp? }
here is my package.json
"webpack": "^5.20.2",
"webpack-dev-server": "^4.0.0-beta.0",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "^6.1.0"
You have to change before to the onBeforeSetupMiddleware. Link with migration description from v3 to v4. https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md
In case, something will change on the migration guide, details are attached below
v3:
module.exports = {
devServer: {
after: function (app, server, compiler) {
app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
v4:
module.exports = {
devServer: {
onAfterSetupMiddleware: function (devServer) {
devServer.app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
fxxk, I'm stupid, when i search some key word (eg: onBeforeSetupMiddleware), I found the github of webpack-dev-server which tell the changes in new version 4.0.0 beta. https://github.com/webpack/webpack-dev-server/releases

How to dynamically change Apollo Web Socket Link URI?

Currently I've set up Apollo's web socket link like so:
const wsLink = new WebSocketLink({
uri: `ws://example.com/graphql?token=${getToken()}`,
options: {
reconnect: true,
connectionParams(): ConnectionParams {
return {
authToken: getToken(),
};
},
},
});
This works fine while the connection lasts, but fails when the connection needs to be re-established if the token in the query string has expired.
The way the infra I'm dealing with is set up requires this token to be set as a query param in the URI. How can I dynamically change the URI so that I may provide a new token when the connection needs to be re-established?
You can set property wsLink.subscriptionClient.url manually (or create a new subscriptionClient instance?) in function setContext https://www.apollographql.com/docs/link/links/context/.
For example:
import { setContext } from 'apollo-link-context'
...
const wsLink = your code...
const authLink = setContext(() => {
wsLink.subscriptionClient.url = `ws://example.com/graphql?token=${getToken()}`
})
...
const config = {
link: ApolloLink.from([
authLink,
wsLink
]),
...
}

Django CSRF token failure risk

On our production server, periodically we suffer from many CSRF token failures. The site does work fine for the rest, and I am aware CSRF failures may be user-side errors. However, for example this morning we received a flood of new failures, so we want to exclude any other possibilities.
An example failure mail today:
{
"GET": {},
"COOKIES": {},
"ERROR": "Referer checking failed - no Referer.",
"USER": "AnonymousUser",
"META": {
"REMOTE_ADDR": "127.0.0.1",
"mod_wsgi.version": "(4, 5, 20)",
"DOCUMENT_ROOT": "/usr/local/apache2/htdocs",
"SERVER_ADDR": "127.0.0.1",
"HTTP_ACCEPT_ENCODING": "gzip, deflate, br",
"wsgi.multithread": "True",
"HTTP_FORWARDED_REQUEST_URI": "/",
"CONTEXT_DOCUMENT_ROOT": "/usr/local/apache2/htdocs",
"wsgi.file_wrapper": "<class 'mod_wsgi.FileWrapper'>",
"mod_wsgi.path_info": "/",
"HTTP_ORIGIN": "chrome-extension://aegnopegbbhjeeiganiajffnalhlkkjb",
(...)
},
"POST": {}
}
Especially the HTTP_ORIGIN looks "interesting": why is this Chrome extension scraping/bullying us?
So essentially: Do we need to be worried about this?
Thanks!
This looks like an oddly coded "feature" in the "Browser Safety" Chrome extension. It tries to check if a URL is valid by sending an empty POST request to it (why?!).
var checkUrlState = function (url) {
var urlState = null;
if (blacklists.indexOf(domainFromUrl((url).toString())) < 0) {
var xhr = new XMLHttpRequest();
try {
xhr.open("POST", url, true);
xhr.timeout = 5000; // time in milliseconds
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
urlState = xhr.status;
} else {
urlState = null;
}
}
xhr.ontimeout = function () {
}
xhr.send();
} catch (e) {
onErrorReceived.call(xhr);
}
}
return urlState;
}
I'm also seeing this on my sites. I would recommend filtering it on the frontend based on the Origin header.

Loopback - How to extend api using loopback

I want to extend my api using loopback . I have read the documentation
'use strict';
module.exports = function(Meetups,pusher) {
Meetups.status = function(cb) {
var currentDate = new Date();
var currentHour = currentDate.getHours();
var OPEN_HOUR = 6;
var CLOSE_HOUR = 20;
console.log('Current hour is %d', currentHour);
var response;
if (currentHour >= OPEN_HOUR && currentHour < CLOSE_HOUR) {
response = 'We are open yeah!!! for business.';
} else {
response = 'Sorry, we are closed. Open daily from 6am to 8pm.';
}
cb(null, response);
};
Meetups.remoteMethod(
'status', {
http: {
path: '/status',
verb: 'get'
},
returns: {
arg: 'status',
type: 'string'
}
}
);
Meetups.pusher = function(cb) {
if (2>1) {
response = 'sending something';
} else {
response = 'mont blanc';
}
cb(null, response);
};
Meetups.remoteMethod(
'pusher', {
http: {
path: '/pusher',
verb: 'get'
},
returns: {
arg: 'pusher',
type: 'string'
}
}
);
};
First, I added /status route and it worked fine. But, when i tried to add /pusher . It just didnt work. I am getting an error
{
"error": {
"statusCode": 500,
"name": "ReferenceError",
"message": "response is not defined",
"stack": "ReferenceError: response is not defined\n at Function.Meetups.pusher (/Users/ankursharma/Documents/projects/meetupz/common/models/meetups.js:34:20)\n at SharedMethod.invoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/shared-method.js:270:25)\n at HttpContext.invoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/http-context.js:297:12)\n at phaseInvoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:677:9)\n at runHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:135:5)\n at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)\n at Object.async.eachSeries (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:162:9)\n at runHandlers (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:144:13)\n at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)\n at /Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:157:25\n at /Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:154:25\n at execStack (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:522:7)\n at RemoteObjects.execHooks (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:526:10)\n at phaseBeforeInvoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:673:10)\n at runHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:135:5)\n at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)"
}
}
I am pretty sure, its a very small mistake. I am beginner in loopback and trying to implement loopback in my project.
In the example they define response as a local variable to that remote method, you did not. Secondly, (Meetups,pusher) you do not need to export pusher here. You are adding to Meetups.
You have to declare response in your pusher remote method.
An alternative way without declaring response is, Simply returning the value.
Example:
Meetups.pusher = function(cb) {
if (2>1) {
return 'sending something';
} else {
return 'mont blanc';
}
};
Define the variable and return the variable or you can directly call the cb in if and else like
Meetups.pusher = function(cb) {
if (2>1) {
cb(null,'sending something');
} else {
cb(null, 'mont blanc');
}
};

Cherrypy configuration for cherrypy.quickstart

This is configuration for /projects endpoint. What modification do i have to add for adding an endpoint "/projects/all" at the same port.
conf = {
'global':{
'server.socket_host': "127.0.0.1",
'server.socket_port': config.SERVER_PORT
},
'/projects': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'application/json')],
}
}
webapp = ApiApp()
webapp.projects = ProjectsApi()
cherrypy.quickstart(webapp, '/', conf)