{"id":23055943,"url":"https://github.com/yetanotherchris/letmein","last_synced_at":"2025-08-15T05:32:28.009Z","repository":{"id":54431424,"uuid":"81376737","full_name":"yetanotherchris/letmein","owner":"yetanotherchris","description":"Encrypted notes service using .NET Core, Postgres and Docker.","archived":false,"fork":false,"pushed_at":"2024-07-31T20:10:15.000Z","size":728,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-01T23:58:50.358Z","etag":null,"topics":["docker","dotnet-core","letmein","marten","pastebin-service"],"latest_commit_sha":null,"homepage":null,"language":"C#","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/yetanotherchris.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":"2017-02-08T21:16:24.000Z","updated_at":"2024-07-31T20:10:19.000Z","dependencies_parsed_at":"2024-07-31T23:22:24.176Z","dependency_job_id":null,"html_url":"https://github.com/yetanotherchris/letmein","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanotherchris%2Fletmein","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanotherchris%2Fletmein/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanotherchris%2Fletmein/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanotherchris%2Fletmein/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yetanotherchris","download_url":"https://codeload.github.com/yetanotherchris/letmein/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229893852,"owners_count":18140620,"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":["docker","dotnet-core","letmein","marten","pastebin-service"],"created_at":"2024-12-16T01:14:01.256Z","updated_at":"2024-12-16T01:14:01.874Z","avatar_url":"https://github.com/yetanotherchris.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Letmein\n\n[![Docker Pulls](https://img.shields.io/docker/pulls/anotherchris/letmein.svg)](https://hub.docker.com/r/anotherchris/letmein/)\n\n### What is it?\n\nLetmein is an encrypted notes service, similar to cryptobin.co. No encryption keys are stored in the database, and the encryption is performed in the browser. Notes last 12 hours by default, but this is configurable (see below) with the option to have multiple expiry times. A background service runs in the same process as the web server (in a separate thread), cleaning up expired notes every 5 minutes. This 5 minutes/300 second wait time is also configurable.\n\nThe service is intended to be run using a Docker stack, with Kestrel (Microsoft's cross-platform web server) and is currently tested on Linux but developed on Windows using Podman. \n\nRunning the Docker image will start the Kestrel web server with letmein running.\n\n### Tech stack\n\n- .NET 8\n- [Sjcl](https://github.com/bitwiseshiftleft/sjcl) Javascript library for encryption.\n- Postgres (using [Marten](https://github.com/JasperFx/marten))\n- Cloud storage (S3, Azure, Google) (using [CloudFileStore](https://github.com/yetanotherchris/CloudFileStore))\n\n### Quick start\n\nLetmein now supports 3 ways to store your pastes: local storage, cloud file store and database. It listens on port 8080 by default.\n\n#### Step 1. Configure a storage provider\n\n##### Local storage\n\nPastes can be stored inside the `storage` directory inside the container, the full path is `/app/storage`. If you want to persist the pastes, simply map this as a volume.  \n\nYou don't need to customise any environmental variables for this, it will launch using FileSystem by default, as the storage provider.\n\n##### S3\nAdd the following to your environmental variables\n\n```\nREPOSITORY_TYPE=S3\nS3__AccessKey=key\nS3__BucketName=bucket\nS3__Region=for example, eu-west-1\nS3__SecretKey=secret\n```\n\n##### Google Cloud Storage\nAdd the following to your environmental variables\n\n```\nREPOSITORY_TYPE=GoogleCloud\nGoogleCloud__BucketName=name of your bucket\nGoogleCloud__type=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__project_id=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__private_key_id=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__private_key=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__client_email=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__client_id=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__auth_uri=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__token_uri=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__auth_provider_x509_cert_url=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\nGoogleCloud__client_x509_cert_url=\u003cCOPY FROM YOUR SERVICE ACCOUNT JSON FILE\u003e\n```\n\n##### Azure Blobs\nAdd the following to your environmental variables\n\n```\nREPOSITORY_TYPE=AzureBlobs\nAzure__ContainerName=container name\nAzure__ConnectionString=get this from the Azure portal\n```\n\n##### Postgres\n\nIf you don't want to buy Postgres hosting (such as AWS RDS), you can run Postgres as a Docker container. The example below assumes the Postgres container is inside the same Docker network as your Letmein Docker container.\n\nStart a Postgres container (it needs 9.5 or higher):\n\n    docker run -d --name postgres -p 5432:5432 -e POSTGRES_USER=letmein -e POSTGRES_PASSWORD=letmein123 postgres \n\n#### Step 2. Run the Letmein Docker container\n\nRun the Letmein Docker container (below assumes you're using Postgres):\n\n    docker run -d -p 8080:8080 --link postgres:postgres -e POSTGRES_CONNECTIONSTRING=\"host=postgres;database=letmein;password=letmein123;username=letmein\" anotherchris/letmein\n\nNow go to [http://localhost:8080](http://localhost:8080) and store some text.\n\n### FAQ\n\nThere is a FAQ available in the application itself. You can read this on [Letmein.io][https://www.letmein.io/FAQ].\n\n### Customisations\n\nThe letmein image is fairly customisable. The various customisations can be done via environmental variables passed to the Docker container, which are uppercase by convention (except the cloud storage environmental variables above):\n\n- `REPOSITORY_TYPE` - Where pastes are stored. Possible values: \"FileSystem\", \"Postgres\", \"S3\", \"GoogleCloud\", \"AzureBlobs\". Default is FileSystem.\n- `POSTGRES_CONNECTIONSTRING` - The connection string to the Postgres database.\n- `EXPIRY_TIMES` - A comma-separated list of minutes that pastes expire after. For example \"90, 600\" would be 1 hour 30 minutes, and 10 hours. The default for this setting is 720 minutes (12 hours)\n- `CLEANUP_SLEEPTIME` - Number of seconds to sleep in between checking for expired pastes. The default for this setting is 300 seconds.\n- `ID_TYPE` - Short url ID type. Possible values: `default (random-with-pronounceable)`, `pronounceable`, `short-pronounceable`, `short-mixedcase`, `shortcode`. See below for notes on clash rates.\n\n#### UI Customisations\n\n- `PAGE_TITLE` - The `\u003ctitle\u003e` prefix of each page.\n- `HEADER_TEXT` - The header text on each page, next to the logo.\n- `HEADER_SUBTEXT` - The text underneath the header.\n- `FOOTER_TEXT` - Text in the footer. The version number in the footer isn't configurable.\n\nYou can also configure the application quite easily by forking the repository, and changing the views (`*.cshtml` files), and then running `docker build .` in the `src\\Letmein.Web` folder.\n\n##### ID_TYPE clash rates\n\nThe various types of short url types you configure change the chances you'll receive a clash between ids. Letmein doesn't check if an url already exists, so you can receive clashes if you use the short ids.\n\n- `random-with-pronounceable` - 4 random characters  (a-z, A-Z, 0-9), and a pronounceable password (a non-dictionary word). \n  - `P = (1/64) * (1/64) * (1/64) * (1/64) * (1/500)`\n- `pronounceable` - 8 character pronounceable password (a non-dictionary word).\n  - `P = (1/500)`\n- `short-pronounceable` - 5 character pronounceable password (a non-dictionary word).\n  - `P = (1/300)`\n- `short-mixedcase` - 4 random characters (a-z, A-Z, 0-9).\n  - `P = (1/64) * (1/64) * (1/64) * (1/64)`\n- `shortcode` - 2 numbers, 2 characters and 2 numbers. First two numbers are the 2 from the current time's millseconds, characters are 2 uppercase, 2 digits from the current time's seconds.\n  - `P = (1/1000) * (1/26) * (1/26) * (1/60)`\n\nThese are rough estimates of probability (particularly the pronounceable passwords).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyetanotherchris%2Fletmein","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyetanotherchris%2Fletmein","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyetanotherchris%2Fletmein/lists"}