Allow running the app behind a reverse proxy (#57)

* change url to hide app behind a relative path

* pass some of ther server configuration through to the client

* serve static files and connect to socket.io correctly when a URL Prefix is set

* Revert the changes to opengraph meta tags

opengraph meta tags need to be absolute URLs

* Remove unused commented-out code

* fix background.png url

* use prefix path for open graph metadata

* Revert changes using server side url modifications

* get open graph and socket.io url from request url / window.location

* remove debug console.log

* Fix favicon when not running under "/"

* Add proxying instructions to the README

Co-authored-by: Laurent Mazet <mazet@softndesign.org>
Co-authored-by: ophir <pere.jobs@gmail.com>
This commit is contained in:
finnboeger 2020-05-01 12:33:13 +02:00 committed by GitHub
parent 3ba9925d9f
commit 0f0b333335
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 27 deletions

View file

@ -66,6 +66,12 @@ PORT=5001 npm start
This will run WBO directly on your machine, on port 5001, without any isolation from the other services.
### Running WBO on a subfolder
By default, WBO launches his own web server and serves all of its content at the root of the server (on `/`).
If you want to make the server accessible with a different path like https://your.domain.com/wbo/ you have to setup a reverse proxy.
See instructions on our Wiki about [how to setup a reverse proxy for WBO](https://github.com/lovasoa/whitebophir/wiki/Setup-behind-Reverse-Proxies).
## Troubleshooting
If you experience an issue or want to propose a new feature in WBO, please [open a github issue](https://github.com/lovasoa/whitebophir/issues/new).

View file

@ -5,19 +5,20 @@
<meta charset="utf-8" />
<title>{{board}} | WBO | {{translations.collaborative_whiteboard}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" href="board.css" />
<script src="/socket.io/socket.io.js"></script>
<link rel="stylesheet" type="text/css" href="../board.css" />
<script src="../socket.io/socket.io.js"></script>
<meta name="description" content="{{translations.tagline}}'" />
<meta name="keywords"
content="{{translations.collaborative_whiteboard}},online,draw,paint,shared,realtime,wbo,whitebophir" />
<link rel="apple-touch-icon" href="/favicon.svg">
<link rel="apple-touch-icon" href="../favicon.svg">
<link rel="icon" type="image/x-icon" sizes="16x16" href="../favicon.ico">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0" />
<meta property="og:title" content="{{board}} board on WBO" />
<meta property="og:url" content="{{baseUrl}}/boards/{{boardUriComponent}}" />
<meta property="og:image" content="{{baseUrl}}/preview/{{boardUriComponent}}" />
<link rel="canonical" href="{{baseUrl}}/boards/{{boardUriComponent}}?lang={{language}}" />
<meta property="og:url" content="{{baseUrl}}/boards/{{boardUriComponent}}" />
<meta property="og:image" content="{{baseUrl}}/preview/{{boardUriComponent}}" />
<link rel="canonical" href="{{boardUriComponent}}?lang={{language}}" />
{{#languages}}
<link rel="alternate" hreflang="{{.}}" href="{{../baseUrl}}/boards/{{../boardUriComponent}}?lang={{.}}" />
<link rel="alternate" hreflang="{{.}}" href="{{../boardUriComponent}}?lang={{.}}" />
{{/languages}}
</head>
@ -78,17 +79,17 @@
<script type="application/json" id="translations">{{{json translations}}}</script>
<script src="js/path-data-polyfill.js"></script>
<script src="js/minitpl.js"></script>
<script src="js/board.js"></script>
<script src="tools/pencil/pencil.js"></script>
<script src="tools/line/line.js"></script>
<script src="tools/rect/rect.js"></script>
<script src="tools/text/text.js"></script>
<script src="tools/eraser/eraser.js"></script>
<script src="tools/hand/hand.js"></script>
<script src="tools/zoom/zoom.js"></script>
<script src="/js/canvascolor/canvascolor.min.js"></script>
<script src="../js/path-data-polyfill.js"></script>
<script src="../js/minitpl.js"></script>
<script src="../js/board.js"></script>
<script src="../tools/pencil/pencil.js"></script>
<script src="../tools/line/line.js"></script>
<script src="../tools/rect/rect.js"></script>
<script src="../tools/text/text.js"></script>
<script src="../tools/eraser/eraser.js"></script>
<script src="../tools/hand/hand.js"></script>
<script src="../tools/zoom/zoom.js"></script>
<script src="../js/canvascolor/canvascolor.min.js"></script>
</body>
</html>
</html>

View file

@ -1,5 +1,5 @@
html {
background: linear-gradient(135deg, #c4dfffa0, transparent), url(/background.png);
background: linear-gradient(135deg, #c4dfffa0, transparent), url(background.png);
width:100%;
height: 100%;
margin:0;

View file

@ -44,12 +44,12 @@
<div>
<p>{{{translations.public_board_description}}}</p>
<a href="/boards/anonymous" class="wbo-button">{{{translations.open_public_board}}}</a>
<a href="boards/anonymous" class="wbo-button">{{{translations.open_public_board}}}</a>
</div>
<div>
<p>{{{translations.private_board_description}}}</p>
<a href="/random" class="wbo-button">{{{translations.create_private_board}}}</a>
<a href="random" class="wbo-button">{{{translations.create_private_board}}}</a>
</div>
<div>
@ -68,4 +68,4 @@
</footer>
</body>
</html>
</html>

View file

@ -55,6 +55,7 @@ Tools.connect = function() {
this.socket = io.connect('', {
"path": window.location.pathname.split("/boards/")[0] + "/socket.io",
"reconnection": true,
"reconnectionDelay": 100, //Make the xhr connections as fast as possible
"timeout": 1000 * 60 * 20 // Timeout after 20 minutes

View file

@ -83,7 +83,7 @@ function handleRequest(request, response) {
// If there is no dot and no directory, parts[1] is the board name
boardTemplate.serve(request, response);
} else { // Else, it's a resource
request.url = "/" + parts.slice(1).join('/');
request.url = parts.slice(1).join('/');
fileserver(request, response, serveError(request, response));
}
} else if (parts[0] === "download") {
@ -121,7 +121,7 @@ function handleRequest(request, response) {
});
} else if (parts[0] === "random") {
var name = crypto.randomBytes(32).toString('base64').replace(/[^\w]/g, '-');
response.writeHead(307, { 'Location': '/boards/' + name });
response.writeHead(307, { 'Location': 'boards/' + name });
response.end(name);
} else if (parts[0] === "") { // Index page
@ -133,4 +133,4 @@ function handleRequest(request, response) {
}
module.exports = app;
module.exports = app;

View file

@ -31,7 +31,8 @@ class Template {
const accept_languages = parsedUrl.query.lang || request.headers['accept-language'];
const language = accept_language_parser.pick(languages, accept_languages) || 'en';
const translations = TRANSLATIONS[language] || {};
const baseUrl = findBaseUrl(request);
const prefix = request.url.split("/boards/")[0].substr(1);
const baseUrl = findBaseUrl(request) + (prefix ? prefix + "/" : "");
return { baseUrl, languages, language, translations };
}
serve(request, response) {