{"id":13674584,"url":"https://github.com/m1dnight/exbin","last_synced_at":"2026-01-12T02:40:24.759Z","repository":{"id":39211784,"uuid":"147788018","full_name":"m1dnight/exbin","owner":"m1dnight","description":"A pastebin clone written in Elixir/Phoenix.","archived":false,"fork":false,"pushed_at":"2024-01-23T19:03:20.000Z","size":5072,"stargazers_count":85,"open_issues_count":10,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-03T11:09:26.268Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/m1dnight.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-09-07T07:33:53.000Z","updated_at":"2024-07-24T18:53:51.000Z","dependencies_parsed_at":"2024-01-23T15:47:40.201Z","dependency_job_id":"f6c9a98d-6d0c-4c4b-b387-0c06693c41ff","html_url":"https://github.com/m1dnight/exbin","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1dnight%2Fexbin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1dnight%2Fexbin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1dnight%2Fexbin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1dnight%2Fexbin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m1dnight","download_url":"https://codeload.github.com/m1dnight/exbin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251330305,"owners_count":21572265,"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":[],"created_at":"2024-08-02T11:00:54.385Z","updated_at":"2026-01-12T02:40:24.753Z","avatar_url":"https://github.com/m1dnight.png","language":"Elixir","funding_links":[],"categories":["Install from Source","Software"],"sub_categories":["Pastebins"],"readme":"\u003c!-- DO NOT REMOVE - contributor_list:data:start:[\"m1dnight\", \"joshproehl\", \"dependabot[bot]\"]:end --\u003e\n# Exbin\n\nA pastebin clone written in Phoenix/Elixir. Live [here](https://exbin.call-cc.be).\n\nI work on this project from time to time, so the development pace is slow. If you want to dive in, feel free. The codebase is relatively small because, well, it's a simple application.\n\n## Features\n\n * Post pastes either publicly or privately\n * Opt-in ephemeral snippets. By default these are deleted approximately 60 minutes after creation.\n * Views are only incremented once every 24 hours, per client.\n * Usage statistics.\n * List of all public pastes\n * Use `nc` to pipe text and get back the URL.\n   (e.g., `cat file.txt | nc exbin.call-cc.be 9999`)\n * \"Raw View\" where text is presented as is. Well suited for copy/pasting.\n * \"Reader View\" where text is presented in a more readable manner. Well suited to share prose text.\n * \"Code View\", showing snippets with syntax highlighting.\n * The netcat endpoint has an HTTP bomb so that scanners and bots don't return.\n\n# Installation\n\nThe easiest way to run your own instance of Exbin is by running it in a Docker container.\nMake a copy of the configuration file in `rel/overlays/config.exs`. The file contains documentation on how to fill it out.\nMount this file in the docker container to configure your instance.\n\n\nCopy the `docker-compose.yaml` file, and change accordingly. Finally, run it with `docker-compose up`.\n\n## Initial User Account\n\nWhen installing/running ExBin for the first time, a user will be created for you.\nIt is highly recommended that you change this user its email and password.\nLook for a line like this in the log files.\n\n```\nCreated a user with email admin@exbin.call-cc.be and password ccbbf2726ac2ce3d3918\n```\n\nIf there are already users present in the database no user will be created.\nThe logfile will show this.\n\n```\nDid not create a user because there are already registered users in the database.\n```\n\nThe first user is the only admin user possible. I should probably update this in the future, but not today.\nIf you already have a bunch of users, you can easily change it by toggling the flag in the database.\n\n## Custom Branding in Docker\n\nIn order to configure this you will need to mount the file into your docker container as a volume, and then set the `custom_logo_path` parameter in the `config.exs` file to the full path (inside the container) that the file is mounted at.\nHere is an example of what you would add to your `docker-compose.yml` and `config.exs`:\n\n```yml\n  exbin:\n    restart: always\n    image: m1dnight/exbin:latest\n    volumes:\n      - ./rel/overlays/config.exs:/app/prod/config.exs\n```\n\n```elixir\ncustom_logo_path: \"/my/logo.png\",\ncustom_logo_size: 30,\n```\n\nLogo by default is 30x30 pixels, but you can define the size for the width/height attributes of the img tag by setting `custom_logo_size`.\nLogos are assumed to be square, so the same value will be used for both height and width.\nAny layout errors that come from using sizes other than 30x30 are your problem. :-)\n\n## JSON API\n\nThere is a JSON API available. If your install has an API key set (the `api_key` variable in `config.exs`), it is required to post through the API. If it is not set, the API can be freely used.\nThe payload of the API is JSON, and expects at least the content of the snippet.\n\nThe `api/new` endpoint expects a JSON payload with the keys `content`, `private`, and `ephemeral`. For example:\n\n```\n{\"content\": \"this is the content\",\n \"private\": true,\n \"ephemeral\": false\n}\n```\n\nAn example request for a snippet without authentication looks like this.\n\n```\n$ curl -XPOST -H \"Content-type: application/json\" -d '{\"content\": \"this is the content\", \"private\": true, \"ephemeral\": false}' 'https://exbin.call-cc.be/api/new'\n{\"content\":\"this is the content\",\"created\":\"2021-10-01T20:32:38.702101Z\",\"name\":\"RegelatedDoublemindedness\",\"url\":\"https://exbin.call-cc.be/RegelatedDoublemindedness\"}\n```\n\nTo use an authenticated endpoint simply add another field to the JSON payload with the token.\n\n```\n$ curl -XPOST -H \"Content-type: application/json\" -d '{\"content\": \"this is the content\", \"private\": true, \"ephemeral\": false, \"token\": \"supersecret\"}' 'https://exbin.call-cc.be/api/new'\n{\"content\":\"this is the content\",\"created\":\"2021-10-01T20:32:38.702101Z\",\"name\":\"RegelatedDoublemindedness\",\"url\":\"https://exbin.call-cc.be/RegelatedDoublemindedness\"}\n```\n\nA snippet can be requested by name using the `api/new` endpoint. No parameters should be given.\nAn example curl request looks like this.\n\n```\n curl 'https://exbin.call-cc.be/api/show/CoppingSuctions'\n {\"content\":\"this is the content\",\"created\":\"2022-05-06T08:40:17.769579Z\",\"name\":\"CoppingSuctions\",\"url\":\"https://exbin.call-cc.be/api/show/CoppingSuctions\"}\n```\n\n# Things To Do\n\n * Empty snippets are not allowed, but if you use some unprintable chars it still passes.\n * Synced paged back or not?\n * Rate limit the amount of pastes a user can make.\n * Admin page\n * Nicer warnings/checks on environment variables instead of crashing immediately.\n * Check older issues to see what I missed\n * Allow a unique user (reuse from rate limiting) to delete a snippet in the next x minutes, or create a unique delete link or something.\n * Maybe use a list to filter out snippets that might contain bad words. Instead of disallowing them, we could drop them from the public list.\n * Write some unit tests..\n\n\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- DO NOT REMOVE - contributor_list:start --\u003e\n## 👥 Contributors\n\n\n- **[@m1dnight](https://github.com/m1dnight)**\n\n- **[@joshproehl](https://github.com/joshproehl)**\n\n- **[@dependabot[bot]](https://github.com/apps/dependabot)**\n\n\u003c!-- DO NOT REMOVE - contributor_list:end --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm1dnight%2Fexbin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm1dnight%2Fexbin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm1dnight%2Fexbin/lists"}