Home

Awesome

mapeo-web

A small sync and storage service for Mapeo maps.

Mapeo is a peer-to-peer local-first collaborative mapping technology. Laptops and phones can sync map data to each other directly, either by finding each other on the local network, or by syncing to a USB key (sneakernet-style) that can then be synced to other devices.

Mapeo Web is a small web service that provides hosting for Mapeo projects. It does this by advertising itself on the internet (and local network) as a regular Mapeo peer, which Mapeo Desktop and Mapeo Mobile can sync with. It also exposes a web interface that lets you customize which Mapeo projects are hosted by it.

Additionally, to facilitate limited sharing of map data, project owners can share specialty GeoJSON export URLs from filters created by Mapeo Desktop.

Usage

With NodeJS and npm installed, run in a terminal:

npm install --global mapeo-web

and then

mapeo-web

This will output a URL of where the service is running. You can plug any Mapeo project ID into it and have it begin being hosted.

You can also add/remove projects from a remote mapeo-web server.

mapeo-web add <projectKey> <url>
mapeo-web remove <projectKey> <url>
mapeo-web list <url>

Security

A Mapeo Project ID acts as a symmetric encryption key. This means, whoever this ID is shared with can:

So! This ID is very important. It needs to be treated as sensitive information. Any Project ID you enter into a Mapeo Web instance will give the operator of that service access to all of your data. Please be mindful of this.

Mapeo Web allows project owners to generate special GeoJSON export URLs. These URLs are obfuscated so that someone who has the URL will not be able to figure out what the original Project ID that the filter came from was. This is a safe way to control data sharing of a subset of your map data with 3rd parties.

For those who this makes sense to, Mapeo Web uses the blake2b hashing algorithm to hide the original Project ID.

Setting up on a Digital Ocean Droplet

# Paste this into an interactive bash or zsh shell, or save it as a file and run it with sh.

# This will create the service file.
sudo cat << EOF | sudo tee /etc/systemd/system/mapeo-web.service > /dev/null
[Unit]
Description=Mapeo Web sync server

[Service]
Type=simple
ExecStart=$(which mapeo-web) start --port 62736
Restart=always
User=mapeo-web
Group=mapeo-web

[Install]
WantedBy=multi-user.target
EOF

sudo chmod 644 /etc/systemd/system/mapeo-web.service

sudo systemctl daemon-reload
sudo systemctl enable mapeo-web
sudo systemctl start mapeo-web

sudo systemctl status mapeo-web
server {
  server_name cloud.mapeo.app;
  proxy_read_timeout 300;
  proxy_connect_timeout 300;
  proxy_send_timeout 300;

  location / {
    proxy_pass http://localhost:62736;
    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-for $remote_addr;
    port_in_redirect    off;
    proxy_http_version  1.1;
    proxy_set_header    Upgrade         $http_upgrade;
    proxy_set_header    Connection      "Upgrade";
  }
}

Put protected routes behind basic auth

It can be important to prevent servers exposed to the internet from being abused.

An easy way to do that is to put the protected APIs behind basic authentication.

In this case, we might want to use NGINX's basic auth so we don't have to implement it ourselves.

Based on this guide

apt-get install apache2-utils

# Add user 'digidem', will prompt for password
# Omit `-c` flag when adding additional users
sudo htpasswd -c /etc/nginx/.htpasswd digidem

Then you'll want to modify the originally config to look like

server {
  server_name cloud.mapeo.app;
  proxy_read_timeout 300;
  proxy_connect_timeout 300;
  proxy_send_timeout 300;

  auth_basic "Project Setup";
  auth_basic_user_file /etc/nginx/.htpasswd;

  location / {
    proxy_pass http://localhost:62736;
    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-for $remote_addr;
    port_in_redirect    off;
    proxy_http_version  1.1;
    proxy_set_header    Upgrade         $http_upgrade;
    proxy_set_header    Connection      "Upgrade";
  }

  location /replicate/ {
    proxy_pass http://localhost:62736;
    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-for $remote_addr;
    port_in_redirect    off;
    proxy_http_version  1.1;
    proxy_set_header    Upgrade         $http_upgrade;
    proxy_set_header    Connection      "Upgrade";

    auth_basic off;
  }
}

License

ISC