Repository: simonw/datasette-publish-vercel (language: python)

Issue:
Signing secret not used
When deploying a Datasette instance to Vercel combined with plugins requiring the signing secret (e.g. `datasette-auth-passwords`):

- Authentication is disconnected after navigating for a few pages
- The following message appears when logging for the second time: "form-urlencoded POST field did not match cookie"

This is clearly a CSRF token issue. After some investigation, it seems the `DATASETTE_SECRET` environment variable is not taken into account after deployment:

- `datasette publish vercel` command generates and sets a Vercel environment variable named `DATASETTE_SECRET`
- In the serverless function `index.py`, the `DATASETTE_SECRET` is never picked up and a new secret is generated (`DATASETTE_SECRET` is only picked-up by the `datasette` CLI)
- Quite oftern a new copy of the serverless function is called server-side thus rotating the secret automatically!

The fix seems easy enough, I'll propose a PR to fix the serverless function to pick-up the `DATASETTE_SECRET` env var.



Discussion / hints:
To debug this issue, here is a simple reproduction setup:

- `plugins/debug.py`
```python
from datasette import hookimpl
import os


@hookimpl
def extra_template_vars(
    template, database, table, columns, view_name, request, datasette
):
    return {
        "secret": datasette._secret,
        "env_secret": os.environ.get("DATASETTE_SECRET"),
    }
```

- `templates/pages/debug.html`
```html
<p>{{ secret }}</p>
<p>{{ env_secret }}</p>
```

- Deploy:
```bash
datasette publish vercel --template-dir templates --plugins-dir plugins --project=ds-debug-secret
```

- Go to `/debug`: both values should be equal but they are not


Fix patch:
diff --git a/datasette_publish_vercel/__init__.py b/datasette_publish_vercel/__init__.py
index a3c894b..0152651 100644
--- a/datasette_publish_vercel/__init__.py
+++ b/datasette_publish_vercel/__init__.py
@@ -21,6 +21,7 @@
 from datasette.app import Datasette
 import json
 import pathlib
+import os
 
 static_mounts = [
     (static, str((pathlib.Path(".") / static).resolve()))
@@ -33,11 +34,14 @@
 except Exception:
     pass
 
+secret = os.environ.get("DATASETTE_SECRET")
+
 app = Datasette(
     [],
     {database_files},
     static_mounts=static_mounts,
     metadata=metadata{extras},
+    secret=secret,
     cors=True,
     config={settings}
 ).app()


Test patch:
diff --git a/tests/test_publish_vercel.py b/tests/test_publish_vercel.py
index 998bd0f..fb88497 100644
--- a/tests/test_publish_vercel.py
+++ b/tests/test_publish_vercel.py
@@ -216,6 +216,7 @@ def test_publish_vercel_generate(generated_app_dir):
     from datasette.app import Datasette
     import json
     import pathlib
+    import os
 
     static_mounts = [
         (static, str((pathlib.Path(".") / static).resolve()))
@@ -228,11 +229,14 @@ def test_publish_vercel_generate(generated_app_dir):
     except Exception:
         pass
 
+    secret = os.environ.get("DATASETTE_SECRET")
+
     app = Datasette(
         [],
         ["test.db"],
         static_mounts=static_mounts,
         metadata=metadata,
+        secret=secret,
         cors=True,
         config={"default_page_size": 10, "sql_time_limit_ms": 2000}
     ).app()