{"id":26480587,"url":"https://github.com/clouedoc/things3-server","last_synced_at":"2026-04-30T03:34:41.009Z","repository":{"id":264986554,"uuid":"891082481","full_name":"clouedoc/things3-server","owner":"clouedoc","description":"A Things3 server with a focus on preserving your privacy.","archived":false,"fork":false,"pushed_at":"2024-11-27T07:16:59.000Z","size":25,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-07T19:43:36.376Z","etag":null,"topics":["things3"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clouedoc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-19T17:37:48.000Z","updated_at":"2025-03-25T16:31:56.000Z","dependencies_parsed_at":"2024-11-27T14:21:37.570Z","dependency_job_id":null,"html_url":"https://github.com/clouedoc/things3-server","commit_stats":null,"previous_names":["clouedoc/things3-server"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/clouedoc/things3-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clouedoc%2Fthings3-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clouedoc%2Fthings3-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clouedoc%2Fthings3-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clouedoc%2Fthings3-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clouedoc","download_url":"https://codeload.github.com/clouedoc/things3-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clouedoc%2Fthings3-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32453968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["things3"],"created_at":"2025-03-20T02:35:43.961Z","updated_at":"2026-04-30T03:34:40.981Z","avatar_url":"https://github.com/clouedoc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Things3 Server\n\n\u003e A Things3 server with a focus on preserving your privacy.\n\nTODO lists contain a ton of sensitive information. From your habits,\nhopes\u0026dreams and your bank passwords, they constitute an ideal target for both\npassive mass surveillance, targeted attacks or rogue employees.\n\nThus, ideally, as one's TODO list, one should be meticulous about the software\nthey pick. In practice, it's challenging enough to find an app that you like,\nand straight impossible to find one that both meets your operative requirements\nand security requirements.\n\nEnter `things3-server`: my small contribution to making your life easier, as a\nbusy hacker trying to organize your life!\n\n`things3-server` is a simple HTTPS server that (currently) proxies the requests\nmade by the Things3 apps to Things3 Cloud.\n\nHowever, it encrypts the text contents, which prevents your data from being\nstored on Things3's servers plaintext.\n\n## WIP\n\nI personally use this software. It works, but it's not perfect.\n\nHere are some areas I would like to improve:\n\n- It shouldn't even use Things3 Cloud as a backend. There is no reason to expose\n  metadata to the app developers. The API is quite simple and could be\n  replicated quite easily. This will be the next milestone for `things3-server`.\n- It leaks if the DNS interception fails, e.g., if Tailscale gets disconnected,\n  and you create a task, it will be stored plaintext on their server forever\n  - ...unless you delete your account, or you log in again + choose to preserve\n    only the data stored on your device.\n  - Do note that it works and is handled gracefully by the current version of\n    the software, as plaintext data gets re-encrypted once edited from another\n    device. However, beware that the full history of all edits is conserved and\n    visible from the Things3 Cloud API.\n- You add your server as a point of failure. If someone gets access to your\n  hosting server, your data is going to be compromised.\n\n## Installation\n\nThis section contains the (currently unfinished) installation instructions.\n\nBeware that the setup is a bit convoluted, so if you're not super tech-savvy,\nyou should email me so that I can ping you once a more consumer-grade version of\nthe software is available.\n\n### Overview\n\nTo connect to the Things3 cloud server, the Things3 app issues a DNS request to\n`cloud.culturedcode.com`. `things3-server` works by configuring a custom DNS\nserver that returns an IP address of a server we control as well as installing\nan SSL certificate on MacOS\u0026iOS that allows `things3-server` to present itself\nas `cloud.culturedcode.com`.\n\nHere is a step-by-step explanation of how it works:\n\n1. Things3 asks our custom DNS server the IP address of `cloud.culturedcode.com`\n2. Our DNS server returns `1.2.3.4` (the IP of our `things3-server`\n   installation)\n3. Things3 connects to `1.2.3.4`\n4. `things3-server` responds with our custom SSL certificate\n5. Things3 will approve the certificate since we previously installed it on our\n   iPhone/Mac/iPad\n6. Things3 communicates with `things3-server` which encrypts\u0026decrypts sensitive\n   fields in the data on-the-fly.\n\n### Setting up a server\n\n1. Any host will do\n2. Make sure to block port 53 and 443 in your firewall as you'll use Tailscale\n   to communicate with your server\n3. Install Tailscale, make sure to connect it to the same Tailnet as your iPhone\n   and Mac\n\n### Setting up DNS interception\n\n1. Setup Tailscale on your hosting server\n2. Setup Tailscale on your iPhone + MacOS device\n3. Tailscale: edit DNS settings. In \"Nameservers,\" add a nameserver that points\n   to your hosting server's Tailscale IP. Enable Split DNS for\n   cloud.culturedcode.com.\n4. Run the DNS server with `deno run --allow-net dns.ts`\n\n### Setting up a custom SSL certificate for cloud.culturedcode.com\n\n#### Generating the SSL certificate\n\n```bash\nmkdir ssl \u0026\u0026 cd ssl\nopenssl genrsa -out cert.key 2048\n# Note: a SAN is required by iOS. Otherwise, an error will be thrown and visible in the console.\n# If you have issue, look at the console for this log line: Trust evaluate failure: [leaf SSLHostname]\nopenssl req -new -x509 -key cert.key -out cert.crt -days 365 \\\n  -subj \"/C=NL/ST=Zuid Holland/L=Rotterdam/O=ACME Corp/OU=Security Department/CN=cloud.culturedcode.com\" \\\n  -addext \"subjectAltName = DNS:cloud.culturedcode.com,DNS:cloud.culturedcode.com\"\ncat cert.key cert.crt \u003e cert.pem\ncd ../\n```\n\n#### Installing the SSL Certificate\n\nThis section shows how to install the SSL certificate on different platforms.\n\nContributions showcasing more complete installation instructions are welcome.\n\n##### MacOS\n\nDouble-click on `ssl/cert.crt`.\n\nClick \"details\" and click \"always trust.\"\n\nInstall the certificate in the \"System\" keychain.\n\n##### iOS\n\nAirDrop `ssl/cert.crt` to your iPhone.\n\nPick \"iPhone\" if asked where to install the certificate.\n\nGo to your settings, find the certificate and install it.\n\nThen, type \"Trust\" in your search bar, and find a toggle that says\n\"cloud.culturedcode.com\"; activate it.\n\n## Maintenance\n\nIf you are upgrading to a new version that encrypts a new field, you will have to \"reset\" your history.\n\nIt's also useful to do this if you accidentally added a task from a client connected directly to Things Cloud rather\nthan your personal server, in which case, the data was sent unencrypted.\n(a future version will store the data\non your server directly, which should prevent this class of issues altogether)\n\n### Taking a backup\n\nJust making sure to not use the Things app on your phone; it'll serve as a backup if anything goes wrong.\n\n### Operation\n\n1. Sign out of Things Cloud\n2. Sign in again\n3. When asked, say to upload tasks from your Mac\n4. Done! Your Things Cloud history is now a clean single encrypted update.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclouedoc%2Fthings3-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclouedoc%2Fthings3-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclouedoc%2Fthings3-server/lists"}