anylist

command module
v0.0.0-...-a903834 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2023 License: MIT Imports: 15 Imported by: 0

README

(Br)AnyList

(Br)AnyList is a mobile-friendly (mobile-only?) frontend for viewing and modifying lists on AnyList.

The backend code is heavily inspired by https://github.com/codetheweb/anylist

Screenshot

It looks like this:

Screenshot of a basic grocery list

Running Locally

Initial Setup

Unmodified, the backend takes in your user credentials via a sops-encrypted file. For your own use, you can either rip out this mechanism and use your own (hardcoded or env vars or flags, etc), or generate your own sops-encrypted file. Here's a quick example of how to do that using age for key material generation.

# Generate a new key for sops to use.
age-keygen -o $XDG_CONFIG_HOME/sops/age/keys.txt
# This will output something like:
# Public key: <public key, starts with 'age'>

# Write the plaintext JSON file with your credentials. You can also create the
# file with sops directly if you don't want the plaintext to touch your disk.
cat >secrets.json <<EOL
{
  "email": "...",
  "password": "..."
}
EOL

# Encrypt the file with your age public key.
sops encrypt --age <public key> secrets.json > secrets.enc.json
Commands
# Run the backend
go run .

# In a different window, run the frontend
cd frontend
pnpm dev

The site is accessible on localhost:5173.

The Extremely Mundane Story

I received an AnyList subscription as a Christmas gift, but I'm not a big fan of downloading apps. The AnyList website is nice, but it doesn't work well on mobile. My needs are simple, a Google Keep-like add/view/remove items from a list type of functionality. That's what this project will attempt to provide.

What Works

The basics: Authentication, loading list data, adding/removing/checking/ unchecking items. Checked items go to the end.

What Doesn't Work

Anything else. Specifically:

  • Any sort of live updating
  • Any sort of reordering
  • Categories
  • Prices
  • Photos

With the exception of live updating, I probably won't even attempt to add any other functionality.

Deployment

Building Release Artifacts

You can build the frontend and the backend as Docker containers.

For the backend:

# From the root directory
docker build -t your.docker.host/anylist .

For the frontend:

cd frontend
pnpm build:cloud
docker build -t your.docker.host/anylist-fe .
Running

Personally, I run the two containers behind an NGINX server (also in Docker) using basic auth, using something like this:

For running the containers:

# Create a network for the frontend to reach the backend
docker network create some-net

# Run the backend. I bake an age-encrypted sops [1] file into my Docker image
# and then mount the decryption key.
# [1] https://github.com/mozilla/sops#encrypting-using-age
docker run --network=some-net \
  --restart=always \
  --name anylist \
  -e "SOPS_AGE_KEY_FILE=/secrets/keys.txt" \
  -v /var/lib/srv/anylist/keys.txt:/secrets/keys.txt:ro \
  <my Docker registry>/anylist

# Run the frontend, point it at the backend's address on the Docker network.
docker run --network=some-net \
  --restart=always \
  --name anylist-fe \
  -e "PUBLIC_API_BASE_URL=http://anylist:8080" \
  <my Docker registry>/anylist-fe

Here's an example NGINX config, should go in a .conf file somewhere.

server {
  listen 80;
  listen [::]:80;

  # Redirect HTTP -> HTTPS
  server_name <domain>;
  return 301 https://<domain>$request_uri;
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name <domain>;

  # TLS config with LetsEncrypt
  include /etc/nginx/letsencrypt.conf;
  ssl_certificate /etc/letsencrypt/live/<domain cert>/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/<domain cert>/privkey.pem;

  satisfy any;

  # Don't allow any traffic except basic auth.
  deny all;

  # Basic auth user/pass live in an htpasswd file
  auth_basic "forbidden";
  auth_basic_user_file /etc/nginx/conf.d/htpasswd;

  # Default traffic to the Svelte app
  location / {
    proxy_set_header  X-Forwarded-For   $remote_addr;
    proxy_set_header  X-Forwarded-Proto $scheme;

    resolver 127.0.0.11 valid=10s;
    set $upstreamName anylist-fe:3000;
    proxy_pass                          http://$upstreamName;
    proxy_set_header  Host              $http_host;
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
  }

  # Forward API requests onto the backend directly,
  location /api/ {
    proxy_set_header  X-Forwarded-For   $remote_addr;
    proxy_set_header  X-Forwarded-Proto $scheme;

    resolver 127.0.0.11 valid=10s;
    set $upstreamName anylist:8080;
    proxy_pass                          http://$upstreamName;
    proxy_set_header  Host              $http_host;
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
  }
}

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL