{"id":15097206,"url":"https://github.com/jrialland/ihaveasecret","last_synced_at":"2026-02-13T13:01:25.002Z","repository":{"id":228935005,"uuid":"775310854","full_name":"jrialland/ihaveasecret","owner":"jrialland","description":"Simple web app for sharing confidential info via temporary links; message auto-deletes upon viewing for security","archived":false,"fork":false,"pushed_at":"2025-05-09T09:05:43.000Z","size":1173,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-08T12:53:43.556Z","etag":null,"topics":["bulma-css","flask","password","remixicon","security"],"latest_commit_sha":null,"homepage":"","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jrialland.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-21T06:31:03.000Z","updated_at":"2025-05-08T17:24:00.000Z","dependencies_parsed_at":"2024-12-05T20:21:48.968Z","dependency_job_id":"9e206002-fd54-471a-9473-a3c4bfabc9db","html_url":"https://github.com/jrialland/ihaveasecret","commit_stats":{"total_commits":8,"total_committers":1,"mean_commits":8.0,"dds":0.0,"last_synced_commit":"ce5fc994dc3d258d3aebc14bfd7306b23be782e3"},"previous_names":["jrialland/ihaveasecret"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/jrialland/ihaveasecret","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrialland%2Fihaveasecret","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrialland%2Fihaveasecret/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrialland%2Fihaveasecret/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrialland%2Fihaveasecret/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jrialland","download_url":"https://codeload.github.com/jrialland/ihaveasecret/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrialland%2Fihaveasecret/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29407016,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T06:24:03.484Z","status":"ssl_error","status_checked_at":"2026-02-13T06:23:12.830Z","response_time":78,"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":["bulma-css","flask","password","remixicon","security"],"created_at":"2024-09-25T16:05:24.299Z","updated_at":"2026-02-13T13:01:24.985Z","avatar_url":"https://github.com/jrialland.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"ihaveasecret\n============\n\nA straightforward web application that enables users to share confidential information with others via temporary links. Once the recipient opens the link, the secret message is automatically removed from the server.\n\nSecrets are stored in Redis and encrypted using the application's secret key.\n\nThe application is intentionally designed to be as simple as possible to meet stringent security standards: minimal JavaScript, basic CSS, and no extravagant features.\n\nIt employs the following components:\n * [python](https://www.python.org/) 3.12\n * [flask](https://flask.palletsprojects.com/en/3.0.x/) ( and [waitress](https://github.com/Pylons/waitress) )\n * [pycryptodome](https://www.pycryptodome.org/)\n * [redis-py](https://github.com/redis/redis-py)\n * [bulma](https://bulma.io/)\n * [remixicon](https://remixicon.com/)\n\nConfiguration\n-----\n\nConfiguration can be accomplished by utilizing Docker secrets, environment variables, or a configuration file. The resolution of configuration settings follows this sequence:\n\n1. Check for a file named the same as the setting in the directory /run/secrets. If such a file exists, the value is extracted from the file's content.\n2. Verify if an environment variable with the corresponding name exists.\n3. Search for the key in the configuration file named \"config.json\".\n\nThe following table provides guidance on configuring the app:\n\n| key | secret file | environment variable | definition | default value |\n|---|---|---|---|---|\n|app.secret_key|/run/secrets/app.secret_key|APP_SECRET_KEY|used for as flask unique key| none (mandatory)|\n|app.url_prefix|/run/secrets/app.url_prefix|APP_URL_PREFIX|path to prepend to all uris| empty|\n|app.proxy_fix|/run/secrets/app.proxy_fix|APP_PROXY_FIX|if set to True, handle X-Forwarded-For header|False|\n|secrets.max_length|/run/secrets/secrets.max_length|SECRETS_MAX_LENGTH|maximum allowed messages length|2048|\n|redis.url|/run/secrets/redis.url|REDIS_URL|redis url|none, in-memory storage is used if missing|\n|passwords.max_attempts|/run/secrets/password.max_attempts|PASSWORDS_MAX_ATTEMPTS|how many tries are allowed|3|\n|app.disable_email|/run/secrets/app.disable_email|APP_DISABLE_EMAIL|disable email notifications|false|\n|smtp.sender_email|/run/secrets/smtp.sender_email|SMTP_SENDER_EMAIL|sender address|noreply@ihaveasecret.io|\n|smtp.server|/run/secrets/smtp.server|SMTP_SERVER|smtp host|localhost|\n|smtp_port|/run/secrets/smtp.port|SMTP_PORT|smtp port|587|\n|smtp_user|/run/secrets/smtp.user|SMTP_USER|smtp user|(none)|\n|smtp_password|/run/secrets/smtp.password|smtp password|(none)|\n\nTODOs :\n-------\n * \u003cstrike\u003eTranslations\u003c/strike\u003e\n * \u003cstrike\u003eDocument configuration keys\u003c/strike\u003e\n * \u003cstrike\u003ejavascript : hint on password strength (https://github.com/dropbox/zxcvbn ?)\u003c/strike\u003e\n * \u003cstrike\u003ejavascript : message length\u003c/strike\u003e\n\nDevelopment :\n-----------\nI use [podman-compose](https://github.com/containers/podman-compose) :\n\n```\npodman-compose up -d\n```\nWill start the application in debug (=flask auto-reload) mode along with a redis instance.\n\nproduction :\n------------\n\nusing docker or podman : `docker build -t ihaveasecret -f Containerfile`\n\ni18n\n-----\n`pybabel extract -F babel.cfg -o messages.pot .`\n`pybabel init -i messages.pot -d translations -l fr`\n`pybabel compile -d translations`\n`pybabel update -i messages.pot -d translations`\n\nScreenshots :\n-------------\n\n![Create a message](./docs/screenshot_create.png)\n![Create a message, filled](./docs/screenshot_create_2.png)\n![Message created](./docs/screenshot_created.png)\n![Checking password](./docs/screenshot_check_password.png)\n![Invalid password](./docs/screenshot_invalid_attempt.png)\n![Read message](/docs/screenshot_read.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrialland%2Fihaveasecret","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjrialland%2Fihaveasecret","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrialland%2Fihaveasecret/lists"}