{"id":15417661,"url":"https://github.com/rubeniskov/cuser","last_synced_at":"2025-04-11T17:33:32.983Z","repository":{"id":8686709,"uuid":"59366505","full_name":"rubeniskov/cuser","owner":"rubeniskov","description":"Distributed messaging service 🌐, with no database, no config and using IPFS layer to distribute the storage all over the universe ♾️.","archived":false,"fork":false,"pushed_at":"2023-01-06T16:45:22.000Z","size":16587,"stargazers_count":4,"open_issues_count":20,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-06T04:06:56.229Z","etag":null,"topics":["cid","conversation","hash","ipfs","messaging","service"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubeniskov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-21T15:15:14.000Z","updated_at":"2023-04-29T03:58:58.000Z","dependencies_parsed_at":"2023-01-13T15:01:07.298Z","dependency_job_id":null,"html_url":"https://github.com/rubeniskov/cuser","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubeniskov%2Fcuser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubeniskov%2Fcuser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubeniskov%2Fcuser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubeniskov%2Fcuser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubeniskov","download_url":"https://codeload.github.com/rubeniskov/cuser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248450122,"owners_count":21105624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cid","conversation","hash","ipfs","messaging","service"],"created_at":"2024-10-01T17:16:47.132Z","updated_at":"2025-04-11T17:33:32.963Z","avatar_url":"https://github.com/rubeniskov.png","language":"JavaScript","funding_links":["https://patreon.com/rubeniskov","https://github.com/sponsors/rubeniskov","https://paypal.me/rubeniskov"],"categories":[],"sub_categories":[],"readme":"\n\u003ch1 align=\"center\"\u003e\n  \u003ca href=\"./\"\u003e\u003cimg width=\"250\" src=\"docs/logo.svg\" alt=\"cuser logo\" /\u003e\u003c/a\u003e\n\u003c/h1\u003e\n\n\u003e**C**hatting via **U**ncentralized **S**ervice with **E**ndless **R**esources\n\n\u003ch3 align=\"center\"\u003eDistributed messaging service 🌐, with no database, no config and using IPFS layer to distribute the storage all over the universe ♾️.\u003c/h3\u003e\n\n## Status\n[![testing](https://github.com/rubeniskov/cuser/workflows/testing/badge.svg)](https://github.com/rubeniskov/cuser/actions?query=workflow%3Atesting)\n[![release](https://github.com/rubeniskov/cuser/workflows/release/badge.svg)](https://github.com/rubeniskov/cuser/actions?query=workflow%3Arelease)\n[![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?token=mI2c282XxH)](https://codecov.io/gh/rubeniskov/cuser)\n[![patreon-donate](https://img.shields.io/badge/patreon-donate-yellow.svg)](https://patreon.com/rubeniskov)\n[![github-sponsor](https://img.shields.io/badge/github-donate-yellow.svg)](https://github.com/sponsors/rubeniskov)\n[![paypal-sponsor](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://paypal.me/rubeniskov)\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"./\"\u003e\u003cimg width=\"480\" src=\"docs/demo_reel.gif\" alt=\"cuser logo\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Motivation\n\nMany times I've try to create a webpage where the users can publish their opinions, but it becomes a hard task when you have to prepare an entire ecosystem to store such data. If the information is public, why not distribute such content all over the internet?.\n\nHere is where `cuser` comes out, taking the powerfull of IPFS, stores the comments using the DAG graph.\n\nThis allows create [SPA's Single Page Aplications](https://es.wikipedia.org/wiki/Single-page_application) with capabilities of [statefull](https://www.atlantic.net/vps-hosting/what-is-stateless-stateful-models-web-development/) websites, blogs, etc... and minimize the storing impact of your server.\n\n- Root CID represents the main article which is associated to a hash in IPFS, it can be created using the CID provider of IPFS if the article is not a IPFS distributed file. \n\n## Getting started\n\n```shell\nnpm install -g cuser\n```\n\n## Spam detection\n\nIPFS manage the data in a fashion way, due the CID is generated using a checksum of the content data, so its really easy to track if the user is publishing the same content in many articles and restrict. A user can not publish repeated comments with the same content.\n\n## Restricted comments tree\n\nA user can only replay the last comment, so a user can not replay on himself. This allows to make a conversation where the user only has the capability (if a mistake) to edit his last post until other user continues the conversation. \n\n## Removing / Editing comments\n\nEven though IPFS is a permanet store due p2p distribution, if a user wants to remove a comment, can be done using hash tree which is manipulated at the server side allowing remove or replace a blocks.\n\n## Security \n\nA user can only edits/remove his owns comments, this is a feature which the `@cuser/server` takes on. Checking the user token which is provided by the server itself adding this security layer for prevent users to change other users comments.\n## Diagram \n\u003cimg src=\"./docs/diagram.svg\"\u003e\n\n## Packages\nList of packages currently in existence for cuser\n| name | description | version | coverage | downloads |\n| ---------|---------|---------|---------|--------- |\n| **Cuser** |\n| [`@cuser/cli`](//github.com/rubeniskov/cuser/tree/master/packages/cli) | command line interface | [![npm-version](https://img.shields.io/npm/v/@cuser/cli.svg)](https://www.npmjs.com/package/@cuser/cli) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=cli)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/cli)](https://www.npmjs.com/package/@cuser/cli) |\n| [`@cuser/core`](//github.com/rubeniskov/cuser/tree/master/packages/core) | Core ipfs wrapper | [![npm-version](https://img.shields.io/npm/v/@cuser/core.svg)](https://www.npmjs.com/package/@cuser/core) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=core)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/core)](https://www.npmjs.com/package/@cuser/core) |\n| [`@cuser/publisher`](//github.com/rubeniskov/cuser/tree/master/packages/publisher) | backend publisher logic | [![npm-version](https://img.shields.io/npm/v/@cuser/publisher.svg)](https://www.npmjs.com/package/@cuser/publisher) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=publisher)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/publisher)](https://www.npmjs.com/package/@cuser/publisher) |\n| [`@cuser/reader`](//github.com/rubeniskov/cuser/tree/master/packages/reader) | messages reader from the ipfs transport layer | [![npm-version](https://img.shields.io/npm/v/@cuser/reader.svg)](https://www.npmjs.com/package/@cuser/reader) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=reader)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/reader)](https://www.npmjs.com/package/@cuser/reader) |\n| [`@cuser/auth`](//github.com/rubeniskov/cuser/tree/master/packages/auth) | auth core utility | [![npm-version](https://img.shields.io/npm/v/@cuser/auth.svg)](https://www.npmjs.com/package/@cuser/auth) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=auth)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/auth)](https://www.npmjs.com/package/@cuser/auth) |\n| [`@cuser/store`](//github.com/rubeniskov/cuser/tree/master/packages/store) | store tree changes managment | [![npm-version](https://img.shields.io/npm/v/@cuser/store.svg)](https://www.npmjs.com/package/@cuser/store) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=store)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/store)](https://www.npmjs.com/package/@cuser/store) |\n| [`@cuser/crypto`](//github.com/rubeniskov/cuser/tree/master/packages/crypto) | cuser crypto utilities | [![npm-version](https://img.shields.io/npm/v/@cuser/crypto.svg)](https://www.npmjs.com/package/@cuser/crypto) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=crypto)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/crypto)](https://www.npmjs.com/package/@cuser/crypto) |\n| [`@cuser/validator`](//github.com/rubeniskov/cuser/tree/master/packages/validator) | json schema validator | [![npm-version](https://img.shields.io/npm/v/@cuser/validator.svg)](https://www.npmjs.com/package/@cuser/validator) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=validator)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/validator)](https://www.npmjs.com/package/@cuser/validator) |\n| [`@cuser/utils`](//github.com/rubeniskov/cuser/tree/master/packages/utils) | common utils used by cuser | [![npm-version](https://img.shields.io/npm/v/@cuser/utils.svg)](https://www.npmjs.com/package/@cuser/utils) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=utils)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/utils)](https://www.npmjs.com/package/@cuser/utils) |\n| [`@cuser/client`](//github.com/rubeniskov/cuser/tree/master/packages/client) | client logic for reading and publishing message using restfull transport | [![npm-version](https://img.shields.io/npm/v/@cuser/client.svg)](https://www.npmjs.com/package/@cuser/client) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=client)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/client)](https://www.npmjs.com/package/@cuser/client) |\n| [`@cuser/server`](//github.com/rubeniskov/cuser/tree/master/packages/server) | http server with express | [![npm-version](https://img.shields.io/npm/v/@cuser/server.svg)](https://www.npmjs.com/package/@cuser/server) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=server)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/server)](https://www.npmjs.com/package/@cuser/server) |\n| **Clients** |\n| **Types** |\n| [`@cuser/proto`](//github.com/rubeniskov/cuser/tree/master/packages/proto) | typing, schemas and services based in protocol buffers | [![npm-version](https://img.shields.io/npm/v/@cuser/proto.svg)](https://www.npmjs.com/package/@cuser/proto) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=proto)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/proto)](https://www.npmjs.com/package/@cuser/proto) |\n| **Middlewares** |\n| [`@cuser/express-middleware-auth`](//github.com/rubeniskov/cuser/tree/master/packages/express-middleware-auth) |  | [![npm-version](https://img.shields.io/npm/v/@cuser/express-middleware-auth.svg)](https://www.npmjs.com/package/@cuser/express-middleware-auth) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=express-middleware-auth)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/express-middleware-auth)](https://www.npmjs.com/package/@cuser/express-middleware-auth) |\n| [`@cuser/express-middleware-rest`](//github.com/rubeniskov/cuser/tree/master/packages/express-middleware-rest) |  | [![npm-version](https://img.shields.io/npm/v/@cuser/express-middleware-rest.svg)](https://www.npmjs.com/package/@cuser/express-middleware-rest) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=express-middleware-rest)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/express-middleware-rest)](https://www.npmjs.com/package/@cuser/express-middleware-rest) |\n| [`@cuser/express-middleware-graphql`](//github.com/rubeniskov/cuser/tree/master/packages/express-middleware-graphql) |  | [![npm-version](https://img.shields.io/npm/v/@cuser/express-middleware-graphql.svg)](https://www.npmjs.com/package/@cuser/express-middleware-graphql) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=express-middleware-graphql)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/express-middleware-graphql)](https://www.npmjs.com/package/@cuser/express-middleware-graphql) |\n| **Integrations** |\n| [`@cuser/react`](//github.com/rubeniskov/cuser/tree/master/packages/react) | react ui components for visualize cuser | [![npm-version](https://img.shields.io/npm/v/@cuser/react.svg)](https://www.npmjs.com/package/@cuser/react) | [![codecov](https://codecov.io/gh/rubeniskov/cuser/branch/master/graph/badge.svg?flag=react)](https://codecov.io/gh/rubeniskov/cuser) | [![npm-downloads](https://img.shields.io/npm/dw/@cuser/react)](https://www.npmjs.com/package/@cuser/react) |\n# Development\n\nBeing a workspaced based mono repo project, yarn `\u003e=1.5.0` is needed to allow local development\n\n### Installing dependencies\n```\nyarn install\n```\n\n### Release\n\n```shell\nGITHUB_ACCESS_TOKEN=\u003caccess_token\u003e npm run release {version_number}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubeniskov%2Fcuser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubeniskov%2Fcuser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubeniskov%2Fcuser/lists"}