{"id":15691485,"url":"https://github.com/anandchowdhary/words","last_synced_at":"2026-04-29T18:32:54.436Z","repository":{"id":78706258,"uuid":"123892483","full_name":"AnandChowdhary/words","owner":"AnandChowdhary","description":"Words doesn't come in the way of you and your thoughts","archived":false,"fork":false,"pushed_at":"2023-02-17T15:02:56.000Z","size":17,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T18:58:21.738Z","etag":null,"topics":["cms","json","php","writing"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/AnandChowdhary.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}},"created_at":"2018-03-05T09:00:12.000Z","updated_at":"2025-08-13T09:06:26.000Z","dependencies_parsed_at":"2023-03-20T08:47:07.170Z","dependency_job_id":null,"html_url":"https://github.com/AnandChowdhary/words","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/AnandChowdhary/words","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnandChowdhary%2Fwords","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnandChowdhary%2Fwords/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnandChowdhary%2Fwords/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnandChowdhary%2Fwords/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AnandChowdhary","download_url":"https://codeload.github.com/AnandChowdhary/words/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AnandChowdhary%2Fwords/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32439179,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T18:12:22.909Z","status":"ssl_error","status_checked_at":"2026-04-29T18:11:33.322Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cms","json","php","writing"],"created_at":"2024-10-03T18:21:50.663Z","updated_at":"2026-04-29T18:32:54.421Z","avatar_url":"https://github.com/AnandChowdhary.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Words\n\nWords is a platform to _just_ write. It doesn't come in the way of you and your thoughts, with complete data privacy.\n\n## How it works\n\nThis repo contains a REST CRUD API for the backend of Words, a platform I made to write and share words with my significant other. You can make a nice frontend to make it all work, or use my repo [vue-words](https://github.com/AnandChowdhary/vue-words) for a headstart.\n\nIt uses the crypto library [OpenSSL](http://php.net/manual/en/intro.openssl.php) to securely encrypt every word you write, with token-based authentication using [JWT](https://github.com/firebase/php-jwt).\n\nIt's database-free, since it uses a JSON file structure to store everything, so you can easily make file backups, import and export data, and manage it completely without any privacy breaches.\n\n## Structure\n\nWords uses a single file, `meta.json` in the root for all your settings. This file contains the directory location to save and view all posts from, as well as your root password, OpenSSL key and initialization vector.\n\nIt looks something like this:\n\n```\n{\n\t\"files\": \"./words/\",\n\t\"key\": \"example_secure_key\",\n\t\"iv\": \"example_initialization_vector\",\n\t\"password\": \"$2y$10$wc5FaC/hnNipOAMHLh4yxuaYFBm0wSa1mE07mH187JSDCumtujfk6\",\n\t\"token_valid_for\": \"25 hours\"\n}\n```\n\nThe `password` in this file is an output of `password_hash(\"example_password\", PASSWORD_DEFAULT)`. You should use the same function to generate a hash of your password and store it in this file.\n\nAn example post looks like then when saved:\n\n```\n{\n    \"title\": \"TmZRWXZZVDNBM21LWWJ1WW9Fd1FzZz09\",\n    \"date\": \"2018-03-05 11:33:20\",\n    \"body\": \"R2d5SkkrTTJrVWlCWjZubkU4T3VvTElPRU1mdzNkM1cySFJGTmNJTTlGWT0=\"\n}\n```\n\nSo, only when you have the same `meta.json` parameters will you be able to decrypt the contents and view the post.\n\n## REST API\n\nAll requests (except when generating a new token) need to be authenticated with a `token` header.\n\n### `POST /` to get a new token\n\nRequest body:\n\n```\n{\n\t\"password\": \"example_password\"\n}\n```\n\nResponse body:\n\n```\n{\n    \"api\": \"words\",\n    \"version\": \"4.1\",\n    \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHBpcmVzIjoiMjAxOC0wMy0wNiAxMjoyOTo1MiJ9.Coe969vqWQDmd34G04Y5HxOhOaz5citBOr5yEjxI6j0\",\n    \"expires\": \"2018-03-06 12:29:52\"\n}\n```\n\n### `GET /posts` to get a list of all posts\n\nResponse body:\n\n```\n{\n    \"api\": \"words\",\n    \"version\": \"4.1\",\n    \"posts\": [\n        {\n            \"id\": \"20180305104246d5bfde2cdc.json\",\n            \"title\": \"Post title has been edited\",\n            \"date\": \"2018-03-05 11:26:44\"\n        },\n        {\n            \"id\": \"20180305113204b375272648.json\",\n            \"title\": \"Post title\",\n            \"date\": \"2018-03-05 11:32:04\"\n        }\n    ]\n}\n```\n\n### `PUT /posts` to create a new post\n\nRequest body:\n\n```\n{\n\t\"title\": \"Post title\",\n\t\"body\": \"\u003cp\u003eThis is an example post!\u003c/p\u003e\"\n}\n```\n\nResponse body:\n\n```\n{\n    \"api\": \"words\",\n    \"version\": \"4.1\",\n    \"created\": true\n}\n```\n\n### `GET /post/{id}` to get a specific post\n\nResponse body:\n\n```\n{\n    \"api\": \"words\",\n    \"version\": \"4.1\",\n    \"post\": {\n        \"title\": \"Post title has been edited\",\n        \"date\": \"2018-03-05 11:26:44\",\n        \"body\": \"\u003cp\u003eThis is an example post!\u003c/p\u003e\"\n    }\n}\n```\n\n### `DELETE /post/{id}` to delete a specific post\n\nResponse body:\n\n```\n{\n    \"api\": \"words\",\n    \"version\": \"4.1\",\n    \"deleted\": true\n}\n```\n\n### `PUT /post/{id}` to update a specific post\n\nRequest body:\n\n```\n{\n\t\"title\": \"Updated post title\",\n\t\"body\": \"\u003cp\u003eThis is an example post which has been updated!\u003c/p\u003e\"\n}\n```\n\nResponse body:\n\n```\n{\n    \"api\": \"words\",\n    \"version\": \"4.1\",\n    \"updated\": true\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanandchowdhary%2Fwords","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanandchowdhary%2Fwords","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanandchowdhary%2Fwords/lists"}