{ "info": { "author": "Jorge Barata", "author_email": "jorge.barata.gonzalez@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Programming Language :: JavaScript", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], "description": "# \ud83d\ude48 See No Evil\n\nClient side encrypted pastebin.\n\n- It has been designed to be short and simple to read.\n- Data is encrypted at the client. It only has [one JS dependency](http://bitwiseshiftleft.github.io/sjcl/).\n- Web and CLI clients are provided. They both share the same JS library for encrypting and decrypting.\n\n## How it works\n\nThe fragment identifier of the URL (`#`) [is never sent to the server](https://www.w3.org/TR/webarch/#media-type-fragid):\n\n> Interpretation of the fragment identifier is performed solely by the agent that dereferences a URI; the fragment identifier is not passed to other systems during the process of retrieval. This means that some intermediaries in Web architecture (such as proxies) have no interaction with fragment identifiers and that redirection (in HTTP [RFC2616], for example) does not account for fragments.\n\nEach time a user sends data to See No Evil:\n\n1. A random key is generated at the client.\n2. The client encrypts the data with this key.\n3. The client sends the encrypted data to the server.\n4. The server stores the encrypted data.\n5. The server returns a safe URL pointing to the encrypted data.\n6. The client appends the random key it generated to the received URL as a fragment identifier and shows it to the user.\n\nThen the user can share this URL with someone else:\n\n1. The server responds with the encrypted data.\n2. The client extracts the key from the URL fragment identifier, decrypts the data, and shows it to the user.\n\n\n### Features\n\n- Every secret has an expiration date. A temporal task deletes the expired ones every ten minutes.\n- Every secret has a maximum number of reads. After all the reads are consumed, the secret is deleted.\n- The server has a REST API. A command line interface is provided.\n\n## Demo\n\nhttps://seenoevil.herokuapp.com\n\n![screen recording](docs/seenoevil.gif)\n\n\n## Usage\n\n### Server\n\n```\n$ pipenv install\n$ pipenv run python -m seenoevil\n```\nFor a complete list of the environment variables, please check [`settings.py`](seenoevil/settings.py).\n\n#### Web client\n\nOpen [127.0.0.1:8000](http://127.0.0.1:8000).\n\n### CLI client\n\nRequires [Node.js](https://nodejs.org/en/) `v8.15.1`.\n\n```\n$ bin/seenoevil\nusage: seenoevil create DATA [EXPIRATION[ READS]]\n seenoevil show URL\n```\n\nSet the `HOST` environment variable to set a different server:\n\n```\n$ HOST=https://seenoevil.herokuapp.com bin/seenoevil create \"I like pancakes\"\n{\"path\":\"/secret/IjAwNTk5YTM0ZjNjNDQ2MTNhNjg0NTQxMGY0Mzk1Njk2Ig.xDziE424HiU5Qb0u8FgdaSda2Ug#Ji3WsojAmAJ7hwb5fggY3KI92PLFOtmC_v9UYwNM3QY\"}%\n```\n\nThe CLI prints JSON to the STDOUT. Using a JSON formatter is recommended (i.e. [`jq`](https://stedolan.github.io/jq/)).\n\n\n## Dependencies\n\n### Client\n\n- [`sjcl`](http://bitwiseshiftleft.github.io/sjcl/)\n - Included in the codebase.\n - Used for client side encryption.\n\n### Python\n- `sanic`: Async web server (check `server.py::app`)\n- `sanic-jinja2`: Jinja2 support for `sanic` (check `templates/`)\n- `peewee`: ORM (check `models.py::Secret`)\n- `itsdangerous`: URL safe serializers (check `models.py::TokenField`)\n- `environs`: Environment variables (check `settings.py::env`)\n\n\n## Heroku\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/jorgebg/seenoevil)\n\nFor a complete list of the environment variables, please check [`settings.py`](seenoevil/settings.py).\n\n\n## Design\n\n### Model\n\n- **`Secret`**\n - `id`: UUID4, primary key\n - `data`: Encrypted data sent by the client.\n - `expiration`: Date the `Secret` will be removed.\n - `reads`: Maximum number of reads before the `Secret` self-destructs.\n\n### Create action\n\n![Create action \u2013 Sequence diagram](docs/diagrams/create.svg)\n\n### Show action\n\n![Create action \u2013 Sequence diagram](docs/diagrams/show.svg)\n\n\n### Folder structure\n\n```\nseenoevil/ # Server\n __init__.py\n server.py\n model.py\n settings.py\n __main__.py\njs/\n cli.js # CLI client\n web.js # Web client\n lib.js # Encrypt and decrypt functions, shared by the Web and CLI client\n vendor/\n sjcl.js\nsecrets.db # Default SQLite3 database\n.env # A default SECRET_KEY is generated by the server here if it's not set\n```\n\nFor details about the folder structure please use [`purpose`](https://github.com/jamiebuilds/purposefile).\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/jorgebg/seenoevil", "keywords": "", "license": "GPLv2", "maintainer": "", "maintainer_email": "", "name": "seenoevil", "package_url": "https://pypi.org/project/seenoevil/", "platform": "", "project_url": "https://pypi.org/project/seenoevil/", "project_urls": { "Homepage": "https://github.com/jorgebg/seenoevil" }, "release_url": "https://pypi.org/project/seenoevil/0.1.2/", "requires_dist": [ "sanic (==19.3.1)", "sanic-jinja2 (==0.7.4)", "peewee (==3.9.4)", "itsdangerous (==1.1.0)", "environs (==4.1.0)" ], "requires_python": ">=3.6.0", "summary": "Client side encrypted pastebin.", "version": "0.1.2" }, "last_serial": 5326380, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "38b8566997d23ccf20cfe0377765352e", "sha256": "076ba3adb835753818c6a71d7b0fd391f5a7abbd7368fe350bc32c20e5f3228f" }, "downloads": -1, "filename": "seenoevil-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "38b8566997d23ccf20cfe0377765352e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 11158, "upload_time": "2019-05-15T15:47:13", "url": "https://files.pythonhosted.org/packages/98/a7/54d1b35b65fc8e90089c4e3dadf66797a1aa18db6ddccaf4dba59b47fbc1/seenoevil-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d960acf05a7abd2f41ff7510f6c9c691", "sha256": "71491e3e14d608c56b0ec0edd852f22e4e1e7e25694bd5451eda848b2c7556a7" }, "downloads": -1, "filename": "seenoevil-0.1.0.tar.gz", "has_sig": false, "md5_digest": "d960acf05a7abd2f41ff7510f6c9c691", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 5434, "upload_time": "2019-05-15T15:47:15", "url": "https://files.pythonhosted.org/packages/1c/57/7fe947f6b829035484649e9c1651788a21ac9109c0e0460e996e1e4bd0ea/seenoevil-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "cedadb574af826f21a1c37261d1375da", "sha256": "9677b16d254d93eae993a4d2cc27545893625cb7d137ccb3401a5d81a6388d1c" }, "downloads": -1, "filename": "seenoevil-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cedadb574af826f21a1c37261d1375da", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 36680, "upload_time": "2019-05-25T23:04:24", "url": "https://files.pythonhosted.org/packages/39/ff/3ed9af7a45fc3ee88c7f1f54894337f90c08f5a3a997d7925a1564ecd46c/seenoevil-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "757d5107263f09a93099af0db77dc9d1", "sha256": "c5aae2380725a901cd50b6d5959c0e34d3f0a1a7a2b156450e43147075767ae1" }, "downloads": -1, "filename": "seenoevil-0.1.1.tar.gz", "has_sig": false, "md5_digest": "757d5107263f09a93099af0db77dc9d1", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 29614, "upload_time": "2019-05-25T23:04:25", "url": "https://files.pythonhosted.org/packages/41/5b/93aea1f651c3afb3696ba6a547de34ab3dff47d1dedd1643c72448a99a8f/seenoevil-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "9480b41458da08d1c47ebf72da145110", "sha256": "cbd03406b9875beda61bf21d68cb8084ecf709d2de7cedf03611947a1a1ae126" }, "downloads": -1, "filename": "seenoevil-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9480b41458da08d1c47ebf72da145110", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 36744, "upload_time": "2019-05-28T11:45:25", "url": "https://files.pythonhosted.org/packages/5a/0c/b8ba138fafb08b38e98371c650b5e306c14f4ff3e8ee4a94380c5465beaa/seenoevil-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "52238daac53fa492bb55f555843c1c13", "sha256": "8b1880ff27fb7b05dd23349080702b593ec58a9a63eb3b1d402844ec44052d02" }, "downloads": -1, "filename": "seenoevil-0.1.2.tar.gz", "has_sig": false, "md5_digest": "52238daac53fa492bb55f555843c1c13", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 29812, "upload_time": "2019-05-28T11:45:26", "url": "https://files.pythonhosted.org/packages/4b/ae/01c318d412ecde677236b224e01985dc29103b9d7bccff3fc0c1100cc7ba/seenoevil-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9480b41458da08d1c47ebf72da145110", "sha256": "cbd03406b9875beda61bf21d68cb8084ecf709d2de7cedf03611947a1a1ae126" }, "downloads": -1, "filename": "seenoevil-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9480b41458da08d1c47ebf72da145110", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 36744, "upload_time": "2019-05-28T11:45:25", "url": "https://files.pythonhosted.org/packages/5a/0c/b8ba138fafb08b38e98371c650b5e306c14f4ff3e8ee4a94380c5465beaa/seenoevil-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "52238daac53fa492bb55f555843c1c13", "sha256": "8b1880ff27fb7b05dd23349080702b593ec58a9a63eb3b1d402844ec44052d02" }, "downloads": -1, "filename": "seenoevil-0.1.2.tar.gz", "has_sig": false, "md5_digest": "52238daac53fa492bb55f555843c1c13", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 29812, "upload_time": "2019-05-28T11:45:26", "url": "https://files.pythonhosted.org/packages/4b/ae/01c318d412ecde677236b224e01985dc29103b9d7bccff3fc0c1100cc7ba/seenoevil-0.1.2.tar.gz" } ] }